VirtualBox

source: vbox/trunk/src/libs/openssl-3.3.2/crypto/bio/bio_sock.c@ 108358

最後變更 在這個檔案從108358是 108206,由 vboxsync 提交於 6 週 前

openssl-3.3.2: Exported all files to OSE and removed .scm-settings ​bugref:10757

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette