ca485d9c19f141bdbeafb80a936cc548a76687dc
[openssl.git] / 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 # 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))
83 static int wsa_init_done = 0;
84 # endif
85
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  */
93 # ifndef WSAAPI
94 #  define WSAAPI
95 # endif
96
97 static int get_ip(const char *str, unsigned char *ip);
98 int BIO_get_host_ip(const char *str, unsigned char *ip)
99 {
100     int i;
101     int err = 1;
102     int locked = 0;
103     struct hostent *he;
104
105     i = get_ip(str, ip);
106     if (i < 0) {
107         BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS);
108         goto err;
109     }
110
111     /*
112      * At this point, we have something that is most probably correct in some
113      * way, so let's init the socket.
114      */
115     if (BIO_sock_init() != 1)
116         return 0;               /* don't generate another error code here */
117
118     /*
119      * If the string actually contained an IP address, we need not do
120      * anything more
121      */
122     if (i > 0)
123         return (1);
124
125     /* do a gethostbyname */
126     CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
127     locked = 1;
128     he = BIO_gethostbyname(str);
129     if (he == NULL) {
130         BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP);
131         goto err;
132     }
133
134     if (he->h_addrtype != AF_INET) {
135         BIOerr(BIO_F_BIO_GET_HOST_IP,
136                BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
137         goto err;
138     }
139     for (i = 0; i < 4; i++)
140         ip[i] = he->h_addr_list[0][i];
141     err = 0;
142
143  err:
144     if (locked)
145         CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
146     if (err) {
147         ERR_add_error_data(2, "host=", str);
148         return 0;
149     } else
150         return 1;
151 }
152
153 int BIO_get_port(const char *str, unsigned short *port_ptr)
154 {
155     int i;
156     struct servent *s;
157
158     if (str == NULL) {
159         BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
160         return (0);
161     }
162     i = atoi(str);
163     if (i != 0)
164         *port_ptr = (unsigned short)i;
165     else {
166         CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
167         /*
168          * Note: under VMS with SOCKETSHR, it seems like the first parameter
169          * is 'char *', instead of 'const char *'
170          */
171 # ifndef CONST_STRICT
172         s = getservbyname((char *)str, "tcp");
173 # else
174         s = getservbyname(str, "tcp");
175 # endif
176         if (s != NULL)
177             *port_ptr = ntohs((unsigned short)s->s_port);
178         CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
179         if (s == NULL) {
180             if (strcmp(str, "http") == 0)
181                 *port_ptr = 80;
182             else if (strcmp(str, "telnet") == 0)
183                 *port_ptr = 23;
184             else if (strcmp(str, "socks") == 0)
185                 *port_ptr = 1080;
186             else if (strcmp(str, "https") == 0)
187                 *port_ptr = 443;
188             else if (strcmp(str, "ssl") == 0)
189                 *port_ptr = 443;
190             else if (strcmp(str, "ftp") == 0)
191                 *port_ptr = 21;
192             else if (strcmp(str, "gopher") == 0)
193                 *port_ptr = 70;
194             else {
195                 SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error());
196                 ERR_add_error_data(3, "service='", str, "'");
197                 return (0);
198             }
199         }
200     }
201     return (1);
202 }
203
204 int BIO_sock_error(int sock)
205 {
206     int j, i;
207     union {
208         size_t s;
209         int i;
210     } size;
211
212     /* heuristic way to adapt for platforms that expect 64-bit optlen */
213     size.s = 0, size.i = sizeof(j);
214     /*
215      * Note: under Windows the third parameter is of type (char *) whereas
216      * under other systems it is (void *) if you don't have a cast it will
217      * choke the compiler: if you do have a cast then you can either go for
218      * (char *) or (void *).
219      */
220     i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size);
221     if (i < 0)
222         return (1);
223     else
224         return (j);
225 }
226
227 struct hostent *BIO_gethostbyname(const char *name)
228 {
229     /*
230      * Caching gethostbyname() results forever is wrong, so we have to let
231      * the true gethostbyname() worry about this
232      */
233 # if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
234     return gethostbyname((char *)name);
235 # else
236     return gethostbyname(name);
237 # endif
238 }
239
240 int BIO_sock_init(void)
241 {
242 # ifdef OPENSSL_SYS_WINDOWS
243     static struct WSAData wsa_state;
244
245     if (!wsa_init_done) {
246         int err;
247
248         wsa_init_done = 1;
249         memset(&wsa_state, 0, sizeof(wsa_state));
250         /*
251          * Not making wsa_state available to the rest of the code is formally
252          * wrong. But the structures we use are [beleived to be] invariable
253          * among Winsock DLLs, while API availability is [expected to be]
254          * probed at run-time with DSO_global_lookup.
255          */
256         if (WSAStartup(0x0202, &wsa_state) != 0) {
257             err = WSAGetLastError();
258             SYSerr(SYS_F_WSASTARTUP, err);
259             BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
260             return (-1);
261         }
262     }
263 # endif                         /* OPENSSL_SYS_WINDOWS */
264 # ifdef WATT32
265     extern int _watt_do_exit;
266     _watt_do_exit = 0;          /* don't make sock_init() call exit() */
267     if (sock_init())
268         return (-1);
269 # endif
270
271 # if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
272     WORD wVerReq;
273     WSADATA wsaData;
274     int err;
275
276     if (!wsa_init_done) {
277         wsa_init_done = 1;
278         wVerReq = MAKEWORD(2, 0);
279         err = WSAStartup(wVerReq, &wsaData);
280         if (err != 0) {
281             SYSerr(SYS_F_WSASTARTUP, err);
282             BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
283             return (-1);
284         }
285     }
286 # endif
287
288     return (1);
289 }
290
291 void BIO_sock_cleanup(void)
292 {
293 # ifdef OPENSSL_SYS_WINDOWS
294     if (wsa_init_done) {
295         wsa_init_done = 0;
296         WSACleanup();
297     }
298 # elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
299     if (wsa_init_done) {
300         wsa_init_done = 0;
301         WSACleanup();
302     }
303 # endif
304 }
305
306 # if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
307
308 int BIO_socket_ioctl(int fd, long type, void *arg)
309 {
310     int i;
311
312 #  ifdef __DJGPP__
313     i = ioctlsocket(fd, type, (char *)arg);
314 #  else
315 #   if defined(OPENSSL_SYS_VMS)
316     /*-
317      * 2011-02-18 SMS.
318      * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
319      * observe that all the consumers pass in an "unsigned long *",
320      * so we arrange a local copy with a short pointer, and use
321      * that, instead.
322      */
323 #    if __INITIAL_POINTER_SIZE == 64
324 #     define ARG arg_32p
325 #     pragma pointer_size save
326 #     pragma pointer_size 32
327     unsigned long arg_32;
328     unsigned long *arg_32p;
329 #     pragma pointer_size restore
330     arg_32p = &arg_32;
331     arg_32 = *((unsigned long *)arg);
332 #    else                       /* __INITIAL_POINTER_SIZE == 64 */
333 #     define ARG arg
334 #    endif                      /* __INITIAL_POINTER_SIZE == 64 [else] */
335 #   else                        /* defined(OPENSSL_SYS_VMS) */
336 #    define ARG arg
337 #   endif                       /* defined(OPENSSL_SYS_VMS) [else] */
338
339     i = ioctlsocket(fd, type, ARG);
340 #  endif                        /* __DJGPP__ */
341     if (i < 0)
342         SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
343     return (i);
344 }
345 # endif                         /* __VMS_VER */
346
347 /*
348  * The reason I have implemented this instead of using sscanf is because
349  * Visual C 1.52c gives an unresolved external when linking a DLL :-(
350  */
351 static int get_ip(const char *str, unsigned char ip[4])
352 {
353     unsigned int tmp[4];
354     int num = 0, c, ok = 0;
355
356     tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
357
358     for (;;) {
359         c = *(str++);
360         if ((c >= '0') && (c <= '9')) {
361             ok = 1;
362             tmp[num] = tmp[num] * 10 + c - '0';
363             if (tmp[num] > 255)
364                 return (0);
365         } else if (c == '.') {
366             if (!ok)
367                 return (-1);
368             if (num == 3)
369                 return (0);
370             num++;
371             ok = 0;
372         } else if (c == '\0' && (num == 3) && ok)
373             break;
374         else
375             return (0);
376     }
377     ip[0] = tmp[0];
378     ip[1] = tmp[1];
379     ip[2] = tmp[2];
380     ip[3] = tmp[3];
381     return (1);
382 }
383
384 int BIO_get_accept_socket(char *host, int bind_mode)
385 {
386     int ret = 0;
387     union {
388         struct sockaddr sa;
389         struct sockaddr_in sa_in;
390 # if OPENSSL_USE_IPV6
391         struct sockaddr_in6 sa_in6;
392 # endif
393     } server, client;
394     int s = INVALID_SOCKET, cs, addrlen;
395     unsigned char ip[4];
396     unsigned short port;
397     char *str = NULL, *e;
398     char *h, *p;
399     unsigned long l;
400     int err_num;
401
402     if (BIO_sock_init() != 1)
403         return (INVALID_SOCKET);
404
405     if ((str = BUF_strdup(host)) == NULL)
406         return (INVALID_SOCKET);
407
408     h = p = NULL;
409     h = str;
410     for (e = str; *e; e++) {
411         if (*e == ':') {
412             p = e;
413         } else if (*e == '/') {
414             *e = '\0';
415             break;
416         }
417     }
418     if (p)
419         *p++ = '\0';            /* points at last ':', '::port' is special
420                                  * [see below] */
421     else
422         p = h, h = NULL;
423
424 # ifdef EAI_FAMILY
425     do {
426         static union {
427             void *p;
428             int (WSAAPI *f) (const char *, const char *,
429                              const struct addrinfo *, struct addrinfo **);
430         } p_getaddrinfo = {
431             NULL
432         };
433         static union {
434             void *p;
435             void (WSAAPI *f) (struct addrinfo *);
436         } p_freeaddrinfo = {
437             NULL
438         };
439         struct addrinfo *res, hint;
440
441         if (p_getaddrinfo.p == NULL) {
442             if ((p_getaddrinfo.p = DSO_global_lookup("getaddrinfo")) == NULL
443                 || (p_freeaddrinfo.p =
444                     DSO_global_lookup("freeaddrinfo")) == NULL)
445                 p_getaddrinfo.p = (void *)-1;
446         }
447         if (p_getaddrinfo.p == (void *)-1)
448             break;
449
450         /*
451          * '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris,
452          * default to IPv6 without any hint. Also note that commonly IPv6
453          * wildchard socket can service IPv4 connections just as well...
454          */
455         memset(&hint, 0, sizeof(hint));
456         hint.ai_flags = AI_PASSIVE;
457         if (h) {
458             if (strchr(h, ':')) {
459                 if (h[1] == '\0')
460                     h = NULL;
461 #  if OPENSSL_USE_IPV6
462                 hint.ai_family = AF_INET6;
463 #  else
464                 h = NULL;
465 #  endif
466             } else if (h[0] == '*' && h[1] == '\0') {
467                 hint.ai_family = AF_INET;
468                 h = NULL;
469             }
470         }
471
472         if ((*p_getaddrinfo.f) (h, p, &hint, &res))
473             break;
474
475         addrlen = res->ai_addrlen <= sizeof(server) ?
476             res->ai_addrlen : sizeof(server);
477         memcpy(&server, res->ai_addr, addrlen);
478
479         (*p_freeaddrinfo.f) (res);
480         goto again;
481     } while (0);
482 # endif
483
484     if (!BIO_get_port(p, &port))
485         goto err;
486
487     memset((char *)&server, 0, sizeof(server));
488     server.sa_in.sin_family = AF_INET;
489     server.sa_in.sin_port = htons(port);
490     addrlen = sizeof(server.sa_in);
491
492     if (h == NULL || strcmp(h, "*") == 0)
493         server.sa_in.sin_addr.s_addr = INADDR_ANY;
494     else {
495         if (!BIO_get_host_ip(h, &(ip[0])))
496             goto err;
497         l = (unsigned long)
498             ((unsigned long)ip[0] << 24L) |
499             ((unsigned long)ip[1] << 16L) |
500             ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]);
501         server.sa_in.sin_addr.s_addr = htonl(l);
502     }
503
504  again:
505     s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
506     if (s == INVALID_SOCKET) {
507         SYSerr(SYS_F_SOCKET, get_last_socket_error());
508         ERR_add_error_data(3, "port='", host, "'");
509         BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
510         goto err;
511     }
512 # ifdef SO_REUSEADDR
513     if (bind_mode == BIO_BIND_REUSEADDR) {
514         int i = 1;
515
516         ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i));
517         bind_mode = BIO_BIND_NORMAL;
518     }
519 # endif
520     if (bind(s, &server.sa, addrlen) == -1) {
521 # ifdef SO_REUSEADDR
522         err_num = get_last_socket_error();
523         if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
524 #  ifdef OPENSSL_SYS_WINDOWS
525             /*
526              * Some versions of Windows define EADDRINUSE to a dummy value.
527              */
528             (err_num == WSAEADDRINUSE))
529 #  else
530             (err_num == EADDRINUSE))
531 #  endif
532         {
533             client = server;
534             if (h == NULL || strcmp(h, "*") == 0) {
535 #  if OPENSSL_USE_IPV6
536                 if (client.sa.sa_family == AF_INET6) {
537                     memset(&client.sa_in6.sin6_addr, 0,
538                            sizeof(client.sa_in6.sin6_addr));
539                     client.sa_in6.sin6_addr.s6_addr[15] = 1;
540                 } else
541 #  endif
542                 if (client.sa.sa_family == AF_INET) {
543                     client.sa_in.sin_addr.s_addr = htonl(0x7F000001);
544                 } else
545                     goto err;
546             }
547             cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
548             if (cs != INVALID_SOCKET) {
549                 int ii;
550                 ii = connect(cs, &client.sa, addrlen);
551                 closesocket(cs);
552                 if (ii == INVALID_SOCKET) {
553                     bind_mode = BIO_BIND_REUSEADDR;
554                     closesocket(s);
555                     goto again;
556                 }
557                 /* else error */
558             }
559             /* else error */
560         }
561 # endif
562         SYSerr(SYS_F_BIND, err_num);
563         ERR_add_error_data(3, "port='", host, "'");
564         BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET);
565         goto err;
566     }
567     if (listen(s, MAX_LISTEN) == -1) {
568         SYSerr(SYS_F_BIND, get_last_socket_error());
569         ERR_add_error_data(3, "port='", host, "'");
570         BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET);
571         goto err;
572     }
573     ret = 1;
574  err:
575     if (str != NULL)
576         OPENSSL_free(str);
577     if ((ret == 0) && (s != INVALID_SOCKET)) {
578         closesocket(s);
579         s = INVALID_SOCKET;
580     }
581     return (s);
582 }
583
584 int BIO_accept(int sock, char **addr)
585 {
586     int ret = INVALID_SOCKET;
587     unsigned long l;
588     unsigned short port;
589     char *p;
590
591     struct {
592         /*
593          * As for following union. Trouble is that there are platforms
594          * that have socklen_t and there are platforms that don't, on
595          * some platforms socklen_t is int and on some size_t. So what
596          * one can do? One can cook #ifdef spaghetti, which is nothing
597          * but masochistic. Or one can do union between int and size_t.
598          * One naturally does it primarily for 64-bit platforms where
599          * sizeof(int) != sizeof(size_t). But would it work? Note that
600          * if size_t member is initialized to 0, then later int member
601          * assignment naturally does the job on little-endian platforms
602          * regardless accept's expectations! What about big-endians?
603          * If accept expects int*, then it works, and if size_t*, then
604          * length value would appear as unreasonably large. But this
605          * won't prevent it from filling in the address structure. The
606          * trouble of course would be if accept returns more data than
607          * actual buffer can accomodate and overwrite stack... That's
608          * where early OPENSSL_assert comes into picture. Besides, the
609          * only 64-bit big-endian platform found so far that expects
610          * size_t* is HP-UX, where stack grows towards higher address.
611          * <appro>
612          */
613         union {
614             size_t s;
615             int i;
616         } len;
617         union {
618             struct sockaddr sa;
619             struct sockaddr_in sa_in;
620 # if OPENSSL_USE_IPV6
621             struct sockaddr_in6 sa_in6;
622 # endif
623         } from;
624     } sa;
625
626     sa.len.s = 0;
627     sa.len.i = sizeof(sa.from);
628     memset(&sa.from, 0, sizeof(sa.from));
629     ret = accept(sock, &sa.from.sa, (void *)&sa.len);
630     if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) {
631         OPENSSL_assert(sa.len.s <= sizeof(sa.from));
632         sa.len.i = (int)sa.len.s;
633         /* use sa.len.i from this point */
634     }
635     if (ret == INVALID_SOCKET) {
636         if (BIO_sock_should_retry(ret))
637             return -2;
638         SYSerr(SYS_F_ACCEPT, get_last_socket_error());
639         BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
640         goto end;
641     }
642
643     if (addr == NULL)
644         goto end;
645
646 # ifdef EAI_FAMILY
647     do {
648         char h[NI_MAXHOST], s[NI_MAXSERV];
649         size_t nl;
650         static union {
651             void *p;
652             int (WSAAPI *f) (const struct sockaddr *, size_t /* socklen_t */ ,
653                              char *, size_t, char *, size_t, int);
654         } p_getnameinfo = {
655             NULL
656         };
657         /*
658          * 2nd argument to getnameinfo is specified to be socklen_t.
659          * Unfortunately there is a number of environments where socklen_t is
660          * not defined. As it's passed by value, it's safe to pass it as
661          * size_t... <appro>
662          */
663
664         if (p_getnameinfo.p == NULL) {
665             if ((p_getnameinfo.p = DSO_global_lookup("getnameinfo")) == NULL)
666                 p_getnameinfo.p = (void *)-1;
667         }
668         if (p_getnameinfo.p == (void *)-1)
669             break;
670
671         if ((*p_getnameinfo.f) (&sa.from.sa, sa.len.i, h, sizeof(h), s,
672                                 sizeof(s), NI_NUMERICHOST | NI_NUMERICSERV))
673             break;
674         nl = strlen(h) + strlen(s) + 2;
675         p = *addr;
676         if (p) {
677             *p = '\0';
678             p = OPENSSL_realloc(p, nl);
679         } else {
680             p = OPENSSL_malloc(nl);
681         }
682         if (p == NULL) {
683             BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
684             goto end;
685         }
686         *addr = p;
687         BIO_snprintf(*addr, nl, "%s:%s", h, s);
688         goto end;
689     } while (0);
690 # endif
691     if (sa.from.sa.sa_family != AF_INET)
692         goto end;
693     l = ntohl(sa.from.sa_in.sin_addr.s_addr);
694     port = ntohs(sa.from.sa_in.sin_port);
695     if (*addr == NULL) {
696         if ((p = OPENSSL_malloc(24)) == NULL) {
697             BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
698             goto end;
699         }
700         *addr = p;
701     }
702     BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d",
703                  (unsigned char)(l >> 24L) & 0xff,
704                  (unsigned char)(l >> 16L) & 0xff,
705                  (unsigned char)(l >> 8L) & 0xff,
706                  (unsigned char)(l) & 0xff, port);
707  end:
708     return (ret);
709 }
710
711 int BIO_set_tcp_ndelay(int s, int on)
712 {
713     int ret = 0;
714 # if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
715     int opt;
716
717 #  ifdef SOL_TCP
718     opt = SOL_TCP;
719 #  else
720 #   ifdef IPPROTO_TCP
721     opt = IPPROTO_TCP;
722 #   endif
723 #  endif
724
725     ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
726 # endif
727     return (ret == 0);
728 }
729
730 int BIO_socket_nbio(int s, int mode)
731 {
732     int ret = -1;
733     int l;
734
735     l = mode;
736 # ifdef FIONBIO
737     ret = BIO_socket_ioctl(s, FIONBIO, &l);
738 # endif
739     return (ret == 0);
740 }
741 #endif