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 native POSIX names. 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 60See :zephyr:code-sample:`sockets-echo-server` and :zephyr:code-sample:`sockets-echo-client` 61sample applications to learn how to create a simple server or client BSD socket based 62application. 63 64.. _secure_sockets_interface: 65 66Secure Sockets 67************** 68 69Zephyr provides an extension of standard POSIX socket API, allowing to create 70and configure sockets with TLS protocol types, facilitating secure 71communication. Secure functions for the implementation are provided by 72mbedTLS library. Secure sockets implementation allows use of both TLS and DTLS 73protocols with standard socket calls. See :c:enum:`net_ip_protocol_secure` type 74for supported secure protocol versions. 75 76To enable secure sockets, set the :kconfig:option:`CONFIG_NET_SOCKETS_SOCKOPT_TLS` 77option. To enable DTLS support, use :kconfig:option:`CONFIG_NET_SOCKETS_ENABLE_DTLS` 78option. 79 80.. _sockets_tls_credentials_subsys: 81 82TLS credentials subsystem 83========================= 84 85TLS credentials must be registered in the system before they can be used with 86secure sockets. See :c:func:`tls_credential_add` for more information. 87 88When a specific TLS credential is registered in the system, it is assigned with 89numeric value of type :c:type:`sec_tag_t`, called a tag. This value can be used 90later on to reference the credential during secure socket configuration with 91socket options. 92 93The following TLS credential types can be registered in the system: 94 95- ``TLS_CREDENTIAL_CA_CERTIFICATE`` 96- ``TLS_CREDENTIAL_SERVER_CERTIFICATE`` 97- ``TLS_CREDENTIAL_PRIVATE_KEY`` 98- ``TLS_CREDENTIAL_PSK`` 99- ``TLS_CREDENTIAL_PSK_ID`` 100 101An example registration of CA certificate (provided in ``ca_certificate`` 102array) looks like this: 103 104.. code-block:: c 105 106 ret = tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, 107 ca_certificate, sizeof(ca_certificate)); 108 109By default certificates in DER format are supported. PEM support can be enabled 110in mbedTLS settings. 111 112Secure Socket Creation 113====================== 114 115A secure socket can be created by specifying secure protocol type, for instance: 116 117.. code-block:: c 118 119 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); 120 121Once created, it can be configured with socket options. For instance, the 122CA certificate and hostname can be set: 123 124.. code-block:: c 125 126 sec_tag_t sec_tag_opt[] = { 127 CA_CERTIFICATE_TAG, 128 }; 129 130 ret = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, 131 sec_tag_opt, sizeof(sec_tag_opt)); 132 133.. code-block:: c 134 135 char host[] = "google.com"; 136 137 ret = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, host, sizeof(host)); 138 139Once configured, socket can be used just like a regular TCP socket. 140 141Several samples in Zephyr use secure sockets for communication. For a sample use 142see e.g. :zephyr:code-sample:`echo-server sample application <sockets-echo-server>` or 143:zephyr:code-sample:`HTTP GET sample application <sockets-http-get>`. 144 145Secure Sockets options 146====================== 147 148Secure sockets offer the following options for socket management: 149 150.. doxygengroup:: secure_sockets_options 151 152Socket offloading 153***************** 154 155Zephyr allows to register custom socket implementations (called offloaded 156sockets). This allows for seamless integration for devices which provide an 157external IP stack and expose socket-like API. 158 159Socket offloading can be enabled with :kconfig:option:`CONFIG_NET_SOCKETS_OFFLOAD` 160option. A network driver that wants to register a new socket implementation 161should use :c:macro:`NET_SOCKET_OFFLOAD_REGISTER` macro. The macro accepts the 162following parameters: 163 164 * ``socket_name`` 165 An arbitrary name for the socket implementation. 166 167 * ``prio`` 168 Socket implementation's priority. The higher the priority, the earlier this 169 particular implementation will be processed when creating a new socket. 170 Lower numeric value indicates higher priority. 171 172 * ``_family`` 173 Socket family implemented by the offloaded socket. ``AF_UNSPEC`` indicates 174 any family. 175 176 * ``_is_supported`` 177 A filtering function, used to verify whether a particular socket family, 178 type and protocol are supported by the offloaded socket implementation. 179 180 * ``_handler`` 181 A function compatible with :c:func:`socket` API, used to create an 182 offloaded socket. 183 184Every offloaded socket implementation should also implement a set of socket 185APIs, specified in :c:struct:`socket_op_vtable` struct. 186 187The function registered for socket creation should allocate a new file 188descriptor using :c:func:`zvfs_reserve_fd` function. Any additional actions, 189specific to the creation of a particular offloaded socket implementation, 190should take place after the file descriptor is allocated. As a final step, 191if the offloaded socket was created successfully, the file descriptor should 192be finalized with :c:func:`zvfs_finalize_typed_fd`, or :c:func:`zvfs_finalize_fd` 193functions. The finalize function allows to register a 194:c:struct:`socket_op_vtable` structure implementing socket APIs for an 195offloaded socket along with an optional socket context data pointer. 196 197Finally, when an offloaded network interface is initialized, it should indicate 198that the interface is offloaded with :c:func:`net_if_socket_offload_set` 199function. The function registers the function used to create an offloaded socket 200(the same as the one provided in :c:macro:`NET_SOCKET_OFFLOAD_REGISTER`) at the 201network interface. 202 203Offloaded socket creation 204========================= 205 206When application creates a new socket with :c:func:`socket` function, the 207network stack iterates over all registered socket implementations (native and 208offloaded). Higher priority socket implementations are processed first. 209For each registered socket implementation, an address family is verified, and if 210it matches (or the socket was registered as ``AF_UNSPEC``), the corresponding 211``_is_supported`` function is called to verify the remaining socket parameters. 212The first implementation that fulfills the socket requirements (i. e. 213``_is_supported`` returns true) will create a new socket with its ``_handler`` 214function. 215 216The above indicates the importance of the socket priority. If multiple socket 217implementations support the same set of socket family/type/protocol, the first 218implementation processed by the system will create a socket. Therefore it's 219important to give the highest priority to the implementation that should be the 220system default. 221 222The socket priority for native socket implementation is configured with Kconfig. 223Use :kconfig:option:`CONFIG_NET_SOCKETS_TLS_PRIORITY` to set the priority for 224the native TLS sockets. 225Use :kconfig:option:`CONFIG_NET_SOCKETS_PRIORITY_DEFAULT` to set the priority 226for the remaining native sockets. 227 228Dealing with multiple offloaded interfaces 229========================================== 230 231As the :c:func:`socket` function does not allow to specify which network 232interface should be used by a socket, it's not possible to choose a specific 233implementation in case multiple offloaded socket implementations, supporting the 234same type of sockets, are available. The same problem arises when both native 235and offloaded sockets are available in the system. 236 237To address this problem, a special socket implementation (called socket 238dispatcher) was introduced. The sole reason for this module is to postpone the 239socket creation for until the first operation on a socket is performed. This 240leaves an opening to use ``SO_BINDTODEVICE`` socket option, to bind a socket to 241a particular network interface (and thus offloaded socket implementation). 242The socket dispatcher can be enabled with :kconfig:option:`CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER` 243Kconfig option. 244 245When enabled, the application can specify the network interface to use with 246:c:func:`setsockopt` function: 247 248.. code-block:: c 249 250 /* A "dispatcher" socket is created */ 251 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 252 253 struct ifreq ifreq = { 254 .ifr_name = "SimpleLink" 255 }; 256 257 /* The socket is "dispatched" to a particular network interface 258 * (offloaded or not). 259 */ 260 setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof(ifreq)); 261 262Similarly, if TLS is supported by both native and offloaded sockets, 263``TLS_NATIVE`` socket option can be used to indicate that a native TLS socket 264should be created. The underlying socket can then be bound to a particular 265network interface: 266 267.. code-block:: c 268 269 /* A "dispatcher" socket is created */ 270 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); 271 272 int tls_native = 1; 273 274 /* The socket is "dispatched" to a native TLS socket implmeentation. 275 * The underlying socket is a "dispatcher" socket now. 276 */ 277 setsockopt(sock, SOL_TLS, TLS_NATIVE, &tls_native, sizeof(tls_native)); 278 279 struct ifreq ifreq = { 280 .ifr_name = "SimpleLink" 281 }; 282 283 /* The underlying socket is "dispatched" to a particular network interface 284 * (offloaded or not). 285 */ 286 setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof(ifreq)); 287 288In case no ``SO_BINDTODEVICE`` socket option is used on a socket, the socket 289will be dispatched according to the default priority and filtering rules on a 290first socket API call. 291 292API Reference 293************* 294 295BSD Sockets 296=========== 297 298.. doxygengroup:: bsd_sockets 299 300TLS Credentials 301=============== 302 303.. doxygengroup:: tls_credentials 304