// 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 uint16 DEFAULT_CLIENT_PORT = 546;

/// Configuration for an address type.
table AddressConfig {
    /// Number of addresses.
    ///
    /// If not set, interpreted as 0 (no addresses will be requested).
    1: uint8 address_count;

    /// 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.
    ///
    /// If the size of `preferred_addresses` is greater than `address_count`,
    /// the client will pick from `preferred_addresses` until `address_count`
    /// addresses are assigned to it.
    ///
    /// Optional field. If not set, or if `preferred_addresses` is empty, no
    /// address hints are provided.
    2: vector<fuchsia.net.Ipv6Address>:MAX preferred_addresses;
};

/// Configuration for negotiating addresses.
table AddressAssignmentConfig {
    /// 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).
    ///
    /// It not set, interpreted as an empty `AddressConfig` (no non-temporary
    /// addresses will be negotiated).
    1: AddressConfig non_temporary_address_config;
};

/// Configuration for requesting configuration information.
table InformationConfig {
    /// Request a list of available DNS servers
    /// [RFC 3646](https://tools.ietf.org/html/rfc3646).
    ///
    /// If not set, interpreted as false;
    1: bool dns_servers;
};

/// 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).
///
/// If the configuration does not request any information (neither addresses
/// nor other configuration information), the [`fuchsia.net.dhcpv6/Client`]
/// creation will fail.
table ClientConfig {
    /// Configuration for negotiating addresses.
    ///
    /// If set, the client runs in stateful mode, as described in
    /// [RFC 8415, Section 6.2](https://tools.ietf.org/html/rfc8415#section-6.2).
    ///
    /// If not set, interpreted as an empty `AddressAssignmentConfig` (no
    /// addresses will be negotiated).
    1: AddressAssignmentConfig address_assignment_config;

    /// Configuration for requesting configuration information.
    ///
    /// If not set, interpreted as an empty `InformationConfig` (no
    /// configuration information will be requested).
    2: InformationConfig information_config;
};

/// Parameters for calling [`fuchsia.net.dhcpv6/ClientProvider.NewClient`].
table NewClientParams {
    /// The ID of the interface the client will run on.
    ///
    /// Required.
    1: uint64 interface_id;

    /// 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: fuchsia.net.Ipv6SocketAddress address;

    /// The [`fuchsia.net.dhcpv6/ClientConfig`] the client starts with.
    ///
    /// Client creation will fail if `config` is not requesting any
    /// information.
    ///
    /// Required.
    3: ClientConfig config;
};

/// 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` the channel handle that can be used to control the
    ///     newly created client. Will be closed if a client cannot be created,
    ///     with an epitaph explaining the reason.
    NewClient(NewClientParams params, request<Client> request);
};

/// Provides methods to watch for discovered network configurations.
///
/// The lifetime of the the client is tied to the channel; closing the channel
/// will result in shutting down the client.
protocol Client {
    compose fuchsia.net.name.DnsServerWatcher;

    /// Returns an address and its parameters.
    ///
    /// Yields a value for every address acquired by the client.
    ///
    /// [`fuchsia.net.interfaces.admin/AddressParameters.address_state_provider`]
    /// is closed if the address becomes invalid (its valid lifetime expires
    /// and Renew and Rebind fail).
    ///
    /// It is invalid to call `WatchAssignmentState` while a previous call is
    /// still pending. Doing so will cause the channel to be closed.
    ///
    /// - response `address` the assigned address.
    /// - response `address_parameters` the parameters of the address.
    WatchAddress()
        -> (fuchsia.net.Subnet address,
            fuchsia.net.interfaces.admin.AddressParameters address_parameters);

    /// Shuts down the `Client`.
    ///
    /// 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 channel is closed after shutdown, regardless of whether an error is
    /// returned.
    ///
    /// * 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() -> () error zx.status;
};
