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