xref: /freebsd/crypto/openssl/crypto/bio/bio_sock2.c (revision e7be843b4a162e68651d3911f0357ed464915629)
1 /*
2  * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 
14 #include "bio_local.h"
15 #include "internal/ktls.h"
16 #include "internal/bio_tfo.h"
17 
18 #include <openssl/err.h>
19 
20 #ifndef OPENSSL_NO_SOCK
21 # ifdef SO_MAXCONN
22 #  define MAX_LISTEN  SO_MAXCONN
23 # elif defined(SOMAXCONN)
24 #  define MAX_LISTEN  SOMAXCONN
25 # else
26 #  define MAX_LISTEN  32
27 # endif
28 
29 /*-
30  * BIO_socket - create a socket
31  * @domain: the socket domain (AF_INET, AF_INET6, AF_UNIX, ...)
32  * @socktype: the socket type (SOCK_STEAM, SOCK_DGRAM)
33  * @protocol: the protocol to use (IPPROTO_TCP, IPPROTO_UDP)
34  * @options: BIO socket options (currently unused)
35  *
36  * Creates a socket.  This should be called before calling any
37  * of BIO_connect and BIO_listen.
38  *
39  * Returns the file descriptor on success or INVALID_SOCKET on failure.  On
40  * failure errno is set, and a status is added to the OpenSSL error stack.
41  */
BIO_socket(int domain,int socktype,int protocol,int options)42 int BIO_socket(int domain, int socktype, int protocol, int options)
43 {
44     int sock = -1;
45 
46     if (BIO_sock_init() != 1)
47         return INVALID_SOCKET;
48 
49     sock = socket(domain, socktype, protocol);
50     if (sock == -1) {
51         ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
52                        "calling socket()");
53         ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
54         return INVALID_SOCKET;
55     }
56 # ifndef OPENSSL_NO_KTLS
57     {
58         /*
59          * The new socket is created successfully regardless of ktls_enable.
60          * ktls_enable doesn't change any functionality of the socket, except
61          * changing the setsockopt to enable the processing of ktls_start.
62          * Thus, it is not a problem to call it for non-TLS sockets.
63          */
64         ktls_enable(sock);
65     }
66 # endif
67 
68     return sock;
69 }
70 
71 /*-
72  * BIO_connect - connect to an address
73  * @sock: the socket to connect with
74  * @addr: the address to connect to
75  * @options: BIO socket options
76  *
77  * Connects to the address using the given socket and options.
78  *
79  * Options can be a combination of the following:
80  * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
81  * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
82  * - BIO_SOCK_NODELAY: don't delay small messages.
83  * - BIO_SOCK_TFO: use TCP Fast Open
84  *
85  * options holds BIO socket options that can be used
86  * You should call this for every address returned by BIO_lookup
87  * until the connection is successful.
88  *
89  * Returns 1 on success or 0 on failure.  On failure errno is set
90  * and an error status is added to the OpenSSL error stack.
91  */
BIO_connect(int sock,const BIO_ADDR * addr,int options)92 int BIO_connect(int sock, const BIO_ADDR *addr, int options)
93 {
94     const int on = 1;
95 
96     if (sock == -1) {
97         ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET);
98         return 0;
99     }
100 
101     if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
102         return 0;
103 
104     if (options & BIO_SOCK_KEEPALIVE) {
105         if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
106                        (const void *)&on, sizeof(on)) != 0) {
107             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
108                            "calling setsockopt()");
109             ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE);
110             return 0;
111         }
112     }
113 
114     if (options & BIO_SOCK_NODELAY) {
115         if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
116                        (const void *)&on, sizeof(on)) != 0) {
117             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
118                            "calling setsockopt()");
119             ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY);
120             return 0;
121         }
122     }
123     if (options & BIO_SOCK_TFO) {
124 # if defined(OSSL_TFO_CLIENT_FLAG)
125 #  if defined(OSSL_TFO_SYSCTL_CLIENT)
126         int enabled = 0;
127         size_t enabledlen = sizeof(enabled);
128 
129         /* Later FreeBSD */
130         if (sysctlbyname(OSSL_TFO_SYSCTL_CLIENT, &enabled, &enabledlen, NULL, 0) < 0) {
131             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
132             return 0;
133         }
134         /* Need to check for client flag */
135         if (!(enabled & OSSL_TFO_CLIENT_FLAG)) {
136             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
137             return 0;
138         }
139 #  elif defined(OSSL_TFO_SYSCTL)
140         int enabled = 0;
141         size_t enabledlen = sizeof(enabled);
142 
143         /* macOS */
144         if (sysctlbyname(OSSL_TFO_SYSCTL, &enabled, &enabledlen, NULL, 0) < 0) {
145             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
146             return 0;
147         }
148         /* Need to check for client flag */
149         if (!(enabled & OSSL_TFO_CLIENT_FLAG)) {
150             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
151             return 0;
152         }
153 #  endif
154 # endif
155 # if defined(OSSL_TFO_CONNECTX)
156         sa_endpoints_t sae;
157 
158         memset(&sae, 0, sizeof(sae));
159         sae.sae_dstaddr = BIO_ADDR_sockaddr(addr);
160         sae.sae_dstaddrlen = BIO_ADDR_sockaddr_size(addr);
161         if (connectx(sock, &sae, SAE_ASSOCID_ANY,
162                      CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE,
163                      NULL, 0, NULL, NULL) == -1) {
164             if (!BIO_sock_should_retry(-1)) {
165                 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
166                                "calling connectx()");
167                 ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
168             }
169             return 0;
170         }
171 # endif
172 # if defined(OSSL_TFO_CLIENT_SOCKOPT)
173         if (setsockopt(sock, IPPROTO_TCP, OSSL_TFO_CLIENT_SOCKOPT,
174                        (const void *)&on, sizeof(on)) != 0) {
175             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
176                            "calling setsockopt()");
177             ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_TFO);
178             return 0;
179         }
180 # endif
181 # if defined(OSSL_TFO_DO_NOT_CONNECT)
182         return 1;
183 # endif
184     }
185 
186     if (connect(sock, BIO_ADDR_sockaddr(addr),
187                 BIO_ADDR_sockaddr_size(addr)) == -1) {
188         if (!BIO_sock_should_retry(-1)) {
189             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
190                            "calling connect()");
191             ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
192         }
193         return 0;
194     }
195 # ifndef OPENSSL_NO_KTLS
196     /*
197      * The new socket is created successfully regardless of ktls_enable.
198      * ktls_enable doesn't change any functionality of the socket, except
199      * changing the setsockopt to enable the processing of ktls_start.
200      * Thus, it is not a problem to call it for non-TLS sockets.
201      */
202     ktls_enable(sock);
203 # endif
204     return 1;
205 }
206 
207 /*-
208  * BIO_bind - bind socket to address
209  * @sock: the socket to set
210  * @addr: local address to bind to
211  * @options: BIO socket options
212  *
213  * Binds to the address using the given socket and options.
214  *
215  * Options can be a combination of the following:
216  * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
217  *   for a recently closed port.
218  *
219  * When restarting the program it could be that the port is still in use.  If
220  * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
221  * It's recommended that you use this.
222  */
BIO_bind(int sock,const BIO_ADDR * addr,int options)223 int BIO_bind(int sock, const BIO_ADDR *addr, int options)
224 {
225 # ifndef OPENSSL_SYS_WINDOWS
226     int on = 1;
227 # endif
228 
229     if (sock == -1) {
230         ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET);
231         return 0;
232     }
233 
234 # ifndef OPENSSL_SYS_WINDOWS
235     /*
236      * SO_REUSEADDR has different behavior on Windows than on
237      * other operating systems, don't set it there.
238      */
239     if (options & BIO_SOCK_REUSEADDR) {
240         if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
241                        (const void *)&on, sizeof(on)) != 0) {
242             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
243                            "calling setsockopt()");
244             ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_REUSEADDR);
245             return 0;
246         }
247     }
248 # endif
249 
250     if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
251         ERR_raise_data(ERR_LIB_SYS, get_last_socket_error() /* may be 0 */,
252                        "calling bind()");
253         ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_BIND_SOCKET);
254         return 0;
255     }
256 
257     return 1;
258 }
259 
260 /*-
261  * BIO_listen - Creates a listen socket
262  * @sock: the socket to listen with
263  * @addr: local address to bind to
264  * @options: BIO socket options
265  *
266  * Binds to the address using the given socket and options, then
267  * starts listening for incoming connections.
268  *
269  * Options can be a combination of the following:
270  * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
271  * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
272  * - BIO_SOCK_NODELAY: don't delay small messages.
273  * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
274  *   for a recently closed port.
275  * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
276  *   for IPv6 addresses and not IPv4 addresses mapped to IPv6.
277  * - BIO_SOCK_TFO: accept TCP fast open (set TCP_FASTOPEN)
278  *
279  * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
280  * then check both for new clients that connect to it.  You want to set up
281  * the socket as non-blocking in that case since else it could hang.
282  *
283  * Not all operating systems support IPv4 addresses on an IPv6 socket, and for
284  * others it's an option.  If you pass the BIO_LISTEN_V6_ONLY it will try to
285  * create the IPv6 sockets to only listen for IPv6 connection.
286  *
287  * It could be that the first BIO_listen() call will listen to all the IPv6
288  * and IPv4 addresses and that then trying to bind to the IPv4 address will
289  * fail.  We can't tell the difference between already listening ourself to
290  * it and someone else listening to it when failing and errno is EADDRINUSE, so
291  * it's recommended to not give an error in that case if the first call was
292  * successful.
293  *
294  * When restarting the program it could be that the port is still in use.  If
295  * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
296  * It's recommended that you use this.
297  */
BIO_listen(int sock,const BIO_ADDR * addr,int options)298 int BIO_listen(int sock, const BIO_ADDR *addr, int options)
299 {
300     int on = 1;
301     int socktype;
302     socklen_t socktype_len = sizeof(socktype);
303 
304     if (sock == -1) {
305         ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET);
306         return 0;
307     }
308 
309     if (getsockopt(sock, SOL_SOCKET, SO_TYPE,
310                    (void *)&socktype, &socktype_len) != 0
311         || socktype_len != sizeof(socktype)) {
312         ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
313                        "calling getsockopt()");
314         ERR_raise(ERR_LIB_BIO, BIO_R_GETTING_SOCKTYPE);
315         return 0;
316     }
317 
318     if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
319         return 0;
320 
321     if (options & BIO_SOCK_KEEPALIVE) {
322         if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
323                        (const void *)&on, sizeof(on)) != 0) {
324             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
325                            "calling setsockopt()");
326             ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE);
327             return 0;
328         }
329     }
330 
331     if (options & BIO_SOCK_NODELAY) {
332         if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
333                        (const void *)&on, sizeof(on)) != 0) {
334             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
335                            "calling setsockopt()");
336             ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY);
337             return 0;
338         }
339     }
340 
341   /* On OpenBSD it is always IPv6 only with IPv6 sockets thus read-only */
342 # if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
343     if (BIO_ADDR_family(addr) == AF_INET6) {
344         /*
345          * Note: Windows default of IPV6_V6ONLY is ON, and Linux is OFF.
346          * Therefore we always have to use setsockopt here.
347          */
348         on = options & BIO_SOCK_V6_ONLY ? 1 : 0;
349         if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
350                        (const void *)&on, sizeof(on)) != 0) {
351             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
352                            "calling setsockopt()");
353             ERR_raise(ERR_LIB_BIO, BIO_R_LISTEN_V6_ONLY);
354             return 0;
355         }
356     }
357 # endif
358 
359     if (!BIO_bind(sock, addr, options))
360         return 0;
361 
362     if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
363         ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
364                        "calling listen()");
365         ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_LISTEN_SOCKET);
366         return 0;
367     }
368 
369 # if defined(OSSL_TFO_SERVER_SOCKOPT)
370     /*
371      * Must do it explicitly after listen() for macOS, still
372      * works fine on other OS's
373      */
374     if ((options & BIO_SOCK_TFO) && socktype != SOCK_DGRAM) {
375         int q = OSSL_TFO_SERVER_SOCKOPT_VALUE;
376 #  if defined(OSSL_TFO_CLIENT_FLAG)
377 #   if defined(OSSL_TFO_SYSCTL_SERVER)
378         int enabled = 0;
379         size_t enabledlen = sizeof(enabled);
380 
381         /* Later FreeBSD */
382         if (sysctlbyname(OSSL_TFO_SYSCTL_SERVER, &enabled, &enabledlen, NULL, 0) < 0) {
383             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
384             return 0;
385         }
386         /* Need to check for server flag */
387         if (!(enabled & OSSL_TFO_SERVER_FLAG)) {
388             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
389             return 0;
390         }
391 #   elif defined(OSSL_TFO_SYSCTL)
392         int enabled = 0;
393         size_t enabledlen = sizeof(enabled);
394 
395         /* Early FreeBSD, macOS */
396         if (sysctlbyname(OSSL_TFO_SYSCTL, &enabled, &enabledlen, NULL, 0) < 0) {
397             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
398             return 0;
399         }
400         /* Need to check for server flag */
401         if (!(enabled & OSSL_TFO_SERVER_FLAG)) {
402             ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
403             return 0;
404         }
405 #   endif
406 #  endif
407         if (setsockopt(sock, IPPROTO_TCP, OSSL_TFO_SERVER_SOCKOPT,
408                        (void *)&q, sizeof(q)) < 0) {
409             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
410                            "calling setsockopt()");
411             ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_TFO);
412             return 0;
413         }
414     }
415 # endif
416 
417     return 1;
418 }
419 
420 /*-
421  * BIO_accept_ex - Accept new incoming connections
422  * @sock: the listening socket
423  * @addr: the BIO_ADDR to store the peer address in
424  * @options: BIO socket options, applied on the accepted socket.
425  *
426  */
BIO_accept_ex(int accept_sock,BIO_ADDR * addr_,int options)427 int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
428 {
429     socklen_t len;
430     int accepted_sock;
431     BIO_ADDR locaddr;
432     BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
433 
434     len = sizeof(*addr);
435     accepted_sock = accept(accept_sock,
436                            BIO_ADDR_sockaddr_noconst(addr), &len);
437     if (accepted_sock == -1) {
438         if (!BIO_sock_should_retry(accepted_sock)) {
439             ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
440                            "calling accept()");
441             ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR);
442         }
443         return INVALID_SOCKET;
444     }
445 
446     if (!BIO_socket_nbio(accepted_sock, (options & BIO_SOCK_NONBLOCK) != 0)) {
447         closesocket(accepted_sock);
448         return INVALID_SOCKET;
449     }
450 
451     return accepted_sock;
452 }
453 
454 /*-
455  * BIO_closesocket - Close a socket
456  * @sock: the socket to close
457  */
BIO_closesocket(int sock)458 int BIO_closesocket(int sock)
459 {
460     if (sock < 0 || closesocket(sock) < 0)
461         return 0;
462     return 1;
463 }
464 #endif
465