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