]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bio/b_sock.c
Re-align some comments after running the reformat script.
[thirdparty/openssl.git] / crypto / bio / b_sock.c
CommitLineData
d02b48c6 1/* crypto/bio/b_sock.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
0f113f3e 8 *
d02b48c6
RE
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
0f113f3e 15 *
d02b48c6
RE
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
0f113f3e 22 *
d02b48c6
RE
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
0f113f3e 37 * 4. If you include any Windows specific code (or a derivative thereof) from
d02b48c6
RE
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
0f113f3e 40 *
d02b48c6
RE
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
0f113f3e 52 *
d02b48c6
RE
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
d02b48c6 59#include <stdio.h>
58964a49 60#include <stdlib.h>
d02b48c6
RE
61#include <errno.h>
62#define USE_SOCKETS
63#include "cryptlib.h"
ec577822 64#include <openssl/bio.h>
b764ab95 65#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
0f113f3e
MC
66# include <netdb.h>
67# if defined(NETWARE_CLIB)
68# include <sys/ioctl.h>
eef0c1f3 69NETDB_DEFINE_CONTEXT
0f113f3e 70# endif
eef0c1f3 71#endif
9ba4cc00 72#ifndef OPENSSL_NO_SOCK
0f113f3e
MC
73# include <openssl/dso.h>
74# define SOCKET_PROTOCOL IPPROTO_TCP
75# ifdef SO_MAXCONN
76# define MAX_LISTEN SO_MAXCONN
77# elif defined(SOMAXCONN)
78# define MAX_LISTEN SOMAXCONN
79# else
80# define MAX_LISTEN 32
81# endif
82# if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
83static int wsa_init_done = 0;
84# endif
d02b48c6 85
2f4c1dc8
AP
86/*
87 * WSAAPI specifier is required to make indirect calls to run-time
88 * linked WinSock 2 functions used in this module, to be specific
89 * [get|free]addrinfo and getnameinfo. This is because WinSock uses
90 * uses non-C calling convention, __stdcall vs. __cdecl, on x86
91 * Windows. On non-WinSock platforms WSAAPI needs to be void.
92 */
0f113f3e
MC
93# ifndef WSAAPI
94# define WSAAPI
95# endif
96
97# if 0
98static unsigned long BIO_ghbn_hits = 0L;
99static unsigned long BIO_ghbn_miss = 0L;
100
101# define GHBN_NUM 4
102static struct ghbn_cache_st {
103 char name[129];
104 struct hostent *ent;
105 unsigned long order;
106} ghbn_cache[GHBN_NUM];
107# endif
108
109static int get_ip(const char *str, unsigned char *ip);
110# if 0
58964a49
RE
111static void ghbn_free(struct hostent *a);
112static struct hostent *ghbn_dup(struct hostent *a);
0f113f3e 113# endif
6b691a5c 114int BIO_get_host_ip(const char *str, unsigned char *ip)
0f113f3e
MC
115{
116 int i;
117 int err = 1;
118 int locked = 0;
119 struct hostent *he;
120
121 i = get_ip(str, ip);
122 if (i < 0) {
123 BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS);
124 goto err;
125 }
126
127 /*
128 * At this point, we have something that is most probably correct in some
129 * way, so let's init the socket.
130 */
131 if (BIO_sock_init() != 1)
132 return 0; /* don't generate another error code here */
133
134 /*
135 * If the string actually contained an IP address, we need not do
136 * anything more
137 */
138 if (i > 0)
139 return (1);
140
141 /* do a gethostbyname */
142 CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
143 locked = 1;
144 he = BIO_gethostbyname(str);
145 if (he == NULL) {
146 BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP);
147 goto err;
148 }
149
150 if (he->h_addrtype != AF_INET) {
151 BIOerr(BIO_F_BIO_GET_HOST_IP,
152 BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
153 goto err;
154 }
155 for (i = 0; i < 4; i++)
156 ip[i] = he->h_addr_list[0][i];
157 err = 0;
ba9f2808
BM
158
159 err:
0f113f3e
MC
160 if (locked)
161 CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
162 if (err) {
163 ERR_add_error_data(2, "host=", str);
164 return 0;
165 } else
166 return 1;
167}
d02b48c6 168
6b691a5c 169int BIO_get_port(const char *str, unsigned short *port_ptr)
0f113f3e
MC
170{
171 int i;
172 struct servent *s;
173
174 if (str == NULL) {
175 BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
176 return (0);
177 }
178 i = atoi(str);
179 if (i != 0)
180 *port_ptr = (unsigned short)i;
181 else {
182 CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
183 /*
184 * Note: under VMS with SOCKETSHR, it seems like the first parameter
185 * is 'char *', instead of 'const char *'
186 */
187# ifndef CONST_STRICT
188 s = getservbyname((char *)str, "tcp");
189# else
190 s = getservbyname(str, "tcp");
191# endif
192 if (s != NULL)
193 *port_ptr = ntohs((unsigned short)s->s_port);
194 CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
195 if (s == NULL) {
196 if (strcmp(str, "http") == 0)
197 *port_ptr = 80;
198 else if (strcmp(str, "telnet") == 0)
199 *port_ptr = 23;
200 else if (strcmp(str, "socks") == 0)
201 *port_ptr = 1080;
202 else if (strcmp(str, "https") == 0)
203 *port_ptr = 443;
204 else if (strcmp(str, "ssl") == 0)
205 *port_ptr = 443;
206 else if (strcmp(str, "ftp") == 0)
207 *port_ptr = 21;
208 else if (strcmp(str, "gopher") == 0)
209 *port_ptr = 70;
210# if 0
211 else if (strcmp(str, "wais") == 0)
212 *port_ptr = 21;
213# endif
214 else {
215 SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error());
216 ERR_add_error_data(3, "service='", str, "'");
217 return (0);
218 }
219 }
220 }
221 return (1);
222}
d02b48c6 223
6b691a5c 224int BIO_sock_error(int sock)
0f113f3e
MC
225{
226 int j, i;
227 union {
228 size_t s;
229 int i;
230 } size;
231
232 /* heuristic way to adapt for platforms that expect 64-bit optlen */
233 size.s = 0, size.i = sizeof(j);
234 /*
235 * Note: under Windows the third parameter is of type (char *) whereas
236 * under other systems it is (void *) if you don't have a cast it will
237 * choke the compiler: if you do have a cast then you can either go for
238 * (char *) or (void *).
239 */
240 i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size);
241 if (i < 0)
242 return (1);
243 else
244 return (j);
245}
246
247# if 0
6b691a5c 248long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
0f113f3e
MC
249{
250 int i;
251 char **p;
252
253 switch (cmd) {
254 case BIO_GHBN_CTRL_HITS:
255 return (BIO_ghbn_hits);
256 /* break; */
257 case BIO_GHBN_CTRL_MISSES:
258 return (BIO_ghbn_miss);
259 /* break; */
260 case BIO_GHBN_CTRL_CACHE_SIZE:
261 return (GHBN_NUM);
262 /* break; */
263 case BIO_GHBN_CTRL_GET_ENTRY:
264 if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) {
265 p = (char **)parg;
266 if (p == NULL)
267 return (0);
268 *p = ghbn_cache[iarg].name;
269 ghbn_cache[iarg].name[128] = '\0';
270 return (1);
271 }
272 return (0);
273 /* break; */
274 case BIO_GHBN_CTRL_FLUSH:
275 for (i = 0; i < GHBN_NUM; i++)
276 ghbn_cache[i].order = 0;
277 break;
278 default:
279 return (0);
280 }
281 return (1);
282}
283# endif
284
285# if 0
6b691a5c 286static struct hostent *ghbn_dup(struct hostent *a)
0f113f3e
MC
287{
288 struct hostent *ret;
289 int i, j;
290
291 MemCheck_off();
292 ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
293 if (ret == NULL)
294 return (NULL);
295 memset(ret, 0, sizeof(struct hostent));
296
297 for (i = 0; a->h_aliases[i] != NULL; i++) ;
298 i++;
299 ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *));
300 if (ret->h_aliases == NULL)
301 goto err;
302 memset(ret->h_aliases, 0, i * sizeof(char *));
303
304 for (i = 0; a->h_addr_list[i] != NULL; i++) ;
305 i++;
306 ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *));
307 if (ret->h_addr_list == NULL)
308 goto err;
309 memset(ret->h_addr_list, 0, i * sizeof(char *));
310
311 j = strlen(a->h_name) + 1;
312 if ((ret->h_name = OPENSSL_malloc(j)) == NULL)
313 goto err;
314 memcpy((char *)ret->h_name, a->h_name, j);
315 for (i = 0; a->h_aliases[i] != NULL; i++) {
316 j = strlen(a->h_aliases[i]) + 1;
317 if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL)
318 goto err;
319 memcpy(ret->h_aliases[i], a->h_aliases[i], j);
320 }
321 ret->h_length = a->h_length;
322 ret->h_addrtype = a->h_addrtype;
323 for (i = 0; a->h_addr_list[i] != NULL; i++) {
324 if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL)
325 goto err;
326 memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length);
327 }
328 if (0) {
329 err:
330 if (ret != NULL)
331 ghbn_free(ret);
332 ret = NULL;
333 }
334 MemCheck_on();
335 return (ret);
336}
58964a49 337
6b691a5c 338static void ghbn_free(struct hostent *a)
0f113f3e
MC
339{
340 int i;
341
342 if (a == NULL)
343 return;
344
345 if (a->h_aliases != NULL) {
346 for (i = 0; a->h_aliases[i] != NULL; i++)
347 OPENSSL_free(a->h_aliases[i]);
348 OPENSSL_free(a->h_aliases);
349 }
350 if (a->h_addr_list != NULL) {
351 for (i = 0; a->h_addr_list[i] != NULL; i++)
352 OPENSSL_free(a->h_addr_list[i]);
353 OPENSSL_free(a->h_addr_list);
354 }
355 if (a->h_name != NULL)
356 OPENSSL_free(a->h_name);
357 OPENSSL_free(a);
358}
359
360# endif
15863658 361
6b691a5c 362struct hostent *BIO_gethostbyname(const char *name)
0f113f3e
MC
363{
364# if 1
365 /*
366 * Caching gethostbyname() results forever is wrong, so we have to let
367 * the true gethostbyname() worry about this
368 */
369# if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
370 return gethostbyname((char *)name);
371# else
372 return gethostbyname(name);
373# endif
374# else
375 struct hostent *ret;
376 int i, lowi = 0, j;
377 unsigned long low = (unsigned long)-1;
58964a49 378
c602e7f4 379# if 0
0f113f3e
MC
380 /*
381 * It doesn't make sense to use locking here: The function interface is
382 * not thread-safe, because threads can never be sure when some other
383 * thread destroys the data they were given a pointer to.
384 */
385 CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
c602e7f4 386# endif
0f113f3e
MC
387 j = strlen(name);
388 if (j < 128) {
389 for (i = 0; i < GHBN_NUM; i++) {
390 if (low > ghbn_cache[i].order) {
391 low = ghbn_cache[i].order;
392 lowi = i;
393 }
394 if (ghbn_cache[i].order > 0) {
395 if (strncmp(name, ghbn_cache[i].name, 128) == 0)
396 break;
397 }
398 }
399 } else
400 i = GHBN_NUM;
401
402 if (i == GHBN_NUM) { /* no hit */
403 BIO_ghbn_miss++;
404 /*
405 * Note: under VMS with SOCKETSHR, it seems like the first parameter
406 * is 'char *', instead of 'const char *'
407 */
c602e7f4 408# ifndef CONST_STRICT
0f113f3e 409 ret = gethostbyname((char *)name);
eef0c1f3 410# else
0f113f3e 411 ret = gethostbyname(name);
c602e7f4 412# endif
58964a49 413
0f113f3e
MC
414 if (ret == NULL)
415 goto end;
416 if (j > 128) { /* too big to cache */
c602e7f4 417# if 0
0f113f3e
MC
418 /*
419 * If we were trying to make this function thread-safe (which is
420 * bound to fail), we'd have to give up in this case (or allocate
421 * more memory).
422 */
423 ret = NULL;
c602e7f4 424# endif
0f113f3e
MC
425 goto end;
426 }
427
428 /* else add to cache */
429 if (ghbn_cache[lowi].ent != NULL)
430 ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
431 ghbn_cache[lowi].name[0] = '\0';
432
433 if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) {
434 BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE);
435 goto end;
436 }
437 strncpy(ghbn_cache[lowi].name, name, 128);
438 ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits;
439 } else {
440 BIO_ghbn_hits++;
441 ret = ghbn_cache[i].ent;
442 ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits;
443 }
444 end:
c602e7f4 445# if 0
0f113f3e 446 CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
c602e7f4 447# endif
0f113f3e
MC
448 return (ret);
449# endif
450}
c602e7f4 451
6b691a5c 452int BIO_sock_init(void)
0f113f3e
MC
453{
454# ifdef OPENSSL_SYS_WINDOWS
455 static struct WSAData wsa_state;
456
457 if (!wsa_init_done) {
458 int err;
459
460 wsa_init_done = 1;
461 memset(&wsa_state, 0, sizeof(wsa_state));
462 /*
463 * Not making wsa_state available to the rest of the code is formally
464 * wrong. But the structures we use are [beleived to be] invariable
465 * among Winsock DLLs, while API availability is [expected to be]
466 * probed at run-time with DSO_global_lookup.
467 */
468 if (WSAStartup(0x0202, &wsa_state) != 0) {
469 err = WSAGetLastError();
470 SYSerr(SYS_F_WSASTARTUP, err);
471 BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
472 return (-1);
473 }
474 }
475# endif /* OPENSSL_SYS_WINDOWS */
476# ifdef WATT32
477 extern int _watt_do_exit;
478 _watt_do_exit = 0; /* don't make sock_init() call exit() */
479 if (sock_init())
480 return (-1);
481# endif
482
483# if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
4d8743f4
RL
484 WORD wVerReq;
485 WSADATA wsaData;
486 int err;
487
0f113f3e
MC
488 if (!wsa_init_done) {
489 wsa_init_done = 1;
490 wVerReq = MAKEWORD(2, 0);
491 err = WSAStartup(wVerReq, &wsaData);
492 if (err != 0) {
493 SYSerr(SYS_F_WSASTARTUP, err);
494 BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
495 return (-1);
496 }
497 }
498# endif
499
500 return (1);
501}
d02b48c6 502
6b691a5c 503void BIO_sock_cleanup(void)
0f113f3e
MC
504{
505# ifdef OPENSSL_SYS_WINDOWS
506 if (wsa_init_done) {
507 wsa_init_done = 0;
508# if 0 /* this call is claimed to be non-present in
509 * Winsock2 */
510 WSACancelBlockingCall();
511# endif
4d8743f4 512 WSACleanup();
0f113f3e
MC
513 }
514# elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
515 if (wsa_init_done) {
516 wsa_init_done = 0;
517 WSACleanup();
518 }
519# endif
520}
d02b48c6 521
0f113f3e 522# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
7d7d2cbc 523
c029841e 524int BIO_socket_ioctl(int fd, long type, void *arg)
0f113f3e
MC
525{
526 int i;
527
528# ifdef __DJGPP__
529 i = ioctlsocket(fd, type, (char *)arg);
530# else
531# if defined(OPENSSL_SYS_VMS)
50e735f9
MC
532 /*-
533 * 2011-02-18 SMS.
534 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
535 * observe that all the consumers pass in an "unsigned long *",
536 * so we arrange a local copy with a short pointer, and use
537 * that, instead.
538 */
0f113f3e
MC
539# if __INITIAL_POINTER_SIZE == 64
540# define ARG arg_32p
541# pragma pointer_size save
542# pragma pointer_size 32
543 unsigned long arg_32;
544 unsigned long *arg_32p;
545# pragma pointer_size restore
546 arg_32p = &arg_32;
547 arg_32 = *((unsigned long *)arg);
548# else /* __INITIAL_POINTER_SIZE == 64 */
549# define ARG arg
550# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
551# else /* defined(OPENSSL_SYS_VMS) */
552# define ARG arg
553# endif /* defined(OPENSSL_SYS_VMS) [else] */
554
555 i = ioctlsocket(fd, type, ARG);
556# endif /* __DJGPP__ */
557 if (i < 0)
558 SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
559 return (i);
560}
561# endif /* __VMS_VER */
562
563/*
564 * The reason I have implemented this instead of using sscanf is because
565 * Visual C 1.52c gives an unresolved external when linking a DLL :-(
566 */
6b691a5c 567static int get_ip(const char *str, unsigned char ip[4])
0f113f3e
MC
568{
569 unsigned int tmp[4];
570 int num = 0, c, ok = 0;
571
572 tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
573
574 for (;;) {
575 c = *(str++);
576 if ((c >= '0') && (c <= '9')) {
577 ok = 1;
578 tmp[num] = tmp[num] * 10 + c - '0';
579 if (tmp[num] > 255)
580 return (0);
581 } else if (c == '.') {
582 if (!ok)
583 return (-1);
584 if (num == 3)
585 return (0);
586 num++;
587 ok = 0;
588 } else if (c == '\0' && (num == 3) && ok)
589 break;
590 else
591 return (0);
592 }
593 ip[0] = tmp[0];
594 ip[1] = tmp[1];
595 ip[2] = tmp[2];
596 ip[3] = tmp[3];
597 return (1);
598}
d02b48c6 599
6b691a5c 600int BIO_get_accept_socket(char *host, int bind_mode)
0f113f3e
MC
601{
602 int ret = 0;
603 union {
604 struct sockaddr sa;
605 struct sockaddr_in sa_in;
606# if OPENSSL_USE_IPV6
607 struct sockaddr_in6 sa_in6;
608# endif
609 } server, client;
610 int s = INVALID_SOCKET, cs, addrlen;
611 unsigned char ip[4];
612 unsigned short port;
613 char *str = NULL, *e;
614 char *h, *p;
615 unsigned long l;
616 int err_num;
617
618 if (BIO_sock_init() != 1)
619 return (INVALID_SOCKET);
620
621 if ((str = BUF_strdup(host)) == NULL)
622 return (INVALID_SOCKET);
623
624 h = p = NULL;
625 h = str;
626 for (e = str; *e; e++) {
627 if (*e == ':') {
628 p = e;
629 } else if (*e == '/') {
630 *e = '\0';
631 break;
632 }
633 }
634 if (p)
635 *p++ = '\0'; /* points at last ':', '::port' is special
636 * [see below] */
637 else
638 p = h, h = NULL;
639
640# ifdef EAI_FAMILY
641 do {
642 static union {
643 void *p;
644 int (WSAAPI *f) (const char *, const char *,
645 const struct addrinfo *, struct addrinfo **);
646 } p_getaddrinfo = {
647 NULL
648 };
649 static union {
650 void *p;
651 void (WSAAPI *f) (struct addrinfo *);
652 } p_freeaddrinfo = {
653 NULL
654 };
655 struct addrinfo *res, hint;
656
657 if (p_getaddrinfo.p == NULL) {
658 if ((p_getaddrinfo.p = DSO_global_lookup("getaddrinfo")) == NULL
659 || (p_freeaddrinfo.p =
660 DSO_global_lookup("freeaddrinfo")) == NULL)
661 p_getaddrinfo.p = (void *)-1;
662 }
663 if (p_getaddrinfo.p == (void *)-1)
664 break;
665
666 /*
667 * '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris,
668 * default to IPv6 without any hint. Also note that commonly IPv6
669 * wildchard socket can service IPv4 connections just as well...
670 */
671 memset(&hint, 0, sizeof(hint));
672 hint.ai_flags = AI_PASSIVE;
673 if (h) {
674 if (strchr(h, ':')) {
675 if (h[1] == '\0')
676 h = NULL;
677# if OPENSSL_USE_IPV6
678 hint.ai_family = AF_INET6;
679# else
680 h = NULL;
681# endif
682 } else if (h[0] == '*' && h[1] == '\0') {
683 hint.ai_family = AF_INET;
684 h = NULL;
685 }
686 }
687
688 if ((*p_getaddrinfo.f) (h, p, &hint, &res))
689 break;
690
691 addrlen = res->ai_addrlen <= sizeof(server) ?
692 res->ai_addrlen : sizeof(server);
693 memcpy(&server, res->ai_addr, addrlen);
694
695 (*p_freeaddrinfo.f) (res);
696 goto again;
697 } while (0);
698# endif
699
700 if (!BIO_get_port(p, &port))
701 goto err;
702
703 memset((char *)&server, 0, sizeof(server));
704 server.sa_in.sin_family = AF_INET;
705 server.sa_in.sin_port = htons(port);
706 addrlen = sizeof(server.sa_in);
707
708 if (h == NULL || strcmp(h, "*") == 0)
709 server.sa_in.sin_addr.s_addr = INADDR_ANY;
710 else {
711 if (!BIO_get_host_ip(h, &(ip[0])))
712 goto err;
713 l = (unsigned long)
714 ((unsigned long)ip[0] << 24L) |
715 ((unsigned long)ip[1] << 16L) |
716 ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]);
717 server.sa_in.sin_addr.s_addr = htonl(l);
718 }
719
720 again:
721 s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
722 if (s == INVALID_SOCKET) {
723 SYSerr(SYS_F_SOCKET, get_last_socket_error());
724 ERR_add_error_data(3, "port='", host, "'");
725 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
726 goto err;
727 }
728# ifdef SO_REUSEADDR
729 if (bind_mode == BIO_BIND_REUSEADDR) {
730 int i = 1;
731
732 ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i));
733 bind_mode = BIO_BIND_NORMAL;
734 }
735# endif
736 if (bind(s, &server.sa, addrlen) == -1) {
737# ifdef SO_REUSEADDR
738 err_num = get_last_socket_error();
739 if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
740# ifdef OPENSSL_SYS_WINDOWS
741 /*
742 * Some versions of Windows define EADDRINUSE to a dummy value.
743 */
744 (err_num == WSAEADDRINUSE))
745# else
746 (err_num == EADDRINUSE))
747# endif
748 {
749 client = server;
750 if (h == NULL || strcmp(h, "*") == 0) {
751# if OPENSSL_USE_IPV6
752 if (client.sa.sa_family == AF_INET6) {
753 memset(&client.sa_in6.sin6_addr, 0,
754 sizeof(client.sa_in6.sin6_addr));
755 client.sa_in6.sin6_addr.s6_addr[15] = 1;
756 } else
757# endif
758 if (client.sa.sa_family == AF_INET) {
759 client.sa_in.sin_addr.s_addr = htonl(0x7F000001);
760 } else
761 goto err;
762 }
763 cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
764 if (cs != INVALID_SOCKET) {
765 int ii;
766 ii = connect(cs, &client.sa, addrlen);
767 closesocket(cs);
768 if (ii == INVALID_SOCKET) {
769 bind_mode = BIO_BIND_REUSEADDR;
770 closesocket(s);
771 goto again;
772 }
773 /* else error */
774 }
775 /* else error */
776 }
777# endif
778 SYSerr(SYS_F_BIND, err_num);
779 ERR_add_error_data(3, "port='", host, "'");
780 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET);
781 goto err;
782 }
783 if (listen(s, MAX_LISTEN) == -1) {
784 SYSerr(SYS_F_BIND, get_last_socket_error());
785 ERR_add_error_data(3, "port='", host, "'");
786 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET);
787 goto err;
788 }
789 ret = 1;
790 err:
791 if (str != NULL)
792 OPENSSL_free(str);
793 if ((ret == 0) && (s != INVALID_SOCKET)) {
794 closesocket(s);
795 s = INVALID_SOCKET;
796 }
797 return (s);
798}
d02b48c6 799
6b691a5c 800int BIO_accept(int sock, char **addr)
0f113f3e
MC
801{
802 int ret = INVALID_SOCKET;
803 unsigned long l;
804 unsigned short port;
805 char *p;
806
807 struct {
808 /*
809 * As for following union. Trouble is that there are platforms
810 * that have socklen_t and there are platforms that don't, on
811 * some platforms socklen_t is int and on some size_t. So what
812 * one can do? One can cook #ifdef spaghetti, which is nothing
813 * but masochistic. Or one can do union between int and size_t.
814 * One naturally does it primarily for 64-bit platforms where
815 * sizeof(int) != sizeof(size_t). But would it work? Note that
816 * if size_t member is initialized to 0, then later int member
817 * assignment naturally does the job on little-endian platforms
818 * regardless accept's expectations! What about big-endians?
819 * If accept expects int*, then it works, and if size_t*, then
820 * length value would appear as unreasonably large. But this
821 * won't prevent it from filling in the address structure. The
822 * trouble of course would be if accept returns more data than
823 * actual buffer can accomodate and overwrite stack... That's
824 * where early OPENSSL_assert comes into picture. Besides, the
825 * only 64-bit big-endian platform found so far that expects
826 * size_t* is HP-UX, where stack grows towards higher address.
827 * <appro>
828 */
829 union {
830 size_t s;
831 int i;
832 } len;
833 union {
834 struct sockaddr sa;
835 struct sockaddr_in sa_in;
836# if OPENSSL_USE_IPV6
837 struct sockaddr_in6 sa_in6;
838# endif
839 } from;
840 } sa;
841
842 sa.len.s = 0;
843 sa.len.i = sizeof(sa.from);
844 memset(&sa.from, 0, sizeof(sa.from));
845 ret = accept(sock, &sa.from.sa, (void *)&sa.len);
846 if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) {
847 OPENSSL_assert(sa.len.s <= sizeof(sa.from));
848 sa.len.i = (int)sa.len.s;
849 /* use sa.len.i from this point */
850 }
851 if (ret == INVALID_SOCKET) {
852 if (BIO_sock_should_retry(ret))
853 return -2;
854 SYSerr(SYS_F_ACCEPT, get_last_socket_error());
855 BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
856 goto end;
857 }
858
859 if (addr == NULL)
860 goto end;
861
862# ifdef EAI_FAMILY
863 do {
864 char h[NI_MAXHOST], s[NI_MAXSERV];
865 size_t nl;
866 static union {
867 void *p;
868 int (WSAAPI *f) (const struct sockaddr *, size_t /* socklen_t */ ,
869 char *, size_t, char *, size_t, int);
870 } p_getnameinfo = {
871 NULL
872 };
873 /*
874 * 2nd argument to getnameinfo is specified to be socklen_t.
875 * Unfortunately there is a number of environments where socklen_t is
876 * not defined. As it's passed by value, it's safe to pass it as
877 * size_t... <appro>
878 */
879
880 if (p_getnameinfo.p == NULL) {
881 if ((p_getnameinfo.p = DSO_global_lookup("getnameinfo")) == NULL)
882 p_getnameinfo.p = (void *)-1;
883 }
884 if (p_getnameinfo.p == (void *)-1)
885 break;
886
887 if ((*p_getnameinfo.f) (&sa.from.sa, sa.len.i, h, sizeof(h), s,
888 sizeof(s), NI_NUMERICHOST | NI_NUMERICSERV))
889 break;
890 nl = strlen(h) + strlen(s) + 2;
891 p = *addr;
892 if (p) {
893 *p = '\0';
894 p = OPENSSL_realloc(p, nl);
895 } else {
896 p = OPENSSL_malloc(nl);
897 }
898 if (p == NULL) {
899 BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
900 goto end;
901 }
902 *addr = p;
903 BIO_snprintf(*addr, nl, "%s:%s", h, s);
904 goto end;
905 } while (0);
906# endif
907 if (sa.from.sa.sa_family != AF_INET)
908 goto end;
909 l = ntohl(sa.from.sa_in.sin_addr.s_addr);
910 port = ntohs(sa.from.sa_in.sin_port);
911 if (*addr == NULL) {
912 if ((p = OPENSSL_malloc(24)) == NULL) {
913 BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
914 goto end;
915 }
916 *addr = p;
917 }
918 BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d",
919 (unsigned char)(l >> 24L) & 0xff,
920 (unsigned char)(l >> 16L) & 0xff,
921 (unsigned char)(l >> 8L) & 0xff,
922 (unsigned char)(l) & 0xff, port);
923 end:
924 return (ret);
925}
d02b48c6 926
6b691a5c 927int BIO_set_tcp_ndelay(int s, int on)
0f113f3e
MC
928{
929 int ret = 0;
930# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
931 int opt;
d02b48c6 932
0f113f3e
MC
933# ifdef SOL_TCP
934 opt = SOL_TCP;
935# else
936# ifdef IPPROTO_TCP
937 opt = IPPROTO_TCP;
938# endif
939# endif
dfeab068 940
0f113f3e
MC
941 ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
942# endif
943 return (ret == 0);
944}
945
946int BIO_socket_nbio(int s, int mode)
947{
948 int ret = -1;
949 int l;
950
951 l = mode;
952# ifdef FIONBIO
953 ret = BIO_socket_ioctl(s, FIONBIO, &l);
954# endif
955 return (ret == 0);
956}
4a1fbd13 957#endif