// Copyright 2017 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.mdns;

using fuchsia.net;
using zx;

// TODO(dalesat): Soft transition in progress.
// 1) Add the following definitions:
//    Subscriber.SubscribeToService2
//    ServiceSubscriber2
//    Publisher.PublishServiceInstance2
//    PublicationResponder2 (completed)
// 2) Transition all clients to the '2' versions. (completed)
// 3) Change the originals to be identical to the '2' versions. (completed)
// 3.1) Implement new features under the original names. (completed)
// 4) Transition all clients to the original names.
// 5) Remove the '2' versions.

// TODO(fxbug.dev/7904): Make these alias comments doc comments.

/// Identifies a host. Host names consist of one or more labels separated by
/// '.'s. A host name must not end with a '.'. Labels must each be 63 characters
/// or less (not including the separator) and are UTF-8-encoded. A complete host
/// name, including separators, must be 255 characters or less.
alias host_name = string:255;

/// Identifies a (type of) service being published. Service names consist of
/// two labels, both terminated with a '.'. The first label must start with an
/// underscore and be 16 characters or less, including the underscore. The
/// second label must be either '_tcp' or '_udp'. Labels do not contain '.'s.
/// With underscores and terminators, that makes for a maximum of 22 characters.
/// Service names are UTF-8-encoded.
alias service_name = string:22;

/// Identifies a specific instance of a service being published. Instance names
/// consist of a single label, which is at most 63 characters long and which
/// contains no '.'s. Instance names are UTF-8-encoded.
alias instance_name = string:63;

/// Identifies a subtype of a service. Subtype names consist of a single label,
/// which is at most 63 characters long and which contains no '.'s. Subtype
/// names are UTF-8-encoded.
alias subtype_name = string:63;

/// Provides description relating to a service instance. In typical use, TXT
/// strings consist of a key and value separated by '='. TXT strings must be
/// at most 255 characters long and are UTF-8-encoded.
alias txt_string = string:255;

/// Discoverable protocol for resolving host names to IP addresses.
[Discoverable]
protocol Resolver {
    /// Gets the addresses for the specified host. `timeout` specifies how long
    /// the service should wait before giving up when waiting for a response to
    /// a resolution query. In typical use, a timeout of two or three seconds
    /// is recommended.
    ///
    /// A successful resolution may return one or both addresses. An
    /// unsuccessful resolution is indicated when both addresses are null.
    ResolveHostName(host_name host, zx.duration timeout)
        -> (fuchsia.net.Ipv4Address? v4_address,
            fuchsia.net.Ipv6Address? v6_address);
};

/// Discoverable protocol for finding service instances.
[Discoverable]
protocol Subscriber {
    /// Subscribes to a service. The subscription lasts until `subscriber` is
    /// unbound.
    [Transitional]
    SubscribeToService(service_name service, ServiceSubscriber subscriber);

    /// Subscribes to a service. The subscription lasts until `subscriber` is
    /// unbound.
    [Transitional, Deprecated]
    SubscribeToService2(service_name service, ServiceSubscriber2 subscriber);
};

/// Discoverable protocol for publishing service instances.
[Discoverable]
protocol Publisher {
    /// Publishes a service instance. `publication_responder` is consulted via its
    /// `OnPublication` method for initial announcements and to answer queries.
    /// The service is published until the `publication_responder` channel closes. In
    /// addition to announcements and queries for the service type, all queries
    /// for subtypes are answered subject to filtering through the responder.
    /// `perform_probe` indicates whether a probe for a conflicting instance
    /// should be performed before publishing the instance. This value should
    /// be `true` unless the instance name is known to be unique.
    ///
    /// If a service with the same service and instance names is already published, the
    /// old publication will be terminated, and the responder channel for the old
    /// publication will be closed.
    [Transitional]
    PublishServiceInstance(service_name service,
                           instance_name instance,
                           Media media,
                           bool perform_probe,
                           PublicationResponder publication_responder) -> () error Error;

    /// Publishes a service instance. `publication_responder` is consulted via its
    /// `OnPublication` method for initial announcements and to answer queries.
    /// The service is published until the `publication_responder` channel closes. In
    /// addition to announcements and queries for the service type, all queries
    /// for subtypes are answered subject to filtering through the responder.
    /// `perform_probe` indicates whether a probe for a conflicting instance
    /// should be performed before publishing the instance. This value should
    /// be `true` unless the instance name is known to be unique.
    ///
    /// If a service with the same service and instance names is already published, the
    /// old publication will be terminated, and the responder channel for the old
    /// publication will be closed.
    [Transitional, Deprecated]
    PublishServiceInstance2(service_name service,
                            instance_name instance,
                            bool perform_probe,
                            PublicationResponder2 publication_responder) -> () error Error;
};

/// Specifies network media on which a service instance should be published.
bits Media : uint32 {
    /// Specifies wired interfaces.
    WIRED = 1;

    /// Specifies wireless interfaces.
    WIRELESS = 2;
};

/// Error values for instance publishing.
enum Error : int32 {
    /// The specified service name is invalid.
    INVALID_SERVICE_NAME = 1;

    /// The specified instance name is invalid.
    INVALID_INSTANCE_NAME = 2;

    /// The specified service instance is already being published by another
    /// host on the subnet. This result occurs when an initial probe discovers
    /// a conflicting instance.
    ALREADY_PUBLISHED_ON_SUBNET = 4;

    // The specified `Media` value is invalid.
    INVALID_MEDIA = 5;
};

/// Client-implemented interface for subscribers. Method replies are used to
/// throttle traffic. The service won't necessarily wait for a reply before
/// calling another method.
protocol ServiceSubscriber {
    /// Notifies the subscriber that a service instance has been discovered.
    OnInstanceDiscovered(ServiceInstance instance) -> ();

    /// Notifies the subscriber that addresses or text for a known service
    /// instance have changed.
    OnInstanceChanged(ServiceInstance instance) -> ();

    /// Notifies the subscriber that a known service instance has been lost.
    OnInstanceLost(service_name service, instance_name instance) -> ();

    /// Notifies the subscriber that a PTR query has been sent.
    OnQuery(ResourceType resource_type) -> ();
};

/// Client-implemented interface for subscribers. Method replies are used to
/// throttle traffic. The service won't necessarily wait for a reply before
/// calling another method.
protocol ServiceSubscriber2 {
    /// Notifies the subscriber that a service instance has been discovered.
    OnInstanceDiscovered(ServiceInstance2 instance) -> ();

    /// Notifies the subscriber that addresses or text for a known service
    /// instance have changed.
    OnInstanceChanged(ServiceInstance2 instance) -> ();

    /// Notifies the subscriber that a known service instance has been lost.
    OnInstanceLost(service_name service, instance_name instance) -> ();

    /// Notifies the subscriber that a PTR query has been sent.
    OnQuery(ResourceType resource_type) -> ();
};

/// DNS resource types.
enum ResourceType {
    /// Domain name pointer.
    PTR = 12;
    /// Any (wildcard) type.
    ANY = 255;
};

/// Describes a service instance.
table ServiceInstance {
    /// The name of the service.
    1: service_name service;

    /// The name of the service instance.
    2: instance_name instance;

    /// IPv4 socket address for the service. May be unset.
    3: fuchsia.net.Ipv4SocketAddress ipv4_endpoint;

    /// IPv6 socket address for the service. May be unset.
    4: fuchsia.net.Ipv6SocketAddress ipv6_endpoint;

    /// Text strings describing the instance.
    5: vector<txt_string>:MAX_TEXT_STRINGS text;

    /// The priority of the SRV resource record for this publication. See
    /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
    6: uint16 srv_priority;

    /// The weight of the SRV resource record for this publication. See
    /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
    7: uint16 srv_weight;
};

/// Describes a service instance.
table ServiceInstance2 {
    /// The name of the service.
    1: service_name service;

    /// The name of the service instance.
    2: instance_name instance;

    /// IPv4 socket address for the service. May be unset.
    3: fuchsia.net.Ipv4SocketAddress ipv4_endpoint;

    /// IPv6 socket address for the service. May be unset.
    4: fuchsia.net.Ipv6SocketAddress ipv6_endpoint;

    /// Text strings describing the instance.
    5: vector<txt_string>:MAX_TEXT_STRINGS text;

    /// The priority of the SRV resource record for this publication. See
    /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
    6: uint16 srv_priority;

    /// The weight of the SRV resource record for this publication. See
    /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
    7: uint16 srv_weight;
};

/// Client-supplied publication responder interface.
protocol PublicationResponder {
    /// Provides instance information for initial announcements and query
    /// responses relating to the service instance specified in
    /// `Publisher.PublishServiceInstance`.  If the publication relates to a
    /// subtype of the service, `subtype` contains the subtype, otherwise
    /// it is null. If `publication` is null, no announcement or response is
    /// transmitted. Strings in `text` are transmitted in the TXT record.
    OnPublication(
        PublicationCause publication_cause,
        subtype_name? subtype,
        vector<fuchsia.net.IpAddress>:64 source_addresses)
        -> (Publication? publication);

    /// Sets the subtypes for the service instance. The specified subtypes will
    /// be announced subject to filtering through the responder. The initial
    /// subtype collection is empty.
    -> SetSubtypes(vector<subtype_name>:MAX_SUBTYPES subtypes);

    /// Initiates reannouncement of the service instance due to a change in the
    /// instance's port number or text strings. All announcements are filtered
    /// through `OnPublication`, which replies with the new port and text
    /// values.
    -> Reannounce();
};

/// Describes the cause of a publication.
enum PublicationCause : int32 {
    /// Indicates the publication is part of an initial announcement.
    ANNOUNCEMENT = 1;

    /// Indicates the publication is in response to a question that requests a
    /// multicast response.
    QUERY_MULTICAST_RESPONSE = 2;

    /// Indicates the publication is in response to a question that requests a
    /// unicast response.
    QUERY_UNICAST_RESPONSE = 3;
};

/// Client-supplied publication responder interface.
protocol PublicationResponder2 {
    /// Provides instance information for initial announcements and query
    /// responses relating to the service instance specified in
    /// `Publisher.PublishServiceInstance`. `query` indicates whether data is
    /// requested for an initial announcement (false) or in response to a query
    /// (true). If the publication relates to a subtype of the service,
    /// `subtype` contains the subtype, otherwise it is null. If `publication`
    /// is null, no announcement or response is transmitted. Strings in `text`
    /// are transmitted in the TXT record.
    OnPublication(
        bool query, subtype_name? subtype, vector<fuchsia.net.IpAddress>:64 source_addresses)
        -> (Publication? publication);

    /// Sets the subtypes for the service instance. The specified subtypes will
    /// be announced subject to filtering through the responder. The initial
    /// subtype collection is empty.
    -> SetSubtypes(vector<subtype_name>:MAX_SUBTYPES subtypes);

    /// Initiates reannouncement of the service instance due to a change in the
    /// instance's port number or text strings. All announcements are filtered
    /// through `OnPublication`, which replies with the new port and text
    /// values.
    -> Reannounce();
};

/// Describes an initial instance announcement or query response. In typical
/// use, the default SRV priority, SRV weight and TTL values should be used. TTL
/// values are rounded down to the nearest second. TTL values less than one
/// second are not permitted and will result in the `PublicationResponder`
/// channel being closed.
struct Publication {
    /// The port at which the service instance is addressable.
    uint16 port;

    /// Text strings describing the instance.
    vector<txt_string>:MAX_TEXT_STRINGS text;

    /// The priority of the SRV resource record for this publication. See
    /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
    uint16 srv_priority = DEFAULT_SRV_PRIORITY;

    /// The weight of the SRV resource record for this publication. See
    /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
    uint16 srv_weight = DEFAULT_SRV_WEIGHT;

    /// Time-to-live for PTR resource records.
    zx.duration ptr_ttl = DEFAULT_PTR_TTL;

    /// Time-to-live for SRV resource records.
    zx.duration srv_ttl = DEFAULT_SRV_TTL;

    /// Time-to-live for TXT resource records.
    zx.duration txt_ttl = DEFAULT_TXT_TTL;
};

const uint16 DEFAULT_SRV_PRIORITY = 0;
const uint16 DEFAULT_SRV_WEIGHT = 0;
const zx.duration DEFAULT_PTR_TTL = 120000000000; // 2 minutes
const zx.duration DEFAULT_SRV_TTL = 120000000000; // 2 minutes
const zx.duration DEFAULT_TXT_TTL = 4500000000000; // 75 minutes
const uint32 MAX_TEXT_STRINGS = 256;
const uint32 MAX_SUBTYPES = 256;
