]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/crypto/bio/b_sock.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / crypto / bio / b_sock.c
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 #include <stdio.h>
60 #include <stdlib.h>
61 #include <errno.h>
62 #define USE_SOCKETS
63 #include "cryptlib.h"
64 #include <openssl/bio.h>
65 #if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
66 # include <netdb.h>
67 # if defined(NETWARE_CLIB)
68 #  include <sys/ioctl.h>
69 NETDB_DEFINE_CONTEXT
70 # endif
71 #endif
72 #ifndef OPENSSL_NO_SOCK
73 # ifdef OPENSSL_SYS_WIN16
74 #  define SOCKET_PROTOCOL 0     /* more microsoft stupidity */
75 # else
76 #  define SOCKET_PROTOCOL IPPROTO_TCP
77 # endif
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 0
90 static unsigned long BIO_ghbn_hits = 0L;
91 static unsigned long BIO_ghbn_miss = 0L;
92
93 #  define GHBN_NUM        4
94 static struct ghbn_cache_st {
95     char name[129];
96     struct hostent *ent;
97     unsigned long order;
98 } ghbn_cache[GHBN_NUM];
99 # endif
100
101 static int get_ip(const char *str, unsigned char *ip);
102 # if 0
103 static void ghbn_free(struct hostent *a);
104 static struct hostent *ghbn_dup(struct hostent *a);
105 # endif
106 int BIO_get_host_ip(const char *str, unsigned char *ip)
107 {
108     int i;
109     int err = 1;
110     int locked = 0;
111     struct hostent *he;
112
113     i = get_ip(str, ip);
114     if (i < 0) {
115         BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS);
116         goto err;
117     }
118
119     /*
120      * At this point, we have something that is most probably correct in some
121      * way, so let's init the socket.
122      */
123     if (BIO_sock_init() != 1)
124         return 0;               /* don't generate another error code here */
125
126     /*
127      * If the string actually contained an IP address, we need not do
128      * anything more
129      */
130     if (i > 0)
131         return (1);
132
133     /* do a gethostbyname */
134     CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
135     locked = 1;
136     he = BIO_gethostbyname(str);
137     if (he == NULL) {
138         BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP);
139         goto err;
140     }
141
142     /* cast to short because of win16 winsock definition */
143     if ((short)he->h_addrtype != AF_INET) {
144         BIOerr(BIO_F_BIO_GET_HOST_IP,
145                BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
146         goto err;
147     }
148     for (i = 0; i < 4; i++)
149         ip[i] = he->h_addr_list[0][i];
150     err = 0;
151
152  err:
153     if (locked)
154         CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
155     if (err) {
156         ERR_add_error_data(2, "host=", str);
157         return 0;
158     } else
159         return 1;
160 }
161
162 int BIO_get_port(const char *str, unsigned short *port_ptr)
163 {
164     int i;
165     struct servent *s;
166
167     if (str == NULL) {
168         BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
169         return (0);
170     }
171     i = atoi(str);
172     if (i != 0)
173         *port_ptr = (unsigned short)i;
174     else {
175         CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
176         /*
177          * Note: under VMS with SOCKETSHR, it seems like the first parameter
178          * is 'char *', instead of 'const char *'
179          */
180 # ifndef CONST_STRICT
181         s = getservbyname((char *)str, "tcp");
182 # else
183         s = getservbyname(str, "tcp");
184 # endif
185         if (s != NULL)
186             *port_ptr = ntohs((unsigned short)s->s_port);
187         CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
188         if (s == NULL) {
189             if (strcmp(str, "http") == 0)
190                 *port_ptr = 80;
191             else if (strcmp(str, "telnet") == 0)
192                 *port_ptr = 23;
193             else if (strcmp(str, "socks") == 0)
194                 *port_ptr = 1080;
195             else if (strcmp(str, "https") == 0)
196                 *port_ptr = 443;
197             else if (strcmp(str, "ssl") == 0)
198                 *port_ptr = 443;
199             else if (strcmp(str, "ftp") == 0)
200                 *port_ptr = 21;
201             else if (strcmp(str, "gopher") == 0)
202                 *port_ptr = 70;
203 # if 0
204             else if (strcmp(str, "wais") == 0)
205                 *port_ptr = 21;
206 # endif
207             else {
208                 SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error());
209                 ERR_add_error_data(3, "service='", str, "'");
210                 return (0);
211             }
212         }
213     }
214     return (1);
215 }
216
217 int BIO_sock_error(int sock)
218 {
219     int j, i;
220     int size;
221
222     size = sizeof(int);
223     /*
224      * Note: under Windows the third parameter is of type (char *) whereas
225      * under other systems it is (void *) if you don't have a cast it will
226      * choke the compiler: if you do have a cast then you can either go for
227      * (char *) or (void *).
228      */
229     i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size);
230     if (i < 0)
231         return (1);
232     else
233         return (j);
234 }
235
236 # if 0
237 long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
238 {
239     int i;
240     char **p;
241
242     switch (cmd) {
243     case BIO_GHBN_CTRL_HITS:
244         return (BIO_ghbn_hits);
245         /* break; */
246     case BIO_GHBN_CTRL_MISSES:
247         return (BIO_ghbn_miss);
248         /* break; */
249     case BIO_GHBN_CTRL_CACHE_SIZE:
250         return (GHBN_NUM);
251         /* break; */
252     case BIO_GHBN_CTRL_GET_ENTRY:
253         if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) {
254             p = (char **)parg;
255             if (p == NULL)
256                 return (0);
257             *p = ghbn_cache[iarg].name;
258             ghbn_cache[iarg].name[128] = '\0';
259             return (1);
260         }
261         return (0);
262         /* break; */
263     case BIO_GHBN_CTRL_FLUSH:
264         for (i = 0; i < GHBN_NUM; i++)
265             ghbn_cache[i].order = 0;
266         break;
267     default:
268         return (0);
269     }
270     return (1);
271 }
272 # endif
273
274 # if 0
275 static struct hostent *ghbn_dup(struct hostent *a)
276 {
277     struct hostent *ret;
278     int i, j;
279
280     MemCheck_off();
281     ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
282     if (ret == NULL)
283         return (NULL);
284     memset(ret, 0, sizeof(struct hostent));
285
286     for (i = 0; a->h_aliases[i] != NULL; i++) ;
287     i++;
288     ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *));
289     if (ret->h_aliases == NULL)
290         goto err;
291     memset(ret->h_aliases, 0, i * sizeof(char *));
292
293     for (i = 0; a->h_addr_list[i] != NULL; i++) ;
294     i++;
295     ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *));
296     if (ret->h_addr_list == NULL)
297         goto err;
298     memset(ret->h_addr_list, 0, i * sizeof(char *));
299
300     j = strlen(a->h_name) + 1;
301     if ((ret->h_name = OPENSSL_malloc(j)) == NULL)
302         goto err;
303     memcpy((char *)ret->h_name, a->h_name, j);
304     for (i = 0; a->h_aliases[i] != NULL; i++) {
305         j = strlen(a->h_aliases[i]) + 1;
306         if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL)
307             goto err;
308         memcpy(ret->h_aliases[i], a->h_aliases[i], j);
309     }
310     ret->h_length = a->h_length;
311     ret->h_addrtype = a->h_addrtype;
312     for (i = 0; a->h_addr_list[i] != NULL; i++) {
313         if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL)
314             goto err;
315         memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length);
316     }
317     if (0) {
318  err:
319         if (ret != NULL)
320             ghbn_free(ret);
321         ret = NULL;
322     }
323     MemCheck_on();
324     return (ret);
325 }
326
327 static void ghbn_free(struct hostent *a)
328 {
329     int i;
330
331     if (a == NULL)
332         return;
333
334     if (a->h_aliases != NULL) {
335         for (i = 0; a->h_aliases[i] != NULL; i++)
336             OPENSSL_free(a->h_aliases[i]);
337         OPENSSL_free(a->h_aliases);
338     }
339     if (a->h_addr_list != NULL) {
340         for (i = 0; a->h_addr_list[i] != NULL; i++)
341             OPENSSL_free(a->h_addr_list[i]);
342         OPENSSL_free(a->h_addr_list);
343     }
344     if (a->h_name != NULL)
345         OPENSSL_free(a->h_name);
346     OPENSSL_free(a);
347 }
348
349 # endif
350
351 struct hostent *BIO_gethostbyname(const char *name)
352 {
353 # if 1
354     /*
355      * Caching gethostbyname() results forever is wrong, so we have to let
356      * the true gethostbyname() worry about this
357      */
358 #  if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
359     return gethostbyname((char *)name);
360 #  else
361     return gethostbyname(name);
362 #  endif
363 # else
364     struct hostent *ret;
365     int i, lowi = 0, j;
366     unsigned long low = (unsigned long)-1;
367
368 #  if 0
369     /*
370      * It doesn't make sense to use locking here: The function interface is
371      * not thread-safe, because threads can never be sure when some other
372      * thread destroys the data they were given a pointer to.
373      */
374     CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
375 #  endif
376     j = strlen(name);
377     if (j < 128) {
378         for (i = 0; i < GHBN_NUM; i++) {
379             if (low > ghbn_cache[i].order) {
380                 low = ghbn_cache[i].order;
381                 lowi = i;
382             }
383             if (ghbn_cache[i].order > 0) {
384                 if (strncmp(name, ghbn_cache[i].name, 128) == 0)
385                     break;
386             }
387         }
388     } else
389         i = GHBN_NUM;
390
391     if (i == GHBN_NUM) {        /* no hit */
392         BIO_ghbn_miss++;
393         /*
394          * Note: under VMS with SOCKETSHR, it seems like the first parameter
395          * is 'char *', instead of 'const char *'
396          */
397 #  ifndef CONST_STRICT
398         ret = gethostbyname((char *)name);
399 #  else
400         ret = gethostbyname(name);
401 #  endif
402
403         if (ret == NULL)
404             goto end;
405         if (j > 128) {          /* too big to cache */
406 #  if 0
407             /*
408              * If we were trying to make this function thread-safe (which is
409              * bound to fail), we'd have to give up in this case (or allocate
410              * more memory).
411              */
412             ret = NULL;
413 #  endif
414             goto end;
415         }
416
417         /* else add to cache */
418         if (ghbn_cache[lowi].ent != NULL)
419             ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
420         ghbn_cache[lowi].name[0] = '\0';
421
422         if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) {
423             BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE);
424             goto end;
425         }
426         strncpy(ghbn_cache[lowi].name, name, 128);
427         ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits;
428     } else {
429         BIO_ghbn_hits++;
430         ret = ghbn_cache[i].ent;
431         ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits;
432     }
433  end:
434 #  if 0
435     CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
436 #  endif
437     return (ret);
438 # endif
439 }
440
441 int BIO_sock_init(void)
442 {
443 # ifdef OPENSSL_SYS_WINDOWS
444     static struct WSAData wsa_state;
445
446     if (!wsa_init_done) {
447         int err;
448
449         wsa_init_done = 1;
450         memset(&wsa_state, 0, sizeof(wsa_state));
451         if (WSAStartup(0x0101, &wsa_state) != 0) {
452             err = WSAGetLastError();
453             SYSerr(SYS_F_WSASTARTUP, err);
454             BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
455             return (-1);
456         }
457     }
458 # endif                         /* OPENSSL_SYS_WINDOWS */
459 # ifdef WATT32
460     extern int _watt_do_exit;
461     _watt_do_exit = 0;          /* don't make sock_init() call exit() */
462     if (sock_init())
463         return (-1);
464 # endif
465
466 # if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
467     WORD wVerReq;
468     WSADATA wsaData;
469     int err;
470
471     if (!wsa_init_done) {
472         wsa_init_done = 1;
473         wVerReq = MAKEWORD(2, 0);
474         err = WSAStartup(wVerReq, &wsaData);
475         if (err != 0) {
476             SYSerr(SYS_F_WSASTARTUP, err);
477             BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
478             return (-1);
479         }
480     }
481 # endif
482
483     return (1);
484 }
485
486 void BIO_sock_cleanup(void)
487 {
488 # ifdef OPENSSL_SYS_WINDOWS
489     if (wsa_init_done) {
490         wsa_init_done = 0;
491 #  ifndef OPENSSL_SYS_WINCE
492         WSACancelBlockingCall(); /* Winsock 1.1 specific */
493 #  endif
494         WSACleanup();
495     }
496 # elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
497     if (wsa_init_done) {
498         wsa_init_done = 0;
499         WSACleanup();
500     }
501 # endif
502 }
503
504 # if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
505
506 int BIO_socket_ioctl(int fd, long type, void *arg)
507 {
508     int i;
509
510 #  ifdef __DJGPP__
511     i = ioctlsocket(fd, type, (char *)arg);
512 #  else
513     i = ioctlsocket(fd, type, arg);
514 #  endif                        /* __DJGPP__ */
515     if (i < 0)
516         SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
517     return (i);
518 }
519 # endif                         /* __VMS_VER */
520
521 /*
522  * The reason I have implemented this instead of using sscanf is because
523  * Visual C 1.52c gives an unresolved external when linking a DLL :-(
524  */
525 static int get_ip(const char *str, unsigned char ip[4])
526 {
527     unsigned int tmp[4];
528     int num = 0, c, ok = 0;
529
530     tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
531
532     for (;;) {
533         c = *(str++);
534         if ((c >= '0') && (c <= '9')) {
535             ok = 1;
536             tmp[num] = tmp[num] * 10 + c - '0';
537             if (tmp[num] > 255)
538                 return (0);
539         } else if (c == '.') {
540             if (!ok)
541                 return (-1);
542             if (num == 3)
543                 return (0);
544             num++;
545             ok = 0;
546         } else if (c == '\0' && (num == 3) && ok)
547             break;
548         else
549             return (0);
550     }
551     ip[0] = tmp[0];
552     ip[1] = tmp[1];
553     ip[2] = tmp[2];
554     ip[3] = tmp[3];
555     return (1);
556 }
557
558 int BIO_get_accept_socket(char *host, int bind_mode)
559 {
560     int ret = 0;
561     struct sockaddr_in server, client;
562     int s = INVALID_SOCKET, cs;
563     unsigned char ip[4];
564     unsigned short port;
565     char *str = NULL, *e;
566     const char *h, *p;
567     unsigned long l;
568     int err_num;
569
570     if (BIO_sock_init() != 1)
571         return (INVALID_SOCKET);
572
573     if ((str = BUF_strdup(host)) == NULL)
574         return (INVALID_SOCKET);
575
576     h = p = NULL;
577     h = str;
578     for (e = str; *e; e++) {
579         if (*e == ':') {
580             p = &(e[1]);
581             *e = '\0';
582         } else if (*e == '/') {
583             *e = '\0';
584             break;
585         }
586     }
587
588     if (p == NULL) {
589         p = h;
590         h = "*";
591     }
592
593     if (!BIO_get_port(p, &port))
594         goto err;
595
596     memset((char *)&server, 0, sizeof(server));
597     server.sin_family = AF_INET;
598     server.sin_port = htons(port);
599
600     if (strcmp(h, "*") == 0)
601         server.sin_addr.s_addr = INADDR_ANY;
602     else {
603         if (!BIO_get_host_ip(h, &(ip[0])))
604             goto err;
605         l = (unsigned long)
606             ((unsigned long)ip[0] << 24L) |
607             ((unsigned long)ip[1] << 16L) |
608             ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]);
609         server.sin_addr.s_addr = htonl(l);
610     }
611
612  again:
613     s = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL);
614     if (s == INVALID_SOCKET) {
615         SYSerr(SYS_F_SOCKET, get_last_socket_error());
616         ERR_add_error_data(3, "port='", host, "'");
617         BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
618         goto err;
619     }
620 # ifdef SO_REUSEADDR
621     if (bind_mode == BIO_BIND_REUSEADDR) {
622         int i = 1;
623
624         ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i));
625         bind_mode = BIO_BIND_NORMAL;
626     }
627 # endif
628     if (bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) {
629 # ifdef SO_REUSEADDR
630         err_num = get_last_socket_error();
631         if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
632 #  ifdef OPENSSL_SYS_WINDOWS
633             /*
634              * Some versions of Windows define EADDRINUSE to a dummy value.
635              */
636             (err_num == WSAEADDRINUSE))
637 #  else
638             (err_num == EADDRINUSE))
639 #  endif
640         {
641             memcpy((char *)&client, (char *)&server, sizeof(server));
642             if (strcmp(h, "*") == 0)
643                 client.sin_addr.s_addr = htonl(0x7F000001);
644             cs = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL);
645             if (cs != INVALID_SOCKET) {
646                 int ii;
647                 ii = connect(cs, (struct sockaddr *)&client, sizeof(client));
648                 closesocket(cs);
649                 if (ii == INVALID_SOCKET) {
650                     bind_mode = BIO_BIND_REUSEADDR;
651                     closesocket(s);
652                     goto again;
653                 }
654                 /* else error */
655             }
656             /* else error */
657         }
658 # endif
659         SYSerr(SYS_F_BIND, err_num);
660         ERR_add_error_data(3, "port='", host, "'");
661         BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET);
662         goto err;
663     }
664     if (listen(s, MAX_LISTEN) == -1) {
665         SYSerr(SYS_F_BIND, get_last_socket_error());
666         ERR_add_error_data(3, "port='", host, "'");
667         BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET);
668         goto err;
669     }
670     ret = 1;
671  err:
672     if (str != NULL)
673         OPENSSL_free(str);
674     if ((ret == 0) && (s != INVALID_SOCKET)) {
675         closesocket(s);
676         s = INVALID_SOCKET;
677     }
678     return (s);
679 }
680
681 int BIO_accept(int sock, char **addr)
682 {
683     int ret = INVALID_SOCKET;
684     static struct sockaddr_in from;
685     unsigned long l;
686     unsigned short port;
687     int len;
688     char *p;
689
690     memset((char *)&from, 0, sizeof(from));
691     len = sizeof(from);
692     /*
693      * Note: under VMS with SOCKETSHR the fourth parameter is currently of
694      * type (int *) whereas under other systems it is (void *) if you don't
695      * have a cast it will choke the compiler: if you do have a cast then you
696      * can either go for (int *) or (void *).
697      */
698     ret = accept(sock, (struct sockaddr *)&from, (void *)&len);
699     if (ret == INVALID_SOCKET) {
700         if (BIO_sock_should_retry(ret))
701             return -2;
702         SYSerr(SYS_F_ACCEPT, get_last_socket_error());
703         BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
704         goto end;
705     }
706
707     if (addr == NULL)
708         goto end;
709
710     l = ntohl(from.sin_addr.s_addr);
711     port = ntohs(from.sin_port);
712     if (*addr == NULL) {
713         if ((p = OPENSSL_malloc(24)) == NULL) {
714             BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
715             goto end;
716         }
717         *addr = p;
718     }
719     BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d",
720                  (unsigned char)(l >> 24L) & 0xff,
721                  (unsigned char)(l >> 16L) & 0xff,
722                  (unsigned char)(l >> 8L) & 0xff,
723                  (unsigned char)(l) & 0xff, port);
724  end:
725     return (ret);
726 }
727
728 int BIO_set_tcp_ndelay(int s, int on)
729 {
730     int ret = 0;
731 # if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
732     int opt;
733
734 #  ifdef SOL_TCP
735     opt = SOL_TCP;
736 #  else
737 #   ifdef IPPROTO_TCP
738     opt = IPPROTO_TCP;
739 #   endif
740 #  endif
741
742     ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
743 # endif
744     return (ret == 0);
745 }
746 #endif
747
748 int BIO_socket_nbio(int s, int mode)
749 {
750     int ret = -1;
751     int l;
752
753     l = mode;
754 #ifdef FIONBIO
755     ret = BIO_socket_ioctl(s, FIONBIO, &l);
756 #endif
757     return (ret == 0);
758 }