blob: 979eb6450504773d71479b9d9b0c407876033980 [file] [log] [blame]
// Copyright 2019 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;
using fuchsia.io;
using fuchsia.net;
using fuchsia.posix;
using zx;
/// Chosen to be large enough to hold whatever we might want to cram in it. So long as we support
/// socket options, we don't have a good sense of what we might want to send as payload.
// TODO(https://fxbug.dev/44347): replace C structures on the wire with FIDL types.
alias sockopt = bytes:900;
/// The maximum length of an interface name.
// `sizeof((struct ifreq).ifr_name) == 16`; the last byte is reserved for the null terminator.
const uint8 INTERFACE_NAME_LENGTH = 15;
/// An interface name as a sequence of bytes.
alias interface_name = string:INTERFACE_NAME_LENGTH;
/// A 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. Its implementation must
/// support Linux-specific arguments to {Get,Set}SockOpt.
///
/// 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 BaseSocket {
compose fuchsia.io.Node;
/// Sets the local address used for the socket.
Bind(fuchsia.net.SocketAddress addr) -> () error fuchsia.posix.Errno;
/// Initiates a connection to a remote address.
Connect(fuchsia.net.SocketAddress addr) -> () error fuchsia.posix.Errno;
/// Clears connection information from this socket.
Disconnect() -> () error fuchsia.posix.Errno;
/// Retrieves the local socket address.
GetSockName() -> (fuchsia.net.SocketAddress addr) error fuchsia.posix.Errno;
/// Retrieves the remote socket address.
GetPeerName() -> (fuchsia.net.SocketAddress addr) error fuchsia.posix.Errno;
/// Sets the value of a socket option.
SetSockOpt(int16 level, int16 optname, sockopt optval) -> () error fuchsia.posix.Errno;
/// Retrieves the value of a socket option.
GetSockOpt(int16 level, int16 optname) -> (sockopt optval) error fuchsia.posix.Errno;
};
struct Empty {
};
/// Ancillary data for sending datagram sockets.
table SendControlData {
};
/// Ancillary data for received datagram sockets.
table RecvControlData {
};
/// Flags controlling RecvMsg behavior.
bits RecvMsgFlags : uint16 {
/// Returns data from the receive queue without removing from it.
///
/// Equivalent to `MSG_PEEK`.
PEEK = 2;
};
// Flags controlling SendMsg behavior.
bits SendMsgFlags : uint16 {
// NOTE We don't currently support any flags, but we need at least one definition.
RESERVED = 0x8000;
};
/// Socket shutdown mode.
bits ShutdownMode : uint16 {
/// Shutdown socket read endpoint.
READ = 1;
/// Shutdown socket write endpoint.
WRITE = 2;
};
/// A datagram socket.
///
/// This type's [`fuchsia.io.Node/Describe`] method returns an eventpair which is used to signal
/// additional information about the state of the socket such as readiness or shutdown-ness.
///
/// All methods on this type are nonblocking; their exact behaviors match their Linux counterparts.
protocol DatagramSocket {
compose BaseSocket;
/// Shuts down part of the socket.
Shutdown(ShutdownMode mode) -> () error fuchsia.posix.Errno;
/// Receives a message from the socket.
RecvMsg(bool want_addr, uint32 data_len, bool want_control, RecvMsgFlags flags) -> (fuchsia.net.SocketAddress? addr, bytes data, RecvControlData control, uint32 truncated) error fuchsia.posix.Errno;
/// Sends a message on the socket.
SendMsg(fuchsia.net.SocketAddress? addr, bytes:MAX data, SendControlData control, SendMsgFlags flags) -> (int64 len) error fuchsia.posix.Errno;
};
/// A stream socket.
///
/// This type's [`fuchsia.io.Node/Describe`] method returns a socket which is used to transfer data
/// to and from the caller. Signals are used to communicate additional information about the state
/// of the socket such as connectedness and the presence of incoming connections in the case of a
/// listening socket.
///
/// All methods on this type are nonblocking; their exact behaviors match their Linux counterparts.
protocol StreamSocket {
compose BaseSocket;
/// Begins listening for new incoming connections. At most `backlog` connections will be
/// buffered.
Listen(int16 backlog) -> () error fuchsia.posix.Errno;
/// Accepts a buffered incoming connection.
Accept(bool want_addr) -> (fuchsia.net.SocketAddress? addr, StreamSocket s) error fuchsia.posix.Errno;
};
/// Holds information about an interface and its addresses.
table InterfaceAddresses {
/// ID of the interface.
1: uint64 id;
/// Name of the interface.
2: interface_name name;
/// Contains the interface flags, as returned by the SIOCGIFFLAGS ioctl
/// operation.
///
/// TODO(fxbug.dev/64758): remove this once all clients are transitioned to
/// use more strongly-typed `interface_flags`.
3: uint32 flags;
/// All addresses currently assigned to the interface.
4: vector<fuchsia.net.Subnet>:MAX addresses;
/// Contains the interface flags, as returned by the SIOCGIFFLAGS ioctl
/// operation.
5: InterfaceFlags interface_flags;
};
/// A socket's domain.
///
/// Determines the addressing domain for a socket.
enum Domain : int16 {
/// An IPv4 socket. Equivalent to `AF_INET`.
IPV4 = 0;
/// An IPv6 socket. Equivalent to `AF_INET6`.
IPV6 = 1;
};
/// Protocols supported by [`fuchsia.posix.socket/DatagramSocket`].
///
/// `DatagramSocketProtocol` enumerates the protocols supported by the network stack over datagram
/// sockets.
// NOTE: This list can be expanded to accommodate other protocols should the need arise. Most
// notably, there exists the question on whether to support raw IP sockets and what the access model
// for those should be.
enum DatagramSocketProtocol {
/// UDP (User Datagram Protocol).
///
/// A UDP socket is equivalent to the POSIX API of `SOCK_DGRAM` with a protocol of 0 or
/// `IPPROTO_UDP`.
UDP = 1;
/// ICMP (Internet Control Message Protocol) echo.
///
/// An ICMP echo socket is equivalent to the POSIX API of `SOCK_DGRAM` with a protocol of
/// `IPPROTO_ICMP` `IPPROTO_ICMPV6` (depending on provided domain).
///
/// Datagrams sent over an ICMP echo socket *must* have a valid ICMP or ICMPv6 echo header.
ICMP_ECHO = 2;
};
/// Protocols supported by [`fuchsia.posix.socket/StreamSocket`].
///
/// `StreamSocketProtocol` enumerates the protocols supported by the network stack over stream
/// sockets.
enum StreamSocketProtocol {
/// TCP (Transmission Control Protocol).
///
/// A TCP socket is equivalent to the POSIX API of `SOCK_STREAM` with a protocol of 0 or
/// `IPPROTO_TCP`.
TCP = 0;
};
/// Bits representing the interface flags as returned by the SIOCGIFFLAGS ioctl
/// operation. These bitmasks are intended to track the C API definition. For
/// example, `InterfaceFlags.UP` corresponds to `IFF_UP`, etc.
bits InterfaceFlags : uint16 {
UP = 0x1;
BROADCAST = 0x2;
DEBUG = 0x4;
LOOPBACK = 0x8;
POINTTOPOINT = 0x10;
NOTRAILERS = 0x20;
RUNNING = 0x40;
NOARP = 0x80;
PROMISC = 0x100;
ALLMULTI = 0x200;
LEADER = 0x400;
FOLLOWER = 0x800;
MULTICAST = 0x1000;
PORTSEL = 0x2000;
AUTOMEDIA = 0x4000;
DYNAMIC = 0x8000;
};
/// Provider implements the POSIX sockets API.
[Discoverable]
protocol Provider {
/// Requests a stream socket with the specified parameters.
StreamSocket(Domain domain, StreamSocketProtocol proto) -> (StreamSocket s) error fuchsia.posix.Errno;
/// Requests a datagram socket with the specified parameters.
DatagramSocket(Domain domain, DatagramSocketProtocol proto) -> (DatagramSocket s) error fuchsia.posix.Errno;
/// Looks up an interface by its index and returns its name. Returns `ZX_ERR_NOT_FOUND` if the
/// specified index doesn't exist.
InterfaceIndexToName(uint64 index) -> (interface_name name) error zx.status;
/// Looks up an interface by its name and returns its index. Returns `ZX_ERR_NOT_FOUND` if the
/// specified name doesn't exist.
InterfaceNameToIndex(interface_name name) -> (uint64 index) error zx.status;
/// Looks up an interface by its name and returns its flags. Returns `ZX_ERR_NOT_FOUND` if the
/// specified name doesn't exist.
InterfaceNameToFlags(interface_name name) -> (InterfaceFlags flags) error zx.status;
/// Requests a list of [`fuchsia.posix.socket.InterfaceAddresses`]
/// describing the network interfaces on the system.
GetInterfaceAddresses() -> (vector<InterfaceAddresses>:MAX interfaces);
};