// 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)
// 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.
using 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.
using 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.
using 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.
using 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.
using 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,
                           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;
};

/// 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 this
    /// mDNS implementation.
    /// NOTE: This value isn't used currently. It appears here for backward
    /// compatibility.
    [Deprecated]
    ALREADY_PUBLISHED_LOCALLY = 3;

    /// 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;
};

/// 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`. `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();
};

/// 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;
