// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.net.interfaces.admin;

using zx;

type Empty = struct {};

/// Information about the preferred lifetime of an IP address.
type PreferredLifetimeInfo = strict union {
    /// The end of the preferred lifetime of the address.
    ///
    /// The address should *not* be considered deprecated if `zx.time` is in
    /// the past. `preferred_lifetime_end` is exchanged as a means to inform
    /// the deadline where deprecation is expected to happen.
    ///
    /// Refers to the preferred lifetime of the address, as defined in
    /// [RFC 4862, section 2](https://tools.ietf.org/html/rfc4862#section-2).
    ///
    /// Must be greater than 0. If `zx.time.INFINITE`, the preferred lifetime
    /// does not expire.
    1: preferred_lifetime_end zx.time;

    /// Set if the address is deprecated.
    ///
    /// When deprecated, the address should no longer be used for initiating
    /// new connection unless explicitly requested, or if no other
    /// non-deprecated addresses are assigned (as described in
    /// [RFC 4862, section 1](https://tools.ietf.org/html/rfc4862#section-1)).
    ///
    /// Once deprecated, an address can become undeprecated if its preferred
    /// lifetime is extended.
    ///
    /// This field is used to signal that the address should be deprecated.
    2: deprecated Empty;
};

/// Properties of an IP address.
type AddressProperties = table {
    /// Information about the preferred lifetime of the address.
    ///
    /// If not set, interpreted as
    /// `PreferredLifetimeInfo.preferred_lifetime_end = zx.time.INFINITE`.
    1: preferred_lifetime_info PreferredLifetimeInfo;

    /// The end of the valid lifetime of the address.
    ///
    /// The address should *not* be considered invalid if `zx.time` is in the
    /// past. `valid_lifetime_end` is exchanged as a means to inform the
    /// deadline where invalidation is expected to happen.
    ///
    /// Refers to the valid lifetime of the address, as defined in
    /// [RFC 4862, section 2](https://tools.ietf.org/html/rfc4862#section-2).
    ///
    /// Must be greater than 0. If `zx.time.INFINITE`, the valid lifetime does
    /// not expire.
    ///
    /// If not set, interpreted as `zx.time.INFINITE`.
    2: valid_lifetime_end zx.time;
};

/// Assignment state of an IP address.
type AddressAssignmentState = strict enum {
    // TODO(https://fxbug.dev/82724): Replace this comment with FIDL that
    // actually reserves 0.
    //
    // The value of 0 is reserved and should never be added to avoid the
    // ambiguity of 0 being the default integer value in some languages. See:
    // https://fuchsia.dev/fuchsia-src/concepts/api/fidl#enum.

    /// Address assignment is in progress, e.g. Duplicate Address Detection
    /// is being performed. The address cannot be used when in this state
    /// (cannot bind to it yet or receive packets destined to it).
    ///
    /// The Duplicate Address Detection mechanism is described in
    /// [RFC 4862, section 5.4](https://tools.ietf.org/html/rfc4862#section-5.4)
    TENTATIVE = 1;

    /// The address is assigned to an interface.
    ASSIGNED = 2;

    /// The address is unavailable, e.g. if the interface holding the address
    /// is offline.
    UNAVAILABLE = 3;
};

/// Reasons from IP address removal.
type AddressRemovalReason = strict enum {
    // TODO(https://fxbug.dev/82724): Replace this comment with FIDL that
    // actually reserves 0.
    //
    // The value of 0 is reserved and should never be added to avoid the
    // ambiguity of 0 being the default integer value in some languages. See:
    // https://fuchsia.dev/fuchsia-src/concepts/api/fidl#enum.

    /// The address is not a valid address.
    INVALID = 1;

    /// The address is already assigned to the interface.
    ALREADY_ASSIGNED = 2;

    /// Duplicate Address Detection failed.
    ///
    /// A neighbor was found to hold the address.
    DAD_FAILED = 3;

    /// The address was removed as a result of the interface being removed.
    INTERFACE_REMOVED = 4;

    /// The address was removed from the interface by user action.
    USER_REMOVED = 5;
};

/// Offers state information about an IP address.
///
/// This protocol encodes the underlying object's lifetime in both directions;
/// the underlying object is alive iff both ends of the protocol are open
/// (unless [`AddressStateProvider.Detach`] has been called). That is:
///
/// - Closing the client end causes the object to be destroyed.
/// - Observing a closure of the server end indicates the object no longer
///   exists.
protocol AddressStateProvider {
    // TODO(https://fxbug.dev/80621): Currently Netstack2's implementation does
    // not support this method due to lack of support for updating addresses'
    // valid and preferred lifetimes, and will send an
    // `AddressRemovalReason.USER_REMOVED` event and close the server end of
    // the protocol.
    /// Push an update when the address properties change.
    ///
    /// The client pushes updates on address properties changes, such as the
    /// address becoming deprecated, or the preferred and valid lifetimes being
    /// updated as a result of extending the address' lifetime. The server is
    /// expected to cache address properties.
    ///
    /// + request `address_properties` the updated properties of the address.
    UpdateAddressProperties(struct {
        address_properties AddressProperties;
    }) -> ();

    /// Hanging get for address assignment state.
    ///
    /// The server does not keep a queue of assignment states, it returns the
    /// latest state if it differs from the last one observed.
    ///
    /// The first call will always immediately return the current assignment
    /// state. Subsequent calls will block until the returned value differs
    /// from the last observed value.
    ///
    /// It is invalid to call this method while a previous call is pending.
    /// Doing so will cause the server end of the protocol to be closed.
    ///
    /// - response `assignment_state` the assignment state of the address.
    WatchAddressAssignmentState() -> (struct {
        assignment_state AddressAssignmentState;
    });

    /// Detaches the address' lifetime from the client end of the protocol.
    ///
    /// The client end of the protocol can be closed immediately after
    /// calling this method, and the address will not be removed.
    Detach();

    /// Terminal event. Immediately precedes the closure of the server end of
    /// the protocol.
    ///
    /// - response `error` the removal reason.
    -> OnAddressRemoved(struct {
        error AddressRemovalReason;
    });
};

/// Address assignment parameters.
type AddressParameters = table {
    /// The initial properties of the address.
    ///
    /// If not set, interpreted as an empty `AddressProperties`.
    1: initial_properties AddressProperties;

    /// True if the address is temporary.
    ///
    /// A temporary address is intended to be used for a short period of time
    /// (hours to days), and its lifetime may not be extended, as detailed in
    /// [RFC 4941](https://tools.ietf.org/html/rfc4941).
    ///
    /// Both temporary and non-temporary addresses have preferred and valid
    /// lifetimes, but temporary addresses may not be renewed beyond their
    /// initial lifetime.
    ///
    /// Information used in source address selection; temporary addresses are
    /// preferred over non-temporary addresses if both types are available, as
    /// detailed in
    /// [RFC 6724, section 5](https://tools.ietf.org/html/rfc6724#section-5).
    ///
    /// If not set, interpreted as false.
    2: temporary bool;
};
