// Copyright 2020 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.dhcpv6;

using fuchsia.net.interfaces.admin;
using fuchsia.net.name;
using fuchsia.net;
using zx;

/// Default port a DHCPv6 client should listen to according to
/// [RFC 8415, Section 7.2](https://tools.ietf.org/html/rfc8415#section-7.2).
const DEFAULT_CLIENT_PORT uint16 = 546;

/// Provides a method to create new clients.
@discoverable
protocol ClientProvider {
    /// Provides a DHCPv6 client.
    ///
    /// + request `params` the parameters to create the client with.
    /// + request `request` grants control over the client. Closed with an
    ///     epitaph if the client cannot be created.
    NewClient(resource struct {
        params @generated_name("NewClientParams") table {
            /// The ID of the interface the client will run on.
            ///
            /// Required.
            1: interface_id uint64;

            /// The socket address to use when communicating with servers.
            ///
            /// DHCPv6 servers listen for link-local multicasts, so not using a
            /// link-local address here may cause interoperability issues.
            ///
            /// Client creation will fail with `INVALID_ARGS` if:
            ///
            /// * a multicast address is provided;
            /// * or a link-local address is provided, and its zone index
            ///     doesn't match `interface_id` (Fuchsia has a 1:1 mapping from
            ///     zone index to interface ID).
            ///
            /// Client creation will fail if it fails to bind a socket to this
            /// address.
            ///
            /// Required.
            2: address fuchsia.net.Ipv6SocketAddress;

            /// Configuration for starting the DHCPv6 client.
            ///
            /// If the configuration requests both addresses and other
            /// configuration parameters, all information is requested in the
            /// same message exchange, running in stateful mode. If only
            /// configuration parameters are requested (no addresses), the
            /// client runs in stateless mode, as described in
            /// [RFC 8415, Section 6.1](https://tools.ietf.org/html/rfc8415#section-6.1).
            ///
            /// Client creation will fail if `config` is not requesting any
            /// information (all fields are empty), or if it contains invalid
            /// fields.
            ///
            /// Required.
            3: config @generated_name("ClientConfig") table {
                /// Configuration for requesting configuration information.
                ///
                /// If not set, interpreted as empty (no configuration
                /// information will be requested).
                1: information_config @generated_name("InformationConfig") table {
                    /// Request a list of available DNS servers
                    /// [RFC 3646](https://tools.ietf.org/html/rfc3646).
                    ///
                    /// If not set, interpreted as false;
                    1: dns_servers bool;
                };

                /// Non-temporary address configuration.
                ///
                /// Configures the client to negotiate non-temporary
                /// addresses (IA_NA), as defined in
                /// [RFC 8415, section 6.2](https://tools.ietf.org/html/rfc8415#section-6.2).
                ///
                /// If not set, interpreted as empty (non-temporary addresses
                /// will not be negotiated).
                2: non_temporary_address_config @generated_name("AddressConfig") table {
                    /// Number of addresses.
                    ///
                    /// Required. Must be greater than 0.
                    1: address_count uint8;

                    /// Preferred addresses.
                    ///
                    /// Used for requesting specific addresses from DHCPv6
                    /// servers. The addresses are used as hints by DHCPv6
                    /// servers, but may be ignored. If the DHCPv6 server
                    /// does not assign the preferred addresses and responds
                    /// with different addresses instead, the DHCPv6
                    /// client's behaviour is to accept the assigned
                    /// addresses.
                    ///
                    /// The size of `preferred_addresses` must be less than
                    /// or equal to `address_count`, otherwise the
                    /// `AddressConfig` is invalid.
                    ///
                    /// Optional field. If not set, or if
                    /// `preferred_addresses` is empty, no address hints are
                    /// provided.
                    2: preferred_addresses vector<fuchsia.net.Ipv6Address>:MAX;
                };
            };
        };
        request server_end:Client;
    });
};

/// Provides methods to watch for discovered network configurations.
///
/// This protocol encodes the underlying object's lifetime in both directions;
/// the underlying object is alive iff both ends of the protocol are open. 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 Client {
    compose fuchsia.net.name.DnsServerWatcher;

    /// Returns an address and its parameters.
    ///
    /// Yields a value for every address acquired by the client.
    ///
    /// 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 `address` the assigned address.
    /// - response `address_parameters` the parameters of the address.
    /// - response `address_state_provider` provides address assignment state
    ///     and enables updating address properties; client end is closed if
    ///     the address becomes invalid (its valid lifetime expires and Renew
    ///     and Rebind fail).
    WatchAddress() -> (resource struct {
        address fuchsia.net.Subnet;
        address_parameters fuchsia.net.interfaces.admin.AddressParameters;
        address_state_provider server_end:fuchsia.net.interfaces.admin.AddressStateProvider;
    });

    /// Gracefully tears down the underlying object.
    ///
    /// Blocks until any held addresses are gracefully released, as described in
    /// [RFC 8415, Section 18.2.7](https://tools.ietf.org/html/rfc8415#section-18.2.7).
    ///
    /// The server end of the protocol is closed after this method returns.
    ///
    /// * error a `zx.status` if any of the addresses were not gracefully
    ///     released, e.g. the client times out waiting for Reply to Release,
    ///     or the interface is down and sending Release fails.
    Shutdown() -> (struct {}) error zx.status;
};
