// 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.
@available(added=11)
library fuchsia.posix.socket.raw;

using fuchsia.net;
using fuchsia.posix;
using fuchsia.posix.socket;
using zx;

type Empty = struct {};

/// The protocol a raw socket may be associated with.
alias Protocol = uint8;

/// The protocol a raw socket is associated with.
type ProtocolAssociation = strict union {
    /// Indicates no association with any protocol.
    ///
    /// The socket will not receive packets. Sent packets must include the
    /// network header.
    1: unassociated Empty;

    /// The associated protocol.
    ///
    /// The socket may only send and receive network packets for the associated
    /// protocol.
    2: associated Protocol;
};

/// A raw network socket provider.
@discoverable
closed protocol Provider {
    /// Requests a raw socket.
    strict Socket(struct {
        domain fuchsia.posix.socket.Domain;
        proto ProtocolAssociation;
    }) -> (resource struct {
        s client_end:Socket;
    }) error fuchsia.posix.Errno;
};

/// A filter for ICMPv6 types.
type Icmpv6Filter = struct {
    /// Indicates whether or not an ICMPv6 type should be blocked.
    ///
    /// Each bit index encodes an ICMPv6 type; bit 0 in `blocked_types[0]` holds
    /// the flag for ICMPv6 type 0 and bit 31 in `blocked_types[7]` holds the
    /// flag for ICMPv6 type 255.
    ///
    /// Equivalent to Linux's `icmp6_filter.icmp6_filt`.
    blocked_types array<uint32, 8>;
};

/// IPv6 socket checksum configuration.
type Ipv6ChecksumConfiguration = strict union {
    /// Indicates that the stack should not calculate checksums for outgoing
    /// packets and valiate checksums for incoming packets.
    1: disabled Empty;

    /// Indicates that the stack should calculate checksums for outgoing packets
    /// and validate checksums for incoming packets.
    ///
    /// `offset` indicates where the checksum is found in the IPv6 packet's
    /// payload.
    ///
    /// The offset must be aligned to the size of an internet checksum as
    /// specified in RFC 1071. That is, the offset must be 2-byte aligned.
    2: offset int32;
};

// TODO(https://fxbug.dev/42056856): Use a generated constant.
const SOCKET_PROTOCOL_NAME string = "fuchsia.posix.socket.raw/Socket";

/// A raw network socket.
///
/// Once a socket has been retrieved from a provider, this interface is then
/// used to further configure and use the socket. This interface is essentially
/// POSIX.
///
/// All methods on this type are nonblocking; their exact behaviors match their
/// Linux counterparts.
///
/// *Warning:* This protocol is not yet ready for direct use by clients.
/// Instead, clients should use the BSD sockets API to interact with sockets.
/// We plan to change this protocol substantially and clients that couple
/// directly to this protocol will make those changes more difficult.
closed protocol Socket {
    compose fuchsia.posix.socket.BaseNetworkSocket;

    strict Describe() -> (resource table {
        /// Signals additional information about the state of the socket such as
        /// readiness or shutdown-ness.
        1: event zx.Handle:EVENTPAIR;
    });

    /// Receives a message from the socket.
    ///
    /// + request `want_addr` request message's source address information to
    ///   be returned.
    /// + request `data_len` the maximum allowed length of the response data
    ///   buffer.
    /// + request `want_control` request ancillary data to be returned.
    /// + request `flags` flags for the receive request.
    /// - response `addr` the message's source address information, if
    ///   requested.
    /// - response `data` the message.
    /// - response `control` control messages, if requested.
    /// - response `truncated` indicates whether or not the returned message
    ///   was truncated.
    strict RecvMsg(struct {
        want_addr bool;
        data_len uint32;
        want_control bool;
        flags fuchsia.posix.socket.RecvMsgFlags;
    }) -> (struct {
        addr fuchsia.net.SocketAddress:optional;
        data vector<uint8>:MAX;
        control fuchsia.posix.socket.NetworkSocketRecvControlData;
        truncated uint32;
    }) error fuchsia.posix.Errno;

    /// Sends a message on the socket.
    ///
    /// + request `addr` the address to send the message to. If unset, will
    ///   send to the connected peer.
    /// + request `data` the message.
    /// + request `control` ancillary data.
    /// + request `flags` flags for the send request.
    strict SendMsg(struct {
        addr fuchsia.net.SocketAddress:optional;
        data vector<uint8>:MAX;
        control fuchsia.posix.socket.NetworkSocketSendControlData;
        flags fuchsia.posix.socket.SendMsgFlags;
    }) -> () error fuchsia.posix.Errno;

    /// Retrieves creation information from the socket.
    ///
    /// - response `domain` the socket's associated domain.
    /// - response `proto` the socket's associated protocol.
    strict GetInfo() -> (struct {
        domain fuchsia.posix.socket.Domain;
        proto ProtocolAssociation;
    }) error fuchsia.posix.Errno;

    /// Set `SOL_IP` -> `IP_HDRINCL`.
    strict SetIpHeaderIncluded(struct {
        value bool;
    }) -> () error fuchsia.posix.Errno;
    /// Get `SOL_IP` -> `IP_HDRINCL`.
    strict GetIpHeaderIncluded() -> (struct {
        value bool;
    }) error fuchsia.posix.Errno;

    /// Set `SOL_ICMPV6` -> `ICMP6_FILTER`.
    strict SetIcmpv6Filter(struct {
        filter Icmpv6Filter;
    }) -> () error fuchsia.posix.Errno;
    /// Get `SOL_ICMPV6` -> `ICMP6_FILTER`.
    strict GetIcmpv6Filter() -> (struct {
        filter Icmpv6Filter;
    }) error fuchsia.posix.Errno;

    /// Set `SOL_IPV6` -> `IPV6_CHECKSUM`.
    strict SetIpv6Checksum(struct {
        config Ipv6ChecksumConfiguration;
    }) -> () error fuchsia.posix.Errno;
    /// Get `SOL_IPV6` -> `IPV6_CHECKSUM`.
    strict GetIpv6Checksum() -> (struct {
        config Ipv6ChecksumConfiguration;
    }) error fuchsia.posix.Errno;
};
