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