1.. _bsd_sockets_interface: 2 3BSD Sockets 4########### 5 6.. contents:: 7 :local: 8 :depth: 2 9 10Overview 11******** 12 13Zephyr offers an implementation of a subset of the BSD Sockets API (a part 14of the POSIX standard). This API allows to reuse existing programming experience 15and port existing simple networking applications to Zephyr. 16 17Here are the key requirements and concepts which governed BSD Sockets 18compatible API implementation for Zephyr: 19 20* Has minimal overhead, similar to the requirement for other 21 Zephyr subsystems. 22* Is namespaced by default, to avoid name conflicts with well-known 23 names like ``close()``, which may be part of libc or other POSIX 24 compatibility libraries. 25 If enabled by :kconfig:option:`CONFIG_POSIX_API`, it will also 26 expose POSIX compatible APIs. 27 28BSD Sockets compatible API is enabled using :kconfig:option:`CONFIG_NET_SOCKETS` 29config option and implements the following operations: ``socket()``, ``close()``, 30``recv()``, ``recvfrom()``, ``send()``, ``sendto()``, ``connect()``, ``bind()``, 31``listen()``, ``accept()``, ``fcntl()`` (to set non-blocking mode), 32``getsockopt()``, ``setsockopt()``, ``poll()``, ``select()``, 33``getaddrinfo()``, ``getnameinfo()``. 34 35Based on the namespacing requirements above, these operations are by 36default exposed as functions with ``zsock_`` prefix, e.g. 37:c:func:`zsock_socket` and :c:func:`zsock_close`. If the config option 38:kconfig:option:`CONFIG_POSIX_API` is defined, all the functions 39will be also exposed as aliases without the prefix. This includes the 40functions like ``close()`` and ``fcntl()`` (which may conflict with 41functions in libc or other libraries, for example, with the filesystem 42libraries). 43 44Another entailment of the design requirements above is that the Zephyr 45API aggressively employs the short-read/short-write property of the POSIX API 46whenever possible (to minimize complexity and overheads). POSIX allows 47for calls like ``recv()`` and ``send()`` to actually process (receive 48or send) less data than requested by the user (on ``SOCK_STREAM`` type 49sockets). For example, a call ``recv(sock, 1000, 0)`` may return 100, 50meaning that only 100 bytes were read (short read), and the application 51needs to retry call(s) to receive the remaining 900 bytes. 52 53The BSD Sockets API uses file descriptors to represent sockets. File 54descriptors are small integers, consecutively assigned from zero, shared 55among sockets, files, special devices (like stdin/stdout), etc. Internally, 56there is a table mapping file descriptors to internal object pointers. 57The file descriptor table is used by the BSD Sockets API even if the rest 58of the POSIX subsystem (filesystem, stdin/stdout) is not enabled. 59 60Zephyr supports multiple types of BSD sockets, the following table summarizes 61what socket types are available: 62 63+--------------+-------------+------------------+---------------------------------------------------------------------------+ 64| Family | Type | Protocol | Description | 65+==============+=============+==================+===========================================================================+ 66| AF_INET |br| | SOCK_DGRAM | IPPROTO_UDP | Enabled if :kconfig:option:`CONFIG_NET_UDP` is set. |br| | 67| AF_INET6 | | | Allows to send and receive UDP datagrams. | 68| | +------------------+---------------------------------------------------------------------------+ 69| | | IPPROTO_DTLS_1_x | Enabled if :kconfig:option:`CONFIG_NET_SOCKETS_ENABLE_DTLS` is set. |br| | 70| | | | Allows to send and receive DTLS datagrams. | 71| +-------------+------------------+---------------------------------------------------------------------------+ 72| | SOCK_STREAM | IPPROTO_TCP | Enabled if :kconfig:option:`CONFIG_NET_TCP` is set. |br| | 73| | | | Allows to send and receive TCP data stream. | 74| | +------------------+---------------------------------------------------------------------------+ 75| | | IPPROTO_TLS_1_x | Enabled if :kconfig:option:`CONFIG_NET_SOCKETS_SOCKOPT_TLS` is set. |br| | 76| | | | Allows to send and receive TLS data stream. | 77| +-------------+------------------+---------------------------------------------------------------------------+ 78| | SOCK_RAW | IPPROTO_IP |br| | Enabled if :kconfig:option:`CONFIG_NET_SOCKETS_INET_RAW` is set. |br| | 79| | | <proto> | Allows to send and receive IPv4/IPv6 datagrams. |br| | 80| | | | Packets are filtered by L4 protocol specified. | 81| | | | IPPROTO_IP is a wildcard protocol to receive all IP datagrams. | 82+--------------+-------------+------------------+---------------------------------------------------------------------------+ 83| AF_PACKET | SOCK_DGRAM | ETH_P_ALL |br| | Enabled if :kconfig:option:`CONFIG_NET_SOCKETS_PACKET_DGRAM` is set. |br| | 84| | | <proto> | Allows to send and receive packets without L2 header. |br| | 85| | | | Packets are filtered by L3 protocol specified. | 86| | | | ETH_P_ALL is a wildcard protocol to receive all packets. | 87| +-------------+------------------+---------------------------------------------------------------------------+ 88| | SOCK_RAW | ETH_P_ALL | Enabled if :kconfig:option:`CONFIG_NET_SOCKETS_PACKET` is set. |br| | 89| | | | Allows to send and receive packets with L2 header included. | 90+--------------+-------------+------------------+---------------------------------------------------------------------------+ 91| AF_CAN | SOCK_RAW | CAN_RAW | Enabled if :kconfig:option:`CONFIG_NET_SOCKETS_CAN` is set. |br| | 92| | | | Allows to send and receive CAN packets. | 93+--------------+-------------+------------------+---------------------------------------------------------------------------+ 94 95See :zephyr:code-sample:`sockets-echo-server` and :zephyr:code-sample:`sockets-echo-client` 96sample applications to learn how to create a simple server or client BSD socket based 97application. 98 99.. _secure_sockets_interface: 100 101Secure Sockets 102************** 103 104Zephyr provides an extension of standard POSIX socket API, allowing to create 105and configure sockets with TLS protocol types, facilitating secure 106communication. Secure functions for the implementation are provided by 107mbedTLS library. Secure sockets implementation allows use of both TLS and DTLS 108protocols with standard socket calls. See :c:enum:`net_ip_protocol_secure` type 109for supported secure protocol versions. 110 111To enable secure sockets, set the :kconfig:option:`CONFIG_NET_SOCKETS_SOCKOPT_TLS` 112option. To enable DTLS support, use :kconfig:option:`CONFIG_NET_SOCKETS_ENABLE_DTLS` 113option. 114 115.. _sockets_tls_credentials_subsys: 116 117TLS credentials subsystem 118========================= 119 120TLS credentials must be registered in the system before they can be used with 121secure sockets. See :c:func:`tls_credential_add` for more information. 122 123When a specific TLS credential is registered in the system, it is assigned with 124numeric value of type :c:type:`sec_tag_t`, called a tag. This value can be used 125later on to reference the credential during secure socket configuration with 126socket options. 127 128The following TLS credential types can be registered in the system: 129 130- ``TLS_CREDENTIAL_CA_CERTIFICATE`` 131- ``TLS_CREDENTIAL_PUBLIC_CERTIFICATE`` 132- ``TLS_CREDENTIAL_PRIVATE_KEY`` 133- ``TLS_CREDENTIAL_PSK`` 134- ``TLS_CREDENTIAL_PSK_ID`` 135 136An example registration of CA certificate (provided in ``ca_certificate`` 137array) looks like this: 138 139.. code-block:: c 140 141 ret = tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, 142 ca_certificate, sizeof(ca_certificate)); 143 144By default certificates in DER format are supported. PEM support can be enabled 145in mbedTLS settings. 146 147Secure Socket Creation 148====================== 149 150A secure socket can be created by specifying secure protocol type, for instance: 151 152.. code-block:: c 153 154 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); 155 156Once created, it can be configured with socket options. For instance, the 157CA certificate and hostname can be set: 158 159.. code-block:: c 160 161 sec_tag_t sec_tag_opt[] = { 162 CA_CERTIFICATE_TAG, 163 }; 164 165 ret = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, 166 sec_tag_opt, sizeof(sec_tag_opt)); 167 168.. code-block:: c 169 170 char host[] = "google.com"; 171 172 ret = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, host, sizeof(host)); 173 174Once configured, socket can be used just like a regular TCP socket. 175 176Several samples in Zephyr use secure sockets for communication. For a sample use 177see e.g. :zephyr:code-sample:`echo-server sample application <sockets-echo-server>` or 178:zephyr:code-sample:`HTTP GET sample application <sockets-http-get>`. 179 180Secure Sockets options 181====================== 182 183Secure sockets offer the following options for socket management: 184 185.. doxygengroup:: secure_sockets_options 186 187Socket offloading 188***************** 189 190Zephyr allows to register custom socket implementations (called offloaded 191sockets). This allows for seamless integration for devices which provide an 192external IP stack and expose socket-like API. 193 194Socket offloading can be enabled with :kconfig:option:`CONFIG_NET_SOCKETS_OFFLOAD` 195option. A network driver that wants to register a new socket implementation 196should use :c:macro:`NET_SOCKET_OFFLOAD_REGISTER` macro. The macro accepts the 197following parameters: 198 199 * ``socket_name`` 200 An arbitrary name for the socket implementation. 201 202 * ``prio`` 203 Socket implementation's priority. The higher the priority, the earlier this 204 particular implementation will be processed when creating a new socket. 205 Lower numeric value indicates higher priority. 206 207 * ``_family`` 208 Socket family implemented by the offloaded socket. ``AF_UNSPEC`` indicates 209 any family. 210 211 * ``_is_supported`` 212 A filtering function, used to verify whether a particular socket family, 213 type and protocol are supported by the offloaded socket implementation. 214 215 * ``_handler`` 216 A function compatible with :c:func:`socket` API, used to create an 217 offloaded socket. 218 219Every offloaded socket implementation should also implement a set of socket 220APIs, specified in :c:struct:`socket_op_vtable` struct. 221 222The function registered for socket creation should allocate a new file 223descriptor using :c:func:`zvfs_reserve_fd` function. Any additional actions, 224specific to the creation of a particular offloaded socket implementation, 225should take place after the file descriptor is allocated. As a final step, 226if the offloaded socket was created successfully, the file descriptor should 227be finalized with :c:func:`zvfs_finalize_typed_fd`, or :c:func:`zvfs_finalize_fd` 228functions. The finalize function allows to register a 229:c:struct:`socket_op_vtable` structure implementing socket APIs for an 230offloaded socket along with an optional socket context data pointer. 231 232Finally, when an offloaded network interface is initialized, it should indicate 233that the interface is offloaded with :c:func:`net_if_socket_offload_set` 234function. The function registers the function used to create an offloaded socket 235(the same as the one provided in :c:macro:`NET_SOCKET_OFFLOAD_REGISTER`) at the 236network interface. 237 238Offloaded socket creation 239========================= 240 241When application creates a new socket with :c:func:`socket` function, the 242network stack iterates over all registered socket implementations (native and 243offloaded). Higher priority socket implementations are processed first. 244For each registered socket implementation, an address family is verified, and if 245it matches (or the socket was registered as ``AF_UNSPEC``), the corresponding 246``_is_supported`` function is called to verify the remaining socket parameters. 247The first implementation that fulfills the socket requirements (i. e. 248``_is_supported`` returns true) will create a new socket with its ``_handler`` 249function. 250 251The above indicates the importance of the socket priority. If multiple socket 252implementations support the same set of socket family/type/protocol, the first 253implementation processed by the system will create a socket. Therefore it's 254important to give the highest priority to the implementation that should be the 255system default. 256 257The socket priority for native socket implementation is configured with Kconfig. 258Use :kconfig:option:`CONFIG_NET_SOCKETS_TLS_PRIORITY` to set the priority for 259the native TLS sockets. 260Use :kconfig:option:`CONFIG_NET_SOCKETS_PRIORITY_DEFAULT` to set the priority 261for the remaining native sockets. 262 263Dealing with multiple offloaded interfaces 264========================================== 265 266As the :c:func:`socket` function does not allow to specify which network 267interface should be used by a socket, it's not possible to choose a specific 268implementation in case multiple offloaded socket implementations, supporting the 269same type of sockets, are available. The same problem arises when both native 270and offloaded sockets are available in the system. 271 272To address this problem, a special socket implementation (called socket 273dispatcher) was introduced. The sole reason for this module is to postpone the 274socket creation for until the first operation on a socket is performed. This 275leaves an opening to use ``SO_BINDTODEVICE`` socket option, to bind a socket to 276a particular network interface (and thus offloaded socket implementation). 277The socket dispatcher can be enabled with :kconfig:option:`CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER` 278Kconfig option. 279 280When enabled, the application can specify the network interface to use with 281:c:func:`setsockopt` function: 282 283.. code-block:: c 284 285 /* A "dispatcher" socket is created */ 286 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 287 288 struct ifreq ifreq = { 289 .ifr_name = "SimpleLink" 290 }; 291 292 /* The socket is "dispatched" to a particular network interface 293 * (offloaded or not). 294 */ 295 setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof(ifreq)); 296 297Similarly, if TLS is supported by both native and offloaded sockets, 298``TLS_NATIVE`` socket option can be used to indicate that a native TLS socket 299should be created. The underlying socket can then be bound to a particular 300network interface: 301 302.. code-block:: c 303 304 /* A "dispatcher" socket is created */ 305 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); 306 307 int tls_native = 1; 308 309 /* The socket is "dispatched" to a native TLS socket implmeentation. 310 * The underlying socket is a "dispatcher" socket now. 311 */ 312 setsockopt(sock, SOL_TLS, TLS_NATIVE, &tls_native, sizeof(tls_native)); 313 314 struct ifreq ifreq = { 315 .ifr_name = "SimpleLink" 316 }; 317 318 /* The underlying socket is "dispatched" to a particular network interface 319 * (offloaded or not). 320 */ 321 setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof(ifreq)); 322 323In case no ``SO_BINDTODEVICE`` socket option is used on a socket, the socket 324will be dispatched according to the default priority and filtering rules on a 325first socket API call. 326 327API Reference 328************* 329 330BSD Sockets 331=========== 332 333.. doxygengroup:: bsd_sockets 334 335TLS Credentials 336=============== 337 338.. doxygengroup:: tls_credentials 339