1 /*
2 * Copyright 1995-2025 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 "bio_local.h"
13
14 #ifndef OPENSSL_NO_SOCK
15 #define SOCKET_PROTOCOL IPPROTO_TCP
16 #ifdef SO_MAXCONN
17 #define MAX_LISTEN SO_MAXCONN
18 #elif defined(SOMAXCONN)
19 #define MAX_LISTEN SOMAXCONN
20 #else
21 #define MAX_LISTEN 32
22 #endif
23 #if defined(OPENSSL_SYS_WINDOWS)
24 static int wsa_init_done = 0;
25 #endif
26
27 #if defined __TANDEM
28 #include <unistd.h>
29 #include <sys/time.h> /* select */
30 #elif defined _WIN32
31 #include <winsock.h> /* for type fd_set */
32 #else
33 #include <unistd.h>
34 #if defined __VMS
35 #include <sys/socket.h>
36 #elif defined _HPUX_SOURCE
37 #include <sys/time.h>
38 #else
39 #include <sys/select.h>
40 #endif
41 #endif
42 #include "internal/sockets.h" /* for openssl_fdset() */
43
44 #ifndef OPENSSL_NO_DEPRECATED_1_1_0
BIO_get_host_ip(const char * str,unsigned char * ip)45 int BIO_get_host_ip(const char *str, unsigned char *ip)
46 {
47 BIO_ADDRINFO *res = NULL;
48 int ret = 0;
49
50 if (BIO_sock_init() != 1)
51 return 0; /* don't generate another error code here */
52
53 if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
54 size_t l;
55
56 if (BIO_ADDRINFO_family(res) != AF_INET) {
57 ERR_raise(ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
58 } else if (BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l)) {
59 /*
60 * Because only AF_INET addresses will reach this far, we can assert
61 * that l should be 4
62 */
63 if (ossl_assert(l == 4))
64 ret = BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l);
65 }
66 BIO_ADDRINFO_free(res);
67 } else {
68 ERR_add_error_data(2, "host=", str);
69 }
70
71 return ret;
72 }
73
BIO_get_port(const char * str,unsigned short * port_ptr)74 int BIO_get_port(const char *str, unsigned short *port_ptr)
75 {
76 BIO_ADDRINFO *res = NULL;
77 int ret = 0;
78
79 if (str == NULL) {
80 ERR_raise(ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED);
81 return 0;
82 }
83
84 if (BIO_sock_init() != 1)
85 return 0; /* don't generate another error code here */
86
87 if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
88 if (BIO_ADDRINFO_family(res) != AF_INET) {
89 ERR_raise(ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
90 } else {
91 *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
92 ret = 1;
93 }
94 BIO_ADDRINFO_free(res);
95 } else {
96 ERR_add_error_data(2, "host=", str);
97 }
98
99 return ret;
100 }
101 #endif
102
BIO_sock_error(int sock)103 int BIO_sock_error(int sock)
104 {
105 int j = 0, i;
106 socklen_t size = sizeof(j);
107
108 /*
109 * Note: under Windows the third parameter is of type (char *) whereas
110 * under other systems it is (void *) if you don't have a cast it will
111 * choke the compiler: if you do have a cast then you can either go for
112 * (char *) or (void *).
113 */
114 i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size);
115 if (i < 0)
116 return get_last_socket_error();
117 else
118 return j;
119 }
120
121 #ifndef OPENSSL_NO_DEPRECATED_1_1_0
BIO_gethostbyname(const char * name)122 struct hostent *BIO_gethostbyname(const char *name)
123 {
124 /*
125 * Caching gethostbyname() results forever is wrong, so we have to let
126 * the true gethostbyname() worry about this
127 */
128 return gethostbyname(name);
129 }
130 #endif
131
132 #ifdef BIO_HAVE_WSAMSG
133 LPFN_WSARECVMSG bio_WSARecvMsg;
134 LPFN_WSASENDMSG bio_WSASendMsg;
135 #endif
136
BIO_sock_init(void)137 int BIO_sock_init(void)
138 {
139 #ifdef OPENSSL_SYS_WINDOWS
140 static struct WSAData wsa_state;
141
142 if (!wsa_init_done) {
143 wsa_init_done = 1;
144 memset(&wsa_state, 0, sizeof(wsa_state));
145 /*
146 * Not making wsa_state available to the rest of the code is formally
147 * wrong. But the structures we use are [believed to be] invariable
148 * among Winsock DLLs, while API availability is [expected to be]
149 * probed at run-time with DSO_global_lookup.
150 */
151 if (WSAStartup(0x0202, &wsa_state) != 0) {
152 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
153 "calling wsastartup()");
154 ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP);
155 return -1;
156 }
157
158 /*
159 * On Windows, some socket functions are not exposed as a prototype.
160 * Instead, their function pointers must be loaded via this elaborate
161 * process...
162 */
163 #ifdef BIO_HAVE_WSAMSG
164 {
165 GUID id_WSARecvMsg = WSAID_WSARECVMSG;
166 GUID id_WSASendMsg = WSAID_WSASENDMSG;
167 DWORD len_out = 0;
168 SOCKET s;
169
170 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
171 if (s != INVALID_SOCKET) {
172 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
173 &id_WSARecvMsg, sizeof(id_WSARecvMsg),
174 &bio_WSARecvMsg, sizeof(bio_WSARecvMsg),
175 &len_out, NULL, NULL)
176 != 0
177 || len_out != sizeof(bio_WSARecvMsg))
178 bio_WSARecvMsg = NULL;
179
180 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
181 &id_WSASendMsg, sizeof(id_WSASendMsg),
182 &bio_WSASendMsg, sizeof(bio_WSASendMsg),
183 &len_out, NULL, NULL)
184 != 0
185 || len_out != sizeof(bio_WSASendMsg))
186 bio_WSASendMsg = NULL;
187
188 closesocket(s);
189 }
190 }
191 #endif
192 }
193 #endif /* OPENSSL_SYS_WINDOWS */
194 #ifdef WATT32
195 extern int _watt_do_exit;
196 _watt_do_exit = 0; /* don't make sock_init() call exit() */
197 if (sock_init())
198 return -1;
199 #endif
200
201 return 1;
202 }
203
bio_sock_cleanup_int(void)204 void bio_sock_cleanup_int(void)
205 {
206 #ifdef OPENSSL_SYS_WINDOWS
207 if (wsa_init_done) {
208 wsa_init_done = 0;
209 WSACleanup();
210 }
211 #endif
212 }
213
BIO_socket_ioctl(int fd,long type,void * arg)214 int BIO_socket_ioctl(int fd, long type, void *arg)
215 {
216 int i;
217
218 #ifdef __DJGPP__
219 i = ioctlsocket(fd, type, (char *)arg);
220 #else
221 #if defined(OPENSSL_SYS_VMS)
222 /*-
223 * 2011-02-18 SMS.
224 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
225 * observe that all the consumers pass in an "unsigned long *",
226 * so we arrange a local copy with a short pointer, and use
227 * that, instead.
228 */
229 #if __INITIAL_POINTER_SIZE == 64
230 #define ARG arg_32p
231 #pragma pointer_size save
232 #pragma pointer_size 32
233 unsigned long arg_32;
234 unsigned long *arg_32p;
235 #pragma pointer_size restore
236 arg_32p = &arg_32;
237 arg_32 = *((unsigned long *)arg);
238 #else /* __INITIAL_POINTER_SIZE == 64 */
239 #define ARG arg
240 #endif /* __INITIAL_POINTER_SIZE == 64 [else] */
241 #else /* defined(OPENSSL_SYS_VMS) */
242 #define ARG arg
243 #endif /* defined(OPENSSL_SYS_VMS) [else] */
244
245 i = ioctlsocket(fd, type, ARG);
246 #endif /* __DJGPP__ */
247 if (i < 0)
248 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
249 "calling ioctlsocket()");
250 return i;
251 }
252
253 #ifndef OPENSSL_NO_DEPRECATED_1_1_0
BIO_get_accept_socket(char * host,int bind_mode)254 int BIO_get_accept_socket(char *host, int bind_mode)
255 {
256 int s = INVALID_SOCKET;
257 char *h = NULL, *p = NULL;
258 BIO_ADDRINFO *res = NULL;
259
260 if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV))
261 return INVALID_SOCKET;
262
263 if (BIO_sock_init() != 1)
264 goto err;
265
266 if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) == 0)
267 goto err;
268
269 if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
270 BIO_ADDRINFO_protocol(res), 0))
271 == INVALID_SOCKET) {
272 s = INVALID_SOCKET;
273 goto err;
274 }
275
276 if (!BIO_listen(s, BIO_ADDRINFO_address(res),
277 bind_mode ? BIO_SOCK_REUSEADDR : 0)) {
278 BIO_closesocket(s);
279 s = INVALID_SOCKET;
280 }
281
282 err:
283 BIO_ADDRINFO_free(res);
284 OPENSSL_free(h);
285 OPENSSL_free(p);
286
287 return s;
288 }
289
BIO_accept(int sock,char ** ip_port)290 int BIO_accept(int sock, char **ip_port)
291 {
292 BIO_ADDR res;
293 int ret = -1;
294
295 ret = BIO_accept_ex(sock, &res, 0);
296 if (ret == (int)INVALID_SOCKET) {
297 if (BIO_sock_should_retry(ret)) {
298 ret = -2;
299 goto end;
300 }
301 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
302 "calling accept()");
303 ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR);
304 goto end;
305 }
306
307 if (ip_port != NULL) {
308 char *host = BIO_ADDR_hostname_string(&res, 1);
309 char *port = BIO_ADDR_service_string(&res, 1);
310 if (host != NULL && port != NULL) {
311 *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
312 } else {
313 *ip_port = NULL;
314 ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
315 }
316
317 if (*ip_port == NULL) {
318 BIO_closesocket(ret);
319 ret = (int)INVALID_SOCKET;
320 } else {
321 strcpy(*ip_port, host);
322 strcat(*ip_port, ":");
323 strcat(*ip_port, port);
324 }
325 OPENSSL_free(host);
326 OPENSSL_free(port);
327 }
328
329 end:
330 return ret;
331 }
332 #endif
333
BIO_set_tcp_ndelay(int s,int on)334 int BIO_set_tcp_ndelay(int s, int on)
335 {
336 int ret = 0;
337 #if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
338 int opt;
339
340 #ifdef SOL_TCP
341 opt = SOL_TCP;
342 #else
343 #ifdef IPPROTO_TCP
344 opt = IPPROTO_TCP;
345 #endif
346 #endif
347
348 ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
349 #endif
350 return (ret == 0);
351 }
352
BIO_socket_nbio(int s,int mode)353 int BIO_socket_nbio(int s, int mode)
354 {
355 int ret = -1;
356 int l;
357
358 l = mode;
359 #ifdef FIONBIO
360 l = mode;
361
362 ret = BIO_socket_ioctl(s, FIONBIO, &l);
363 #elif defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(FNDELAY))
364 /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
365
366 l = fcntl(s, F_GETFL, 0);
367 if (l == -1) {
368 ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
369 "calling fcntl()");
370 ret = -1;
371 } else {
372 #if defined(O_NONBLOCK)
373 l &= ~O_NONBLOCK;
374 #else
375 l &= ~FNDELAY; /* BSD4.x */
376 #endif
377 if (mode) {
378 #if defined(O_NONBLOCK)
379 l |= O_NONBLOCK;
380 #else
381 l |= FNDELAY; /* BSD4.x */
382 #endif
383 }
384 ret = fcntl(s, F_SETFL, l);
385
386 if (ret < 0) {
387 ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
388 "calling fcntl()");
389 }
390 }
391 #else
392 /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
393 ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_INVALID_ARGUMENT);
394 #endif
395
396 return (ret == 0);
397 }
398
BIO_sock_info(int sock,enum BIO_sock_info_type type,union BIO_sock_info_u * info)399 int BIO_sock_info(int sock,
400 enum BIO_sock_info_type type, union BIO_sock_info_u *info)
401 {
402 switch (type) {
403 case BIO_SOCK_INFO_ADDRESS: {
404 socklen_t addr_len;
405 int ret = 0;
406 addr_len = sizeof(*info->addr);
407 ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
408 &addr_len);
409 if (ret == -1) {
410 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
411 "calling getsockname()");
412 ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR);
413 return 0;
414 }
415 if ((size_t)addr_len > sizeof(*info->addr)) {
416 ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
417 return 0;
418 }
419 } break;
420 default:
421 ERR_raise(ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE);
422 return 0;
423 }
424 return 1;
425 }
426
427 /*
428 * Wait on fd at most until max_time; succeed immediately if max_time == 0.
429 * If for_read == 0 then assume to wait for writing, else wait for reading.
430 * Returns -1 on error, 0 on timeout, and 1 on success.
431 */
BIO_socket_wait(int fd,int for_read,time_t max_time)432 int BIO_socket_wait(int fd, int for_read, time_t max_time)
433 {
434 #if defined(OPENSSL_SYS_WINDOWS) || !defined(POLLIN)
435 fd_set confds;
436 struct timeval tv;
437 time_t now;
438
439 #ifdef _WIN32
440 if ((SOCKET)fd == INVALID_SOCKET)
441 #else
442 if (fd < 0 || fd >= FD_SETSIZE)
443 #endif
444 return -1;
445 if (max_time == 0)
446 return 1;
447
448 now = time(NULL);
449 if (max_time < now)
450 return 0;
451
452 FD_ZERO(&confds);
453 openssl_fdset(fd, &confds);
454 tv.tv_usec = 0;
455 tv.tv_sec = (long)(max_time - now); /* might overflow */
456 return select(fd + 1, for_read ? &confds : NULL,
457 for_read ? NULL : &confds, NULL, &tv);
458 #else
459 struct pollfd confds;
460 time_t now;
461
462 if (fd < 0)
463 return -1;
464 if (max_time == 0)
465 return 1;
466
467 now = time(NULL);
468 if (max_time < now)
469 return 0;
470
471 confds.fd = fd;
472 confds.events = for_read ? POLLIN : POLLOUT;
473 return poll(&confds, 1, (int)(max_time - now) * 1000);
474 #endif
475 }
476 #endif /* !defined(OPENSSL_NO_SOCK) */
477