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