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