blob: 033c957aed75efb215aa820ff14c191ade14c226 [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.
@available(added=11)
library fuchsia.posix.socket;
using fuchsia.net;
using fuchsia.net.interfaces;
using fuchsia.posix;
using fuchsia.unknown;
using zx;
// TODO(https://fxbug.dev/42061412): remove once zircon signal values are defined
// in the zx FIDL library.
const USER_SIGNAL_0 uint32 = 0x01000000;
const USER_SIGNAL_1 uint32 = 0x02000000;
const USER_SIGNAL_2 uint32 = 0x04000000;
const USER_SIGNAL_3 uint32 = 0x08000000;
const USER_SIGNAL_4 uint32 = 0x10000000;
const USER_SIGNAL_5 uint32 = 0x20000000;
const SIGNAL_DATAGRAM_INCOMING uint32 = USER_SIGNAL_0;
const SIGNAL_DATAGRAM_OUTGOING uint32 = USER_SIGNAL_1;
const SIGNAL_DATAGRAM_ERROR uint32 = USER_SIGNAL_2;
const SIGNAL_DATAGRAM_SHUTDOWN_READ uint32 = USER_SIGNAL_4;
const SIGNAL_DATAGRAM_SHUTDOWN_WRITE uint32 = USER_SIGNAL_5;
const SIGNAL_STREAM_INCOMING uint32 = USER_SIGNAL_0;
const SIGNAL_STREAM_CONNECTED uint32 = USER_SIGNAL_3;
/// Socket shutdown mode.
type ShutdownMode = strict bits : uint16 {
/// Shutdown socket read endpoint.
READ = 1;
/// Shutdown socket write endpoint.
WRITE = 2;
};
/// Packet timestamp reporting precision options.
type TimestampOption = strict enum {
/// Do not report timestamp.
DISABLED = 0;
/// Report timestamp with nanosecond precision.
NANOSECOND = 1;
/// Report timestamp with microsecond precision.
MICROSECOND = 2;
};
/// A socket.
closed protocol BaseSocket {
compose fuchsia.unknown.Cloneable;
compose fuchsia.unknown.Closeable;
compose fuchsia.unknown.Queryable;
/// Set `SOL_SOCKET` -> `SO_REUSEADDR`.
strict SetReuseAddress(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_REUSEADDR`.
strict GetReuseAddress() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
// NOTE: get `SOL_SOCKET` -> `SO_TYPE` is implemented in the client
// (libfdio).
/// Get `SOL_SOCKET` -> `SO_ERROR`.
/// Returns the last error if there is an error set on the socket.
strict GetError() -> () error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_BROADCAST`.
strict SetBroadcast(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_BROADCAST`.
strict GetBroadcast() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_SNDBUF`.
strict SetSendBuffer(struct {
value_bytes uint64;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_SNDBUF`.
strict GetSendBuffer() -> (struct {
value_bytes uint64;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_RCVBUF`.
strict SetReceiveBuffer(struct {
value_bytes uint64;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_RCVBUF`.
strict GetReceiveBuffer() -> (struct {
value_bytes uint64;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_KEEPALIVE`.
strict SetKeepAlive(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_KEEPALIVE`.
strict GetKeepAlive() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_OOBINLINE`.
strict SetOutOfBandInline(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_OOBINLINE`.
strict GetOutOfBandInline() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_NO_CHECK`.
strict SetNoCheck(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_NO_CHECK`.
strict GetNoCheck() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_LINGER`.
strict SetLinger(struct {
linger bool;
length_secs uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_LINGER`.
strict GetLinger() -> (struct {
linger bool;
length_secs uint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_REUSEPORT`.
strict SetReusePort(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_REUSEPORT`.
strict GetReusePort() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
// NOTE: get `SOL_SOCKET` -> `SO_PEERCRED` not supported in netstack.
// NOTE: get/set `SOL_SOCKET` -> `SO_SNDTIMEO` is implemented in the client
// (libfdio).
// NOTE: get/set `SOL_SOCKET` -> `SO_RCVTIMEO` is implemented in the client
// (libfdio).
/// Get `SOL_SOCKET` -> `SO_ACCEPTCONN`.
strict GetAcceptConn() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_BINDTODEVICE`.
strict SetBindToDevice(struct {
value fuchsia.net.interfaces.Name;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_BINDTODEVICE`.
strict GetBindToDevice() -> (struct {
value fuchsia.net.interfaces.Name;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_BINDTOIFINDEX`.
/// If `value` is 0, this clears the bound interface.
@available(added=20)
strict SetBindToInterfaceIndex(struct {
value fuchsia.net.InterfaceId;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_BINDTOIFINDEX`.
@available(added=20)
strict GetBindToInterfaceIndex() -> (struct {
value fuchsia.net.InterfaceId;
}) error fuchsia.posix.Errno;
/// Set `SOL_SOCKET` -> `SO_TIMESTAMP` or `SO_TIMESTAMPNS`.
// These two options are mutually exclusive. Enabling one disables the
// other. Disabling either disables both.
// https://github.com/torvalds/linux/blob/dcd68326d29/net/core/sock.c#L790-L801
strict SetTimestamp(struct {
value TimestampOption;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_SOCKET` -> `SO_TIMESTAMP` or `SO_TIMESTAMPNS`.
strict GetTimestamp() -> (struct {
value TimestampOption;
}) error fuchsia.posix.Errno;
};
/// A network socket.
closed protocol BaseNetworkSocket {
compose BaseSocket;
/// Sets the local address used for the socket.
strict Bind(struct {
addr fuchsia.net.SocketAddress;
}) -> () error fuchsia.posix.Errno;
/// Initiates a connection to a remote address.
strict Connect(struct {
addr fuchsia.net.SocketAddress;
}) -> () error fuchsia.posix.Errno;
/// Clears connection information from this socket.
strict Disconnect() -> () error fuchsia.posix.Errno;
/// Retrieves the local socket address.
strict GetSockName() -> (struct {
addr fuchsia.net.SocketAddress;
}) error fuchsia.posix.Errno;
/// Retrieves the remote socket address.
strict GetPeerName() -> (struct {
addr fuchsia.net.SocketAddress;
}) error fuchsia.posix.Errno;
/// Shuts down part of the socket.
strict Shutdown(struct {
mode ShutdownMode;
}) -> () error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_TOS`.
strict SetIpTypeOfService(struct {
value uint8;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_TOS`.
strict GetIpTypeOfService() -> (struct {
value uint8;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_TTL`.
// [1, 255] but unset means default, which is `sysctl net.ipv4.ip_default_ttl`.
// https://github.com/torvalds/linux/blob/6f38be8f2cc/net/ipv4/ip_sockglue.c#L1605-L1612
strict SetIpTtl(struct {
value OptionalUint8;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_TTL`.
strict GetIpTtl() -> (struct {
value uint8;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_PKTINFO`.
strict SetIpPacketInfo(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_PKTINFO`.
strict GetIpPacketInfo() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_RECVTOS`.
strict SetIpReceiveTypeOfService(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_RECVTOS`.
strict GetIpReceiveTypeOfService() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_RECVTTL`.
strict SetIpReceiveTtl(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_RECVTTL`.
strict GetIpReceiveTtl() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_MULTICAST_IF`.
strict SetIpMulticastInterface(struct {
iface fuchsia.net.InterfaceId;
address fuchsia.net.Ipv4Address;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_MULTICAST_IF`.
strict GetIpMulticastInterface() -> (struct {
value fuchsia.net.Ipv4Address;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_MULTICAST_TTL`.
// [1, 255] but unset means kernel default, which is 1.
// https://github.com/torvalds/linux/blob/6f38be8f2cc/net/ipv4/ip_sockglue.c#L1088-L1098
strict SetIpMulticastTtl(struct {
value OptionalUint8;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_MULTICAST_TTL`.
strict GetIpMulticastTtl() -> (struct {
value uint8;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_MULTICAST_LOOP`.
strict SetIpMulticastLoopback(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_MULTICAST_LOOP`.
strict GetIpMulticastLoopback() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_ADD_MEMBERSHIP`
strict AddIpMembership(struct {
membership IpMulticastMembership;
}) -> () error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_DROP_MEMBERSHIP`
strict DropIpMembership(struct {
membership IpMulticastMembership;
}) -> () error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_TRANSPARENT`
@available(added=15)
strict SetIpTransparent(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_TRANSPARENT`
@available(added=15)
strict GetIpTransparent() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IP` -> `IP_RECVORIGDSTADDR`
@available(added=15)
strict SetIpReceiveOriginalDestinationAddress(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `IP_RECVORIGDSTADDR`
@available(added=15)
strict GetIpReceiveOriginalDestinationAddress() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_ADD_MEMBERSHIP`.
strict AddIpv6Membership(struct {
membership Ipv6MulticastMembership;
}) -> () error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_DROP_MEMBERSHIP`.
strict DropIpv6Membership(struct {
membership Ipv6MulticastMembership;
}) -> () error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_MULTICAST_IF`.
strict SetIpv6MulticastInterface(struct {
value fuchsia.net.InterfaceId;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_MULTICAST_IF`.
strict GetIpv6MulticastInterface() -> (struct {
value fuchsia.net.InterfaceId;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_UNICAST_HOPS`.
// [0, 255] but unset means use default, which is `sysctl net.ipv6.conf.<device>.hop_limit`.
// https://github.com/torvalds/linux/blob/6f38be8f2cc/net/ipv6/ipv6_sockglue.c#L742-L749
// https://github.com/torvalds/linux/blob/6f38be8f2cc/net/ipv6/ip6_output.c#L291-L294
strict SetIpv6UnicastHops(struct {
value OptionalUint8;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_UNICAST_HOPS`.
strict GetIpv6UnicastHops() -> (struct {
value uint8;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_RECVHOPLIMIT`.
strict SetIpv6ReceiveHopLimit(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_RECVHOPLIMIT`.
strict GetIpv6ReceiveHopLimit() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_MULTICAST_HOPS`.
// [0, 255] but unset means kernel default, which is 1.
// https://github.com/torvalds/linux/blob/6f38be8f2cc/net/ipv6/ipv6_sockglue.c#L751-L760
strict SetIpv6MulticastHops(struct {
value OptionalUint8;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_MULTICAST_HOPS`.
strict GetIpv6MulticastHops() -> (struct {
value uint8;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_MULTICAST_LOOP`.
strict SetIpv6MulticastLoopback(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_MULTICAST_LOOP`.
strict GetIpv6MulticastLoopback() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_V6ONLY`.
strict SetIpv6Only(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_V6ONLY`.
strict GetIpv6Only() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
// NOTE: get `SOL_IPV6` -> `IPV6_PATHMTU` not supported in netstack.
/// Set `SOL_IPV6` -> `IPV6_RECVTCLASS`.
strict SetIpv6ReceiveTrafficClass(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_RECVTCLASS`.
strict GetIpv6ReceiveTrafficClass() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_TCLASS`
// NOTE: see https://tools.ietf.org/html/rfc3542.html for definitions.
//
// [0, 255] but unset means kernel default, which is 0.
// https://github.com/torvalds/linux/blob/6f38be8f2cc/net/ipv6/ipv6_sockglue.c#L594-L611
strict SetIpv6TrafficClass(struct {
value OptionalUint8;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_TCLASS`.
strict GetIpv6TrafficClass() -> (struct {
value uint8;
}) error fuchsia.posix.Errno;
/// Set `SOL_IPV6` -> `IPV6_RECVPKTINFO`.
strict SetIpv6ReceivePacketInfo(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_IPV6` -> `IPV6_RECVPKTINFO`.
strict GetIpv6ReceivePacketInfo() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Get `SOL_IP` -> `SO_ORIGINAL_DST`.
// Return the original destination for the socket (as it was before NAT translation).
@available(added=15)
strict GetOriginalDestination() -> (struct {
value fuchsia.net.SocketAddress;
}) error fuchsia.posix.Errno;
};
/// IPv4 multicast membership options.
type IpMulticastMembership = struct {
/// Interface index for membership.
iface fuchsia.net.InterfaceId;
/// Local interface address requesting or relinquishing ownership.
local_addr fuchsia.net.Ipv4Address;
/// Address of the multicast group the membership refers to.
mcast_addr fuchsia.net.Ipv4Address;
};
/// IPv6 multicast membership options.
type Ipv6MulticastMembership = struct {
/// Interface index for membership.
iface fuchsia.net.InterfaceId;
/// Address of the multicast group the membership refers to.
mcast_addr fuchsia.net.Ipv6Address;
};
/// An optional byte value.
// This exists because FIDL does not allow optional integers.
type OptionalUint8 = strict union {
1: value uint8;
2: unset Empty;
};
/// An optional uint32 value.
// This exists because FIDL does not allow optional integers.
type OptionalUint32 = strict union {
1: value uint32;
2: unset Empty;
};
// TODO(https://fxbug.dev/42159332): Use built-in empty struct when available.
type Empty = struct {};
/// Socket level ancillary data that can be received.
///
/// These match control messages with a `SOL_SOCKET` level.
type SocketRecvControlData = table {
/// Data about the time at which the packet was received.
3: timestamp @generated_name("Timestamp") struct {
/// Time in nanoseconds since epoch (January 1 1970 GMT).
nanoseconds int64;
/// Identifies whether/how the timestamp should be returned to the user.
/// Ignored in the DatagramSocket protocol.
requested TimestampOption;
};
};
/// Network socket (L3) ancillary data that can be received.
type NetworkSocketRecvControlData = table {
/// Socket level ancillary data.
1: socket SocketRecvControlData;
/// IPv4 level ancillary data.
///
/// These match POSIX `SOL_IP` control messages.
2: ip @generated_name("IpRecvControlData") table {
/// The Type of Service value found in a received packet's IPv4 header.
///
/// Present if the `SOL_IP` -> `IP_RECVTOS` option is enabled.
1: tos uint8;
/// The Time to Live value found in a received packet's IPv4 header.
///
/// Present if the `SOL_IP` -> `IP_RECVTTL` option is enabled.
2: ttl uint8;
/// The original destination address.
///
/// Present if the `SOL_IP` -> `IP_RECVORIGDSTADDR` option is enabled.
@available(added=15)
3: original_destination_address fuchsia.net.SocketAddress;
};
/// IPv6 level ancillary data.
///
/// These match POSIX `SOL_IPV6` control messages.
3: ipv6 @generated_name("Ipv6RecvControlData") table {
/// The Traffic Class of a packet that was received.
///
/// Present if the `SOL_IPV6` -> `IPV6_RECVTCLASS` option is enabled.
1: tclass uint8;
/// The Hop Limit of a packet that was received.
///
/// Present if the `SOL_IPV6` -> `IPV6_RECVHOPLIMIT` option is enabled.
2: hoplimit uint8;
/// The packet information of a packet that was received.
///
/// Present if the `SOL_IPV6` -> `IPV6_RECVPKTINFO` option is enabled.
3: pktinfo @generated_name("Ipv6PktInfoRecvControlData") struct {
/// The index of the interface on which the IP packet was received.
iface fuchsia.net.InterfaceId;
/// The destination address specified in the received packet's IP
/// header.
header_destination_addr fuchsia.net.Ipv6Address;
};
};
};
/// Socket level ancillary data that can be sent.
///
/// These match the POSIX `SOL_SOCKET` control messages.
type SocketSendControlData = table {};
/// IPv6-specific disposition of sent data.
///
/// This is currently a struct instead of a table as it is meant to match
/// `in6_pktinfo` which is not expected to grow.
//
// TODO(https://fxbug.dev/42061079): Consider changing this type to better reflect
// the optionality of its fields.
type Ipv6PktInfoSendControlData = struct {
/// The interface index from which the IPv6 packet should be sent.
///
/// 0 indicates that the local interface is unspecified and the
/// stack may choose an appropriate interface.
iface uint64;
/// The source address from which the IPv6 packet should be sent.
///
/// All zeroes indicates that the local address is unspecified and
/// the stack may choose an appropriate address (i.e. the local
/// address to which the socket is bound).
local_addr fuchsia.net.Ipv6Address;
};
/// Network socket (L3) ancillary data that can be sent.
type NetworkSocketSendControlData = table {
/// Socket level ancillary data.
1: socket SocketSendControlData;
/// IPv4 level ancillary data.
///
/// These match POSIX `SOL_IP` control messages.
2: ip @generated_name("IpSendControlData") table {
// TODO(https://fxbug.dev/42178100): Use ordinal 1 for the `SOL_IP` ->
// `IP_TOS` control message, to maintain a consistent order with the
// similar IpRecvControlData table.
/// The Time to Live value to set in the IPv4 header of an outgoing
/// packet.
// Values from range [1, 255] are valid.
2: ttl uint8;
};
/// IPv6 level ancillary data.
///
/// These match POSIX `SOL_IPV6` control messages.
3: ipv6 @generated_name("Ipv6SendControlData") table {
// TODO(https://fxbug.dev/42178100): Use ordinal 1 for the `SOL_IPV6` ->
// `IPV6_TCLASS` control message, to maintain a consistent order with
// the similar IpSendControlData table.
/// The Hop Limit value to set in the IPv6 header of an outgoing
/// packet.
2: hoplimit uint8;
/// Information controlling the local interface and/or address used when
/// sending an IPv6 packet.
3: pktinfo Ipv6PktInfoSendControlData;
};
};
/// Flags controlling RecvMsg behavior.
type RecvMsgFlags = strict bits : uint16 {
/// Returns data from the receive queue without removing from it.
///
/// Equivalent to `MSG_PEEK`.
PEEK = 2;
};
// Flags controlling SendMsg behavior.
type SendMsgFlags = strict bits : uint16 {
// NOTE We don't currently support any flags, but we need at least one
// definition.
RESERVED = 0x8000;
};
/// Base protocol shared by all datagram sockets.
///
/// Complete implementations of a datagram socket should compose this protocol.
closed protocol BaseDatagramSocket {
compose BaseNetworkSocket;
/// Retrieves creation information from the socket.
///
/// - response `domain` the socket's associated domain.
/// - response `proto` the socket's associated protocol.
strict GetInfo() -> (struct {
domain Domain;
proto DatagramSocketProtocol;
}) error fuchsia.posix.Errno;
};
type DatagramSocketSendControlData = table {
/// Network socket ancillary data.
1: network NetworkSocketSendControlData;
};
type DatagramSocketRecvControlData = table {
/// Network socket ancillary data.
1: network NetworkSocketRecvControlData;
};
/// Metadata of a received datagram.
type RecvMsgMeta = table {
/// The from address of the datagram.
1: from fuchsia.net.SocketAddress;
/// Ancillary control message data describing the datagram.
2: control DatagramSocketRecvControlData;
/// The length of the payload, in bytes.
3: payload_len uint16;
};
/// Metadata of a sent datagram.
type SendMsgMeta = table {
/// The destination address, if specified.
1: to fuchsia.net.SocketAddress;
/// Ancillary control message data used for sending the payload.
2: control DatagramSocketSendControlData;
};
/// Constant bounding the number of eventpairs returned by Netstack to clients
/// of the fast protocol.
///
/// Set equal to `ZX_WAIT_MANY_MAXIMUM_ITEMS` - 1, where `ZX_WAIT_MANY_MAXIMUM_ITEMS`
/// is defined in `//zircon/system/public/zircon/types.h` and bounds the number of eventpairs
/// in a single call to `zx_object_wait_many`. The bias leaves room to allow clients to wait
/// for errors on the zircon socket in the same call.
const FAST_UDP_WAIT_MANY_MAXIMUM_ITEMS uint32 = 63;
// TODO(https://fxbug.dev/42056856): Use a generated constant.
const DATAGRAM_SOCKET_PROTOCOL_NAME string = "fuchsia.posix.socket/DatagramSocket";
/// A datagram socket.
closed protocol DatagramSocket {
compose BaseDatagramSocket;
strict Describe() -> (resource table {
/// `ZX_SOCKET_DATAGRAM` on which data is sent and received.
1: socket zx.Handle:SOCKET;
/// Size of the buffer used to receive Tx metadata.
2: tx_meta_buf_size uint64;
/// Size of the buffer used to receive Rx metadata.
3: rx_meta_buf_size uint64;
/// Identifies the version of the protocol used to encode and decode
/// metadata sent alongside payloads over the socket.
4: metadata_encoding_protocol_version
@generated_name("UdpMetadataEncodingProtocolVersion")
flexible enum : uint16 {
ZERO = 0;
};
});
/// Validates that data can be sent.
///
/// + request `args` the requested disposition of data to be sent.
/// - response the constraints sent data must satisfy.
/// * error the error code indicating the reason for validation failure.
strict SendMsgPreflight(table {
/// The destination address.
///
/// If absent, interpreted as the method receiver's connected address and
/// causes the connected address to be returned.
///
/// Required if the method receiver is not connected.
1: to fuchsia.net.SocketAddress;
/// Information controlling the local interface and/or address used when
/// sending an IPv6 packet.
///
/// If absent, indicates that the stack is free to choose an appropriate
/// outgoing route.
//
// TODO(https://fxbug.dev/42057977): document behavior when this field is
// set and the socket is an IPv4 socket.
2: ipv6_pktinfo Ipv6PktInfoSendControlData;
}) -> (resource table {
/// The validated destination address.
///
/// Present only in response to an unset `to` addreess.
1: to fuchsia.net.SocketAddress;
/// Represents the validity of this structure.
///
/// The structure is invalid if any of the elements' peer is closed.
/// Datagrams sent with the associated metadata after invalidation will be
/// silently dropped.
2: validity vector<zx.Handle:<EVENTPAIR, zx.RIGHTS_BASIC>>:FAST_UDP_WAIT_MANY_MAXIMUM_ITEMS;
/// The maximum datagram size that can be sent.
///
/// Datagrams exceeding this will be silently dropped.
3: maximum_size uint32;
}) error fuchsia.posix.Errno;
/// Returns the set of requested control messages.
///
/// - response the set of currently requested control messages.
strict RecvMsgPostflight() -> (resource table {
/// Represents the validity of this structure.
///
/// The structure is invalid if the peer is closed.
1: validity zx.Handle:<EVENTPAIR, zx.RIGHTS_BASIC>;
/// Identifies whether the `SO_TIMESTAMP` or `SO_TIMESTAMPNS` control messages are
/// requested.
2: timestamp TimestampOption;
/// Identifies the status (requested or not) of up to 32 control messages.
/// This set size should be large enough to signal the status of all cmsgs supported
/// by POSIX systems as of 2022. If that changes, the set can be extended by adding
/// additional bits fields.
3: requests @generated_name("CmsgRequests") flexible bits : uint32 {
/// Identifies whether the `IP_RECVTOS` control message is requested.
IP_TOS = 0x1;
/// Identifies whether the `IP_RECVTTL` control message is requested.
IP_TTL = 0x2;
/// Identifies whether the `IPV6_RECVTCLASS` control message is requested.
IPV6_TCLASS = 0x4;
/// Identifies whether the `IPV6_RECVHOPLIMIT` control message is requested.
IPV6_HOPLIMIT = 0x8;
/// Identifies whether the `IPV6_RECVPKTINFO` control message is requested.
IPV6_PKTINFO = 0x10;
/// Identifies whether the `IP_RECVORIGDSTADDR` control message is requested.
@available(added=15)
IP_RECVORIGDSTADDR = 0x20;
};
}) error fuchsia.posix.Errno;
};
// TODO(https://fxbug.dev/42056856): Use a generated constant.
const SYNCHRONOUS_DATAGRAM_SOCKET_PROTOCOL_NAME string
= "fuchsia.posix.socket/SynchronousDatagramSocket";
/// A synchronous datagram socket.
///
/// This protocol defines synchronous methods for sending and receiving datagram
/// payloads over a channel. All methods are nonblocking; their behavior roughly
/// matches 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 SynchronousDatagramSocket {
compose BaseDatagramSocket;
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 RecvMsgFlags;
}) -> (struct {
addr fuchsia.net.SocketAddress:optional;
data vector<uint8>:MAX;
control DatagramSocketRecvControlData;
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.
/// - response `len` the number of bytes sent.
strict SendMsg(struct {
addr fuchsia.net.SocketAddress:optional;
data vector<uint8>:MAX;
control DatagramSocketSendControlData;
flags SendMsgFlags;
}) -> (struct {
len int64;
}) error fuchsia.posix.Errno;
};
// TODO(https://fxbug.dev/42056856): Use a generated constant.
const STREAM_SOCKET_PROTOCOL_NAME string = "fuchsia.posix.socket/StreamSocket";
/// A stream socket.
///
/// 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 StreamSocket {
compose BaseNetworkSocket;
strict Describe() -> (resource table {
/// `ZX_SOCKET_STREAM` on which data is sent and received.
1: socket zx.Handle:SOCKET;
});
/// Begins listening for new incoming connections. At most `backlog`
/// connections will be buffered.
strict Listen(struct {
backlog int16;
}) -> () error fuchsia.posix.Errno;
/// Accepts a buffered incoming connection.
strict Accept(struct {
want_addr bool;
}) -> (resource struct {
addr fuchsia.net.SocketAddress:optional;
s client_end:StreamSocket;
}) error fuchsia.posix.Errno;
/// Retrieves creation information from the socket.
strict GetInfo() -> (struct {
domain Domain;
proto StreamSocketProtocol;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_NODELAY`.
strict SetTcpNoDelay(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_NODELAY`.
strict GetTcpNoDelay() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_MAXSEG`.
strict SetTcpMaxSegment(struct {
value_bytes uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_MAXSEG`.
strict GetTcpMaxSegment() -> (struct {
value_bytes uint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_CORK`.
strict SetTcpCork(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_CORK`.
strict GetTcpCork() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_KEEPIDLE`.
strict SetTcpKeepAliveIdle(struct {
value_secs uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_KEEPIDLE`.
strict GetTcpKeepAliveIdle() -> (struct {
value_secs uint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_KEEPINTVL`.
strict SetTcpKeepAliveInterval(struct {
value_secs uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_KEEPINTVL`.
strict GetTcpKeepAliveInterval() -> (struct {
value_secs uint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_KEEPCNT`.
strict SetTcpKeepAliveCount(struct {
value uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_KEEPCNT`.
strict GetTcpKeepAliveCount() -> (struct {
value uint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_SYNCNT`.
strict SetTcpSynCount(struct {
value uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_SYNCNT`.
strict GetTcpSynCount() -> (struct {
value uint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_LINGER2`.
strict SetTcpLinger(struct {
value_secs OptionalUint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_LINGER2`.
strict GetTcpLinger() -> (struct {
value_secs OptionalUint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_DEFER_ACCEPT`.
strict SetTcpDeferAccept(struct {
value_secs uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_DEFER_ACCEPT`.
strict GetTcpDeferAccept() -> (struct {
value_secs uint32;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_WINDOW_CLAMP`.
strict SetTcpWindowClamp(struct {
value uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_WINDOW_CLAMP`.
strict GetTcpWindowClamp() -> (struct {
value uint32;
}) error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_INFO`.
strict GetTcpInfo() -> (struct {
info TcpInfo;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_QUICKACK`.
strict SetTcpQuickAck(struct {
value bool;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_QUICKACK`.
strict GetTcpQuickAck() -> (struct {
value bool;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_CONGESTION`.
strict SetTcpCongestion(struct {
value TcpCongestionControl;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_CONGESTION`.
strict GetTcpCongestion() -> (struct {
value TcpCongestionControl;
}) error fuchsia.posix.Errno;
/// Set `SOL_TCP` -> `TCP_USER_TIMEOUT`.
strict SetTcpUserTimeout(struct {
value_millis uint32;
}) -> () error fuchsia.posix.Errno;
/// Get `SOL_TCP` -> `TCP_USER_TIMEOUT`.
strict GetTcpUserTimeout() -> (struct {
value_millis uint32;
}) error fuchsia.posix.Errno;
// NOTE: set `SOL_TCP` -> `TCP_REPAIR_OPTIONS` not supported in netstack.
// NOTE: get `SOL_CTP` -> `TCP_NOTSENT_LOWAT` not supported in netstack.
// NOTE: get `SOL_TCP` -> `TCP_CC_INFO` not supported in netstack.
};
/// TCP congestion control modes.
type TcpCongestionControl = strict enum {
RENO = 1;
CUBIC = 2;
};
/// TCP state machine state.
type TcpState = strict enum {
ESTABLISHED = 1;
SYN_SENT = 2;
SYN_RECV = 3;
FIN_WAIT1 = 4;
FIN_WAIT2 = 5;
TIME_WAIT = 6;
CLOSE = 7;
CLOSE_WAIT = 8;
LAST_ACK = 9;
LISTEN = 10;
CLOSING = 11;
};
/// TCP congestion control state machine state.
type TcpCongestionControlState = strict enum {
OPEN = 0;
DISORDER = 1;
CONGESTION_WINDOW_REDUCED = 2;
RECOVERY = 3;
LOSS = 4;
};
/// TCP protocol state.
type TcpInfo = table {
1: state TcpState;
2: ca_state TcpCongestionControlState;
// 3: tcpi_retransmits uint8;
// 4: tcpi_probes uint8;
// 5: tcpi_backoff uint8;
// 6: tcpi_options uint8;
// 7: ... // tcpi_snd_wscale : 4,
// 8: ... // tcpi_rcv_wscale : 4;
// 9: ... // tcpi_delivery_rate_app_limited : 1,
// 10: ... // tcpi_fastopen_client_fail : 2;
11: rto_usec uint32;
// 12: tcpi_ato uint32;
// 13: tcpi_snd_mss uint32;
// 14: tcpi_rcv_mss uint32;
// 15: tcpi_unacked uint32;
// 16: tcpi_sacked uint32;
// 17: tcpi_lost uint32;
// 18: tcpi_retrans uint32;
// 19: tcpi_fackets uint32;
// 20: tcpi_last_data_sent uint32;
// 21: tcpi_last_ack_sent uint32;
// 22: tcpi_last_data_recv uint32;
// 23: tcpi_last_ack_recv uint32;
// 24: tcpi_pmtu uint32;
// 25: tcpi_rcv_ssthresh uint32;
26: rtt_usec uint32;
27: rtt_var_usec uint32;
28: snd_ssthresh uint32;
29: snd_cwnd uint32;
// 30: tcpi_advmss uint32;
// 31: tcpi_reordering uint32;
// 32: tcpi_rcv_rtt uint32;
// 33: tcpi_rcv_space uint32;
// 34: tcpi_total_retrans uint32;
// 35: tcpi_pacing_rate uint64;
// 36: tcpi_max_pacing_rate uint64;
// 37: tcpi_bytes_acked uint64;
// 38: tcpi_bytes_received uint64;
// 39: tcpi_segs_out uint32;
// 40: tcpi_segs_in uint32;
// 41: tcpi_notsent_bytes uint32;
// 42: tcpi_min_rtt uint32;
// 43: tcpi_data_segs_in uint32;
// 44: tcpi_data_segs_out uint32;
// 45: tcpi_delivery_rate uint64;
// 46: tcpi_busy_time uint64;
// 47: tcpi_rwnd_limited uint64;
// 48: tcpi_sndbuf_limited uint64;
// 49: tcpi_delivered uint32;
// 50: tcpi_delivered_ce uint32;
// 51: tcpi_bytes_sent uint64;
// 52: tcpi_bytes_retrans uint64;
// 53: tcpi_dsack_dups uint32;
54: reorder_seen bool;
// 55: tcpi_rcv_ooopack uint32;
// 56: tcpi_snd_wnd uint32;
};
/// Holds information about an interface and its addresses.
type InterfaceAddresses = table {
/// ID of the interface.
1: id uint64;
/// Name of the interface.
2: name fuchsia.net.interfaces.Name;
/// All addresses currently assigned to the interface.
4: addresses vector<fuchsia.net.Subnet>:MAX;
/// Contains the interface flags, as returned by the SIOCGIFFLAGS ioctl
/// operation.
5: interface_flags InterfaceFlags;
};
/// A socket's domain.
///
/// Determines the addressing domain for a socket.
type Domain = strict enum : 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.
type DatagramSocketProtocol = strict enum {
/// 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.
type StreamSocketProtocol = strict enum {
/// 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.
type InterfaceFlags = strict bits : 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.
///
/// *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.
@discoverable
closed protocol Provider {
/// Requests a stream socket with the specified parameters.
strict StreamSocket(struct {
domain Domain;
proto StreamSocketProtocol;
}) -> (resource struct {
s client_end:StreamSocket;
}) error fuchsia.posix.Errno;
/// Requests a datagram socket with the specified parameters.
/// TODO(https://fxbug.dev/42165881): Remove this method once no more callers rely on it.
@selector("fuchsia.posix.socket/Provider.DatagramSocket")
strict DatagramSocketDeprecated(struct {
domain Domain;
proto DatagramSocketProtocol;
}) -> (resource struct {
s client_end:SynchronousDatagramSocket;
}) error fuchsia.posix.Errno;
/// Requests a datagram socket with the specified parameters.
@selector("fuchsia.posix.socket/Provider.DatagramSocketTransitional")
strict DatagramSocket(struct {
domain Domain;
proto DatagramSocketProtocol;
}) -> (strict resource union {
1: datagram_socket client_end:DatagramSocket;
2: synchronous_datagram_socket client_end:SynchronousDatagramSocket;
}) 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.
strict InterfaceIndexToName(struct {
index uint64;
}) -> (struct {
name fuchsia.net.interfaces.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.
strict InterfaceNameToIndex(struct {
name fuchsia.net.interfaces.Name;
}) -> (struct {
index uint64;
}) 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.
strict InterfaceNameToFlags(struct {
name fuchsia.net.interfaces.Name;
}) -> (struct {
flags InterfaceFlags;
}) error zx.Status;
/// Requests a list of [`fuchsia.posix.socket.InterfaceAddresses`]
/// describing the network interfaces on the system.
strict GetInterfaceAddresses() -> (struct {
interfaces vector<InterfaceAddresses>:MAX;
});
};