// 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.
library fuchsia.posix.socket.raw;

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

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
protocol Provider {
    /// Requests a raw socket.
    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;
};

/// 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.
protocol Socket {
    compose fuchsia.posix.socket.BaseNetworkSocket;

    /// 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.
    RecvMsg(struct {
        want_addr bool;
        data_len uint32;
        want_control bool;
        flags fuchsia.posix.socket.RecvMsgFlags;
    }) -> (struct {
        addr fuchsia.net.SocketAddress:optional;
        data bytes;
        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.
    SendMsg(struct {
        addr fuchsia.net.SocketAddress:optional;
        data bytes:MAX;
        control fuchsia.posix.socket.NetworkSocketSendControlData;
        flags fuchsia.posix.socket.SendMsgFlags;
    }) -> (struct {}) error fuchsia.posix.Errno;

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

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

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

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