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