xref: /onnv-gate/usr/src/common/openssl/crypto/bio/b_sock.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/bio/b_sock.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <stdlib.h>
610Sstevel@tonic-gate #include <errno.h>
620Sstevel@tonic-gate #define USE_SOCKETS
630Sstevel@tonic-gate #include "cryptlib.h"
640Sstevel@tonic-gate #include <openssl/bio.h>
65*2139Sjp161948 #if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
66*2139Sjp161948 #include "netdb.h"
67*2139Sjp161948 #endif
68*2139Sjp161948 
69*2139Sjp161948 #ifndef OPENSSL_NO_SOCK
700Sstevel@tonic-gate 
710Sstevel@tonic-gate #ifdef OPENSSL_SYS_WIN16
720Sstevel@tonic-gate #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
730Sstevel@tonic-gate #else
740Sstevel@tonic-gate #define SOCKET_PROTOCOL IPPROTO_TCP
750Sstevel@tonic-gate #endif
760Sstevel@tonic-gate 
770Sstevel@tonic-gate #ifdef SO_MAXCONN
780Sstevel@tonic-gate #define MAX_LISTEN  SO_MAXCONN
790Sstevel@tonic-gate #elif defined(SOMAXCONN)
800Sstevel@tonic-gate #define MAX_LISTEN  SOMAXCONN
810Sstevel@tonic-gate #else
820Sstevel@tonic-gate #define MAX_LISTEN  32
830Sstevel@tonic-gate #endif
840Sstevel@tonic-gate 
85*2139Sjp161948 #if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
860Sstevel@tonic-gate static int wsa_init_done=0;
870Sstevel@tonic-gate #endif
880Sstevel@tonic-gate 
890Sstevel@tonic-gate #if 0
900Sstevel@tonic-gate static unsigned long BIO_ghbn_hits=0L;
910Sstevel@tonic-gate static unsigned long BIO_ghbn_miss=0L;
920Sstevel@tonic-gate 
930Sstevel@tonic-gate #define GHBN_NUM	4
940Sstevel@tonic-gate static struct ghbn_cache_st
950Sstevel@tonic-gate 	{
960Sstevel@tonic-gate 	char name[129];
970Sstevel@tonic-gate 	struct hostent *ent;
980Sstevel@tonic-gate 	unsigned long order;
990Sstevel@tonic-gate 	} ghbn_cache[GHBN_NUM];
1000Sstevel@tonic-gate #endif
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate static int get_ip(const char *str,unsigned char *ip);
1030Sstevel@tonic-gate #if 0
1040Sstevel@tonic-gate static void ghbn_free(struct hostent *a);
1050Sstevel@tonic-gate static struct hostent *ghbn_dup(struct hostent *a);
1060Sstevel@tonic-gate #endif
BIO_get_host_ip(const char * str,unsigned char * ip)1070Sstevel@tonic-gate int BIO_get_host_ip(const char *str, unsigned char *ip)
1080Sstevel@tonic-gate 	{
1090Sstevel@tonic-gate 	int i;
1100Sstevel@tonic-gate 	int err = 1;
1110Sstevel@tonic-gate 	int locked = 0;
1120Sstevel@tonic-gate 	struct hostent *he;
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate 	i=get_ip(str,ip);
1150Sstevel@tonic-gate 	if (i < 0)
1160Sstevel@tonic-gate 		{
1170Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
1180Sstevel@tonic-gate 		goto err;
1190Sstevel@tonic-gate 		}
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	/* At this point, we have something that is most probably correct
1220Sstevel@tonic-gate 	   in some way, so let's init the socket. */
1230Sstevel@tonic-gate 	if (BIO_sock_init() != 1)
1240Sstevel@tonic-gate 		return 0; /* don't generate another error code here */
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 	/* If the string actually contained an IP address, we need not do
1270Sstevel@tonic-gate 	   anything more */
1280Sstevel@tonic-gate 	if (i > 0) return(1);
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	/* do a gethostbyname */
1310Sstevel@tonic-gate 	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
1320Sstevel@tonic-gate 	locked = 1;
1330Sstevel@tonic-gate 	he=BIO_gethostbyname(str);
1340Sstevel@tonic-gate 	if (he == NULL)
1350Sstevel@tonic-gate 		{
1360Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
1370Sstevel@tonic-gate 		goto err;
1380Sstevel@tonic-gate 		}
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	/* cast to short because of win16 winsock definition */
1410Sstevel@tonic-gate 	if ((short)he->h_addrtype != AF_INET)
1420Sstevel@tonic-gate 		{
1430Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
1440Sstevel@tonic-gate 		goto err;
1450Sstevel@tonic-gate 		}
1460Sstevel@tonic-gate 	for (i=0; i<4; i++)
1470Sstevel@tonic-gate 		ip[i]=he->h_addr_list[0][i];
1480Sstevel@tonic-gate 	err = 0;
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate  err:
1510Sstevel@tonic-gate 	if (locked)
1520Sstevel@tonic-gate 		CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
1530Sstevel@tonic-gate 	if (err)
1540Sstevel@tonic-gate 		{
1550Sstevel@tonic-gate 		ERR_add_error_data(2,"host=",str);
1560Sstevel@tonic-gate 		return 0;
1570Sstevel@tonic-gate 		}
1580Sstevel@tonic-gate 	else
1590Sstevel@tonic-gate 		return 1;
1600Sstevel@tonic-gate 	}
1610Sstevel@tonic-gate 
BIO_get_port(const char * str,unsigned short * port_ptr)1620Sstevel@tonic-gate int BIO_get_port(const char *str, unsigned short *port_ptr)
1630Sstevel@tonic-gate 	{
1640Sstevel@tonic-gate 	int i;
1650Sstevel@tonic-gate 	struct servent *s;
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 	if (str == NULL)
1680Sstevel@tonic-gate 		{
1690Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
1700Sstevel@tonic-gate 		return(0);
1710Sstevel@tonic-gate 		}
1720Sstevel@tonic-gate 	i=atoi(str);
1730Sstevel@tonic-gate 	if (i != 0)
1740Sstevel@tonic-gate 		*port_ptr=(unsigned short)i;
1750Sstevel@tonic-gate 	else
1760Sstevel@tonic-gate 		{
1770Sstevel@tonic-gate 		CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
1780Sstevel@tonic-gate 		/* Note: under VMS with SOCKETSHR, it seems like the first
1790Sstevel@tonic-gate 		 * parameter is 'char *', instead of 'const char *'
1800Sstevel@tonic-gate 		 */
1810Sstevel@tonic-gate  		s=getservbyname(
1820Sstevel@tonic-gate #ifndef CONST_STRICT
1830Sstevel@tonic-gate 		    (char *)
1840Sstevel@tonic-gate #endif
1850Sstevel@tonic-gate 		    str,"tcp");
1860Sstevel@tonic-gate 		if(s != NULL)
1870Sstevel@tonic-gate 			*port_ptr=ntohs((unsigned short)s->s_port);
1880Sstevel@tonic-gate 		CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
1890Sstevel@tonic-gate 		if(s == NULL)
1900Sstevel@tonic-gate 			{
1910Sstevel@tonic-gate 			if (strcmp(str,"http") == 0)
1920Sstevel@tonic-gate 				*port_ptr=80;
1930Sstevel@tonic-gate 			else if (strcmp(str,"telnet") == 0)
1940Sstevel@tonic-gate 				*port_ptr=23;
1950Sstevel@tonic-gate 			else if (strcmp(str,"socks") == 0)
1960Sstevel@tonic-gate 				*port_ptr=1080;
1970Sstevel@tonic-gate 			else if (strcmp(str,"https") == 0)
1980Sstevel@tonic-gate 				*port_ptr=443;
1990Sstevel@tonic-gate 			else if (strcmp(str,"ssl") == 0)
2000Sstevel@tonic-gate 				*port_ptr=443;
2010Sstevel@tonic-gate 			else if (strcmp(str,"ftp") == 0)
2020Sstevel@tonic-gate 				*port_ptr=21;
2030Sstevel@tonic-gate 			else if (strcmp(str,"gopher") == 0)
2040Sstevel@tonic-gate 				*port_ptr=70;
2050Sstevel@tonic-gate #if 0
2060Sstevel@tonic-gate 			else if (strcmp(str,"wais") == 0)
2070Sstevel@tonic-gate 				*port_ptr=21;
2080Sstevel@tonic-gate #endif
2090Sstevel@tonic-gate 			else
2100Sstevel@tonic-gate 				{
2110Sstevel@tonic-gate 				SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
2120Sstevel@tonic-gate 				ERR_add_error_data(3,"service='",str,"'");
2130Sstevel@tonic-gate 				return(0);
2140Sstevel@tonic-gate 				}
2150Sstevel@tonic-gate 			}
2160Sstevel@tonic-gate 		}
2170Sstevel@tonic-gate 	return(1);
2180Sstevel@tonic-gate 	}
2190Sstevel@tonic-gate 
BIO_sock_error(int sock)2200Sstevel@tonic-gate int BIO_sock_error(int sock)
2210Sstevel@tonic-gate 	{
2220Sstevel@tonic-gate 	int j,i;
2230Sstevel@tonic-gate 	int size;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	size=sizeof(int);
2260Sstevel@tonic-gate 	/* Note: under Windows the third parameter is of type (char *)
2270Sstevel@tonic-gate 	 * whereas under other systems it is (void *) if you don't have
2280Sstevel@tonic-gate 	 * a cast it will choke the compiler: if you do have a cast then
2290Sstevel@tonic-gate 	 * you can either go for (char *) or (void *).
2300Sstevel@tonic-gate 	 */
2310Sstevel@tonic-gate 	i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
2320Sstevel@tonic-gate 	if (i < 0)
2330Sstevel@tonic-gate 		return(1);
2340Sstevel@tonic-gate 	else
2350Sstevel@tonic-gate 		return(j);
2360Sstevel@tonic-gate 	}
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate #if 0
2390Sstevel@tonic-gate long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
2400Sstevel@tonic-gate 	{
2410Sstevel@tonic-gate 	int i;
2420Sstevel@tonic-gate 	char **p;
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate 	switch (cmd)
2450Sstevel@tonic-gate 		{
2460Sstevel@tonic-gate 	case BIO_GHBN_CTRL_HITS:
2470Sstevel@tonic-gate 		return(BIO_ghbn_hits);
2480Sstevel@tonic-gate 		/* break; */
2490Sstevel@tonic-gate 	case BIO_GHBN_CTRL_MISSES:
2500Sstevel@tonic-gate 		return(BIO_ghbn_miss);
2510Sstevel@tonic-gate 		/* break; */
2520Sstevel@tonic-gate 	case BIO_GHBN_CTRL_CACHE_SIZE:
2530Sstevel@tonic-gate 		return(GHBN_NUM);
2540Sstevel@tonic-gate 		/* break; */
2550Sstevel@tonic-gate 	case BIO_GHBN_CTRL_GET_ENTRY:
2560Sstevel@tonic-gate 		if ((iarg >= 0) && (iarg <GHBN_NUM) &&
2570Sstevel@tonic-gate 			(ghbn_cache[iarg].order > 0))
2580Sstevel@tonic-gate 			{
2590Sstevel@tonic-gate 			p=(char **)parg;
2600Sstevel@tonic-gate 			if (p == NULL) return(0);
2610Sstevel@tonic-gate 			*p=ghbn_cache[iarg].name;
2620Sstevel@tonic-gate 			ghbn_cache[iarg].name[128]='\0';
2630Sstevel@tonic-gate 			return(1);
2640Sstevel@tonic-gate 			}
2650Sstevel@tonic-gate 		return(0);
2660Sstevel@tonic-gate 		/* break; */
2670Sstevel@tonic-gate 	case BIO_GHBN_CTRL_FLUSH:
2680Sstevel@tonic-gate 		for (i=0; i<GHBN_NUM; i++)
2690Sstevel@tonic-gate 			ghbn_cache[i].order=0;
2700Sstevel@tonic-gate 		break;
2710Sstevel@tonic-gate 	default:
2720Sstevel@tonic-gate 		return(0);
2730Sstevel@tonic-gate 		}
2740Sstevel@tonic-gate 	return(1);
2750Sstevel@tonic-gate 	}
2760Sstevel@tonic-gate #endif
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate #if 0
2790Sstevel@tonic-gate static struct hostent *ghbn_dup(struct hostent *a)
2800Sstevel@tonic-gate 	{
2810Sstevel@tonic-gate 	struct hostent *ret;
2820Sstevel@tonic-gate 	int i,j;
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	MemCheck_off();
2850Sstevel@tonic-gate 	ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
2860Sstevel@tonic-gate 	if (ret == NULL) return(NULL);
2870Sstevel@tonic-gate 	memset(ret,0,sizeof(struct hostent));
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate 	for (i=0; a->h_aliases[i] != NULL; i++)
2900Sstevel@tonic-gate 		;
2910Sstevel@tonic-gate 	i++;
2920Sstevel@tonic-gate 	ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
2930Sstevel@tonic-gate 	if (ret->h_aliases == NULL)
2940Sstevel@tonic-gate 		goto err;
2950Sstevel@tonic-gate 	memset(ret->h_aliases, 0, i*sizeof(char *));
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	for (i=0; a->h_addr_list[i] != NULL; i++)
2980Sstevel@tonic-gate 		;
2990Sstevel@tonic-gate 	i++;
3000Sstevel@tonic-gate 	ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
3010Sstevel@tonic-gate 	if (ret->h_addr_list == NULL)
3020Sstevel@tonic-gate 		goto err;
3030Sstevel@tonic-gate 	memset(ret->h_addr_list, 0, i*sizeof(char *));
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 	j=strlen(a->h_name)+1;
3060Sstevel@tonic-gate 	if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
3070Sstevel@tonic-gate 	memcpy((char *)ret->h_name,a->h_name,j);
3080Sstevel@tonic-gate 	for (i=0; a->h_aliases[i] != NULL; i++)
3090Sstevel@tonic-gate 		{
3100Sstevel@tonic-gate 		j=strlen(a->h_aliases[i])+1;
3110Sstevel@tonic-gate 		if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
3120Sstevel@tonic-gate 		memcpy(ret->h_aliases[i],a->h_aliases[i],j);
3130Sstevel@tonic-gate 		}
3140Sstevel@tonic-gate 	ret->h_length=a->h_length;
3150Sstevel@tonic-gate 	ret->h_addrtype=a->h_addrtype;
3160Sstevel@tonic-gate 	for (i=0; a->h_addr_list[i] != NULL; i++)
3170Sstevel@tonic-gate 		{
3180Sstevel@tonic-gate 		if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
3190Sstevel@tonic-gate 			goto err;
3200Sstevel@tonic-gate 		memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
3210Sstevel@tonic-gate 		}
3220Sstevel@tonic-gate 	if (0)
3230Sstevel@tonic-gate 		{
3240Sstevel@tonic-gate err:
3250Sstevel@tonic-gate 		if (ret != NULL)
3260Sstevel@tonic-gate 			ghbn_free(ret);
3270Sstevel@tonic-gate 		ret=NULL;
3280Sstevel@tonic-gate 		}
3290Sstevel@tonic-gate 	MemCheck_on();
3300Sstevel@tonic-gate 	return(ret);
3310Sstevel@tonic-gate 	}
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate static void ghbn_free(struct hostent *a)
3340Sstevel@tonic-gate 	{
3350Sstevel@tonic-gate 	int i;
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 	if(a == NULL)
3380Sstevel@tonic-gate 	    return;
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	if (a->h_aliases != NULL)
3410Sstevel@tonic-gate 		{
3420Sstevel@tonic-gate 		for (i=0; a->h_aliases[i] != NULL; i++)
3430Sstevel@tonic-gate 			OPENSSL_free(a->h_aliases[i]);
3440Sstevel@tonic-gate 		OPENSSL_free(a->h_aliases);
3450Sstevel@tonic-gate 		}
3460Sstevel@tonic-gate 	if (a->h_addr_list != NULL)
3470Sstevel@tonic-gate 		{
3480Sstevel@tonic-gate 		for (i=0; a->h_addr_list[i] != NULL; i++)
3490Sstevel@tonic-gate 			OPENSSL_free(a->h_addr_list[i]);
3500Sstevel@tonic-gate 		OPENSSL_free(a->h_addr_list);
3510Sstevel@tonic-gate 		}
3520Sstevel@tonic-gate 	if (a->h_name != NULL) OPENSSL_free(a->h_name);
3530Sstevel@tonic-gate 	OPENSSL_free(a);
3540Sstevel@tonic-gate 	}
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate #endif
3570Sstevel@tonic-gate 
BIO_gethostbyname(const char * name)3580Sstevel@tonic-gate struct hostent *BIO_gethostbyname(const char *name)
3590Sstevel@tonic-gate 	{
3600Sstevel@tonic-gate #if 1
3610Sstevel@tonic-gate 	/* Caching gethostbyname() results forever is wrong,
3620Sstevel@tonic-gate 	 * so we have to let the true gethostbyname() worry about this */
3630Sstevel@tonic-gate 	return gethostbyname(name);
3640Sstevel@tonic-gate #else
3650Sstevel@tonic-gate 	struct hostent *ret;
3660Sstevel@tonic-gate 	int i,lowi=0,j;
3670Sstevel@tonic-gate 	unsigned long low= (unsigned long)-1;
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate #  if 0
3710Sstevel@tonic-gate 	/* It doesn't make sense to use locking here: The function interface
3720Sstevel@tonic-gate 	 * is not thread-safe, because threads can never be sure when
3730Sstevel@tonic-gate 	 * some other thread destroys the data they were given a pointer to.
3740Sstevel@tonic-gate 	 */
3750Sstevel@tonic-gate 	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
3760Sstevel@tonic-gate #  endif
3770Sstevel@tonic-gate 	j=strlen(name);
3780Sstevel@tonic-gate 	if (j < 128)
3790Sstevel@tonic-gate 		{
3800Sstevel@tonic-gate 		for (i=0; i<GHBN_NUM; i++)
3810Sstevel@tonic-gate 			{
3820Sstevel@tonic-gate 			if (low > ghbn_cache[i].order)
3830Sstevel@tonic-gate 				{
3840Sstevel@tonic-gate 				low=ghbn_cache[i].order;
3850Sstevel@tonic-gate 				lowi=i;
3860Sstevel@tonic-gate 				}
3870Sstevel@tonic-gate 			if (ghbn_cache[i].order > 0)
3880Sstevel@tonic-gate 				{
3890Sstevel@tonic-gate 				if (strncmp(name,ghbn_cache[i].name,128) == 0)
3900Sstevel@tonic-gate 					break;
3910Sstevel@tonic-gate 				}
3920Sstevel@tonic-gate 			}
3930Sstevel@tonic-gate 		}
3940Sstevel@tonic-gate 	else
3950Sstevel@tonic-gate 		i=GHBN_NUM;
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	if (i == GHBN_NUM) /* no hit*/
3980Sstevel@tonic-gate 		{
3990Sstevel@tonic-gate 		BIO_ghbn_miss++;
4000Sstevel@tonic-gate 		/* Note: under VMS with SOCKETSHR, it seems like the first
4010Sstevel@tonic-gate 		 * parameter is 'char *', instead of 'const char *'
4020Sstevel@tonic-gate 		 */
4030Sstevel@tonic-gate 		ret=gethostbyname(
4040Sstevel@tonic-gate #  ifndef CONST_STRICT
4050Sstevel@tonic-gate 		    (char *)
4060Sstevel@tonic-gate #  endif
4070Sstevel@tonic-gate 		    name);
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 		if (ret == NULL)
4100Sstevel@tonic-gate 			goto end;
4110Sstevel@tonic-gate 		if (j > 128) /* too big to cache */
4120Sstevel@tonic-gate 			{
4130Sstevel@tonic-gate #  if 0
4140Sstevel@tonic-gate 			/* If we were trying to make this function thread-safe (which
4150Sstevel@tonic-gate 			 * is bound to fail), we'd have to give up in this case
4160Sstevel@tonic-gate 			 * (or allocate more memory). */
4170Sstevel@tonic-gate 			ret = NULL;
4180Sstevel@tonic-gate #  endif
4190Sstevel@tonic-gate 			goto end;
4200Sstevel@tonic-gate 			}
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 		/* else add to cache */
4230Sstevel@tonic-gate 		if (ghbn_cache[lowi].ent != NULL)
4240Sstevel@tonic-gate 			ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
4250Sstevel@tonic-gate 		ghbn_cache[lowi].name[0] = '\0';
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 		if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
4280Sstevel@tonic-gate 			{
4290Sstevel@tonic-gate 			BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
4300Sstevel@tonic-gate 			goto end;
4310Sstevel@tonic-gate 			}
4320Sstevel@tonic-gate 		strncpy(ghbn_cache[lowi].name,name,128);
4330Sstevel@tonic-gate 		ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
4340Sstevel@tonic-gate 		}
4350Sstevel@tonic-gate 	else
4360Sstevel@tonic-gate 		{
4370Sstevel@tonic-gate 		BIO_ghbn_hits++;
4380Sstevel@tonic-gate 		ret= ghbn_cache[i].ent;
4390Sstevel@tonic-gate 		ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
4400Sstevel@tonic-gate 		}
4410Sstevel@tonic-gate end:
4420Sstevel@tonic-gate #  if 0
4430Sstevel@tonic-gate 	CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
4440Sstevel@tonic-gate #  endif
4450Sstevel@tonic-gate 	return(ret);
4460Sstevel@tonic-gate #endif
4470Sstevel@tonic-gate 	}
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 
BIO_sock_init(void)4500Sstevel@tonic-gate int BIO_sock_init(void)
4510Sstevel@tonic-gate 	{
4520Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINDOWS
4530Sstevel@tonic-gate 	static struct WSAData wsa_state;
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate 	if (!wsa_init_done)
4560Sstevel@tonic-gate 		{
4570Sstevel@tonic-gate 		int err;
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate #ifdef SIGINT
4600Sstevel@tonic-gate 		signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
4610Sstevel@tonic-gate #endif
4620Sstevel@tonic-gate 		wsa_init_done=1;
4630Sstevel@tonic-gate 		memset(&wsa_state,0,sizeof(wsa_state));
4640Sstevel@tonic-gate 		if (WSAStartup(0x0101,&wsa_state)!=0)
4650Sstevel@tonic-gate 			{
4660Sstevel@tonic-gate 			err=WSAGetLastError();
4670Sstevel@tonic-gate 			SYSerr(SYS_F_WSASTARTUP,err);
4680Sstevel@tonic-gate 			BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
4690Sstevel@tonic-gate 			return(-1);
4700Sstevel@tonic-gate 			}
4710Sstevel@tonic-gate 		}
4720Sstevel@tonic-gate #endif /* OPENSSL_SYS_WINDOWS */
4730Sstevel@tonic-gate #ifdef WATT32
4740Sstevel@tonic-gate 	extern int _watt_do_exit;
4750Sstevel@tonic-gate 	_watt_do_exit = 0;    /* don't make sock_init() call exit() */
4760Sstevel@tonic-gate 	if (sock_init())
4770Sstevel@tonic-gate 		return (-1);
4780Sstevel@tonic-gate #endif
479*2139Sjp161948 
480*2139Sjp161948 #if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
481*2139Sjp161948     WORD wVerReq;
482*2139Sjp161948     WSADATA wsaData;
483*2139Sjp161948     int err;
484*2139Sjp161948 
485*2139Sjp161948     if (!wsa_init_done)
486*2139Sjp161948     {
487*2139Sjp161948 
488*2139Sjp161948 # ifdef SIGINT
489*2139Sjp161948         signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
490*2139Sjp161948 # endif
491*2139Sjp161948 
492*2139Sjp161948         wsa_init_done=1;
493*2139Sjp161948         wVerReq = MAKEWORD( 2, 0 );
494*2139Sjp161948         err = WSAStartup(wVerReq,&wsaData);
495*2139Sjp161948         if (err != 0)
496*2139Sjp161948         {
497*2139Sjp161948             SYSerr(SYS_F_WSASTARTUP,err);
498*2139Sjp161948             BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
499*2139Sjp161948             return(-1);
500*2139Sjp161948 			}
501*2139Sjp161948 		}
502*2139Sjp161948 #endif
503*2139Sjp161948 
5040Sstevel@tonic-gate 	return(1);
5050Sstevel@tonic-gate 	}
5060Sstevel@tonic-gate 
BIO_sock_cleanup(void)5070Sstevel@tonic-gate void BIO_sock_cleanup(void)
5080Sstevel@tonic-gate 	{
5090Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINDOWS
5100Sstevel@tonic-gate 	if (wsa_init_done)
5110Sstevel@tonic-gate 		{
5120Sstevel@tonic-gate 		wsa_init_done=0;
5130Sstevel@tonic-gate #ifndef OPENSSL_SYS_WINCE
5140Sstevel@tonic-gate 		WSACancelBlockingCall();
5150Sstevel@tonic-gate #endif
5160Sstevel@tonic-gate 		WSACleanup();
5170Sstevel@tonic-gate 		}
518*2139Sjp161948 #elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
519*2139Sjp161948    if (wsa_init_done)
520*2139Sjp161948         {
521*2139Sjp161948         wsa_init_done=0;
522*2139Sjp161948         WSACleanup();
523*2139Sjp161948 		}
5240Sstevel@tonic-gate #endif
5250Sstevel@tonic-gate 	}
5260Sstevel@tonic-gate 
5270Sstevel@tonic-gate #if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
5280Sstevel@tonic-gate 
BIO_socket_ioctl(int fd,long type,void * arg)5290Sstevel@tonic-gate int BIO_socket_ioctl(int fd, long type, void *arg)
5300Sstevel@tonic-gate 	{
5310Sstevel@tonic-gate 	int i;
5320Sstevel@tonic-gate 
5330Sstevel@tonic-gate #ifdef __DJGPP__
5340Sstevel@tonic-gate 	i=ioctlsocket(fd,type,(char *)arg);
5350Sstevel@tonic-gate #else
5360Sstevel@tonic-gate 	i=ioctlsocket(fd,type,arg);
5370Sstevel@tonic-gate #endif /* __DJGPP__ */
5380Sstevel@tonic-gate 	if (i < 0)
5390Sstevel@tonic-gate 		SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
5400Sstevel@tonic-gate 	return(i);
5410Sstevel@tonic-gate 	}
5420Sstevel@tonic-gate #endif /* __VMS_VER */
5430Sstevel@tonic-gate 
5440Sstevel@tonic-gate /* The reason I have implemented this instead of using sscanf is because
5450Sstevel@tonic-gate  * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
get_ip(const char * str,unsigned char ip[4])5460Sstevel@tonic-gate static int get_ip(const char *str, unsigned char ip[4])
5470Sstevel@tonic-gate 	{
5480Sstevel@tonic-gate 	unsigned int tmp[4];
5490Sstevel@tonic-gate 	int num=0,c,ok=0;
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 	tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
5520Sstevel@tonic-gate 
5530Sstevel@tonic-gate 	for (;;)
5540Sstevel@tonic-gate 		{
5550Sstevel@tonic-gate 		c= *(str++);
5560Sstevel@tonic-gate 		if ((c >= '0') && (c <= '9'))
5570Sstevel@tonic-gate 			{
5580Sstevel@tonic-gate 			ok=1;
5590Sstevel@tonic-gate 			tmp[num]=tmp[num]*10+c-'0';
5600Sstevel@tonic-gate 			if (tmp[num] > 255) return(0);
5610Sstevel@tonic-gate 			}
5620Sstevel@tonic-gate 		else if (c == '.')
5630Sstevel@tonic-gate 			{
5640Sstevel@tonic-gate 			if (!ok) return(-1);
5650Sstevel@tonic-gate 			if (num == 3) return(0);
5660Sstevel@tonic-gate 			num++;
5670Sstevel@tonic-gate 			ok=0;
5680Sstevel@tonic-gate 			}
5690Sstevel@tonic-gate 		else if (c == '\0' && (num == 3) && ok)
5700Sstevel@tonic-gate 			break;
5710Sstevel@tonic-gate 		else
5720Sstevel@tonic-gate 			return(0);
5730Sstevel@tonic-gate 		}
5740Sstevel@tonic-gate 	ip[0]=tmp[0];
5750Sstevel@tonic-gate 	ip[1]=tmp[1];
5760Sstevel@tonic-gate 	ip[2]=tmp[2];
5770Sstevel@tonic-gate 	ip[3]=tmp[3];
5780Sstevel@tonic-gate 	return(1);
5790Sstevel@tonic-gate 	}
5800Sstevel@tonic-gate 
BIO_get_accept_socket(char * host,int bind_mode)5810Sstevel@tonic-gate int BIO_get_accept_socket(char *host, int bind_mode)
5820Sstevel@tonic-gate 	{
5830Sstevel@tonic-gate 	int ret=0;
5840Sstevel@tonic-gate 	struct sockaddr_in server,client;
5850Sstevel@tonic-gate 	int s=INVALID_SOCKET,cs;
5860Sstevel@tonic-gate 	unsigned char ip[4];
5870Sstevel@tonic-gate 	unsigned short port;
5880Sstevel@tonic-gate 	char *str=NULL,*e;
5890Sstevel@tonic-gate 	const char *h,*p;
5900Sstevel@tonic-gate 	unsigned long l;
5910Sstevel@tonic-gate 	int err_num;
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 	if (BIO_sock_init() != 1) return(INVALID_SOCKET);
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 	if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate 	h=p=NULL;
5980Sstevel@tonic-gate 	h=str;
5990Sstevel@tonic-gate 	for (e=str; *e; e++)
6000Sstevel@tonic-gate 		{
6010Sstevel@tonic-gate 		if (*e == ':')
6020Sstevel@tonic-gate 			{
6030Sstevel@tonic-gate 			p= &(e[1]);
6040Sstevel@tonic-gate 			*e='\0';
6050Sstevel@tonic-gate 			}
6060Sstevel@tonic-gate 		else if (*e == '/')
6070Sstevel@tonic-gate 			{
6080Sstevel@tonic-gate 			*e='\0';
6090Sstevel@tonic-gate 			break;
6100Sstevel@tonic-gate 			}
6110Sstevel@tonic-gate 		}
6120Sstevel@tonic-gate 
6130Sstevel@tonic-gate 	if (p == NULL)
6140Sstevel@tonic-gate 		{
6150Sstevel@tonic-gate 		p=h;
6160Sstevel@tonic-gate 		h="*";
6170Sstevel@tonic-gate 		}
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate 	if (!BIO_get_port(p,&port)) goto err;
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate 	memset((char *)&server,0,sizeof(server));
6220Sstevel@tonic-gate 	server.sin_family=AF_INET;
6230Sstevel@tonic-gate 	server.sin_port=htons(port);
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate 	if (strcmp(h,"*") == 0)
6260Sstevel@tonic-gate 		server.sin_addr.s_addr=INADDR_ANY;
6270Sstevel@tonic-gate 	else
6280Sstevel@tonic-gate 		{
6290Sstevel@tonic-gate                 if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
6300Sstevel@tonic-gate 		l=(unsigned long)
6310Sstevel@tonic-gate 			((unsigned long)ip[0]<<24L)|
6320Sstevel@tonic-gate 			((unsigned long)ip[1]<<16L)|
6330Sstevel@tonic-gate 			((unsigned long)ip[2]<< 8L)|
6340Sstevel@tonic-gate 			((unsigned long)ip[3]);
6350Sstevel@tonic-gate 		server.sin_addr.s_addr=htonl(l);
6360Sstevel@tonic-gate 		}
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate again:
6390Sstevel@tonic-gate 	s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
6400Sstevel@tonic-gate 	if (s == INVALID_SOCKET)
6410Sstevel@tonic-gate 		{
6420Sstevel@tonic-gate 		SYSerr(SYS_F_SOCKET,get_last_socket_error());
6430Sstevel@tonic-gate 		ERR_add_error_data(3,"port='",host,"'");
6440Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
6450Sstevel@tonic-gate 		goto err;
6460Sstevel@tonic-gate 		}
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate #ifdef SO_REUSEADDR
6490Sstevel@tonic-gate 	if (bind_mode == BIO_BIND_REUSEADDR)
6500Sstevel@tonic-gate 		{
6510Sstevel@tonic-gate 		int i=1;
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 		ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
6540Sstevel@tonic-gate 		bind_mode=BIO_BIND_NORMAL;
6550Sstevel@tonic-gate 		}
6560Sstevel@tonic-gate #endif
6570Sstevel@tonic-gate 	if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
6580Sstevel@tonic-gate 		{
6590Sstevel@tonic-gate #ifdef SO_REUSEADDR
6600Sstevel@tonic-gate 		err_num=get_last_socket_error();
6610Sstevel@tonic-gate 		if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
6620Sstevel@tonic-gate 			(err_num == EADDRINUSE))
6630Sstevel@tonic-gate 			{
6640Sstevel@tonic-gate 			memcpy((char *)&client,(char *)&server,sizeof(server));
6650Sstevel@tonic-gate 			if (strcmp(h,"*") == 0)
6660Sstevel@tonic-gate 				client.sin_addr.s_addr=htonl(0x7F000001);
6670Sstevel@tonic-gate 			cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
6680Sstevel@tonic-gate 			if (cs != INVALID_SOCKET)
6690Sstevel@tonic-gate 				{
6700Sstevel@tonic-gate 				int ii;
6710Sstevel@tonic-gate 				ii=connect(cs,(struct sockaddr *)&client,
6720Sstevel@tonic-gate 					sizeof(client));
6730Sstevel@tonic-gate 				closesocket(cs);
6740Sstevel@tonic-gate 				if (ii == INVALID_SOCKET)
6750Sstevel@tonic-gate 					{
6760Sstevel@tonic-gate 					bind_mode=BIO_BIND_REUSEADDR;
6770Sstevel@tonic-gate 					closesocket(s);
6780Sstevel@tonic-gate 					goto again;
6790Sstevel@tonic-gate 					}
6800Sstevel@tonic-gate 				/* else error */
6810Sstevel@tonic-gate 				}
6820Sstevel@tonic-gate 			/* else error */
6830Sstevel@tonic-gate 			}
6840Sstevel@tonic-gate #endif
6850Sstevel@tonic-gate 		SYSerr(SYS_F_BIND,err_num);
6860Sstevel@tonic-gate 		ERR_add_error_data(3,"port='",host,"'");
6870Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
6880Sstevel@tonic-gate 		goto err;
6890Sstevel@tonic-gate 		}
6900Sstevel@tonic-gate 	if (listen(s,MAX_LISTEN) == -1)
6910Sstevel@tonic-gate 		{
6920Sstevel@tonic-gate 		SYSerr(SYS_F_BIND,get_last_socket_error());
6930Sstevel@tonic-gate 		ERR_add_error_data(3,"port='",host,"'");
6940Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
6950Sstevel@tonic-gate 		goto err;
6960Sstevel@tonic-gate 		}
6970Sstevel@tonic-gate 	ret=1;
6980Sstevel@tonic-gate err:
6990Sstevel@tonic-gate 	if (str != NULL) OPENSSL_free(str);
7000Sstevel@tonic-gate 	if ((ret == 0) && (s != INVALID_SOCKET))
7010Sstevel@tonic-gate 		{
7020Sstevel@tonic-gate 		closesocket(s);
7030Sstevel@tonic-gate 		s= INVALID_SOCKET;
7040Sstevel@tonic-gate 		}
7050Sstevel@tonic-gate 	return(s);
7060Sstevel@tonic-gate 	}
7070Sstevel@tonic-gate 
BIO_accept(int sock,char ** addr)7080Sstevel@tonic-gate int BIO_accept(int sock, char **addr)
7090Sstevel@tonic-gate 	{
7100Sstevel@tonic-gate 	int ret=INVALID_SOCKET;
7110Sstevel@tonic-gate 	static struct sockaddr_in from;
7120Sstevel@tonic-gate 	unsigned long l;
7130Sstevel@tonic-gate 	unsigned short port;
7140Sstevel@tonic-gate 	int len;
7150Sstevel@tonic-gate 	char *p;
7160Sstevel@tonic-gate 
7170Sstevel@tonic-gate 	memset((char *)&from,0,sizeof(from));
7180Sstevel@tonic-gate 	len=sizeof(from);
7190Sstevel@tonic-gate 	/* Note: under VMS with SOCKETSHR the fourth parameter is currently
7200Sstevel@tonic-gate 	 * of type (int *) whereas under other systems it is (void *) if
7210Sstevel@tonic-gate 	 * you don't have a cast it will choke the compiler: if you do
7220Sstevel@tonic-gate 	 * have a cast then you can either go for (int *) or (void *).
7230Sstevel@tonic-gate 	 */
7240Sstevel@tonic-gate 	ret=accept(sock,(struct sockaddr *)&from,(void *)&len);
7250Sstevel@tonic-gate 	if (ret == INVALID_SOCKET)
7260Sstevel@tonic-gate 		{
7270Sstevel@tonic-gate 		if(BIO_sock_should_retry(ret)) return -2;
7280Sstevel@tonic-gate 		SYSerr(SYS_F_ACCEPT,get_last_socket_error());
7290Sstevel@tonic-gate 		BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
7300Sstevel@tonic-gate 		goto end;
7310Sstevel@tonic-gate 		}
7320Sstevel@tonic-gate 
7330Sstevel@tonic-gate 	if (addr == NULL) goto end;
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate 	l=ntohl(from.sin_addr.s_addr);
7360Sstevel@tonic-gate 	port=ntohs(from.sin_port);
7370Sstevel@tonic-gate 	if (*addr == NULL)
7380Sstevel@tonic-gate 		{
7390Sstevel@tonic-gate 		if ((p=OPENSSL_malloc(24)) == NULL)
7400Sstevel@tonic-gate 			{
7410Sstevel@tonic-gate 			BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
7420Sstevel@tonic-gate 			goto end;
7430Sstevel@tonic-gate 			}
7440Sstevel@tonic-gate 		*addr=p;
7450Sstevel@tonic-gate 		}
7460Sstevel@tonic-gate 	BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
7470Sstevel@tonic-gate 		     (unsigned char)(l>>24L)&0xff,
7480Sstevel@tonic-gate 		     (unsigned char)(l>>16L)&0xff,
7490Sstevel@tonic-gate 		     (unsigned char)(l>> 8L)&0xff,
7500Sstevel@tonic-gate 		     (unsigned char)(l     )&0xff,
7510Sstevel@tonic-gate 		     port);
7520Sstevel@tonic-gate end:
7530Sstevel@tonic-gate 	return(ret);
7540Sstevel@tonic-gate 	}
7550Sstevel@tonic-gate 
BIO_set_tcp_ndelay(int s,int on)7560Sstevel@tonic-gate int BIO_set_tcp_ndelay(int s, int on)
7570Sstevel@tonic-gate 	{
7580Sstevel@tonic-gate 	int ret=0;
7590Sstevel@tonic-gate #if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
7600Sstevel@tonic-gate 	int opt;
7610Sstevel@tonic-gate 
7620Sstevel@tonic-gate #ifdef SOL_TCP
7630Sstevel@tonic-gate 	opt=SOL_TCP;
7640Sstevel@tonic-gate #else
7650Sstevel@tonic-gate #ifdef IPPROTO_TCP
7660Sstevel@tonic-gate 	opt=IPPROTO_TCP;
7670Sstevel@tonic-gate #endif
7680Sstevel@tonic-gate #endif
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 	ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
7710Sstevel@tonic-gate #endif
7720Sstevel@tonic-gate 	return(ret == 0);
7730Sstevel@tonic-gate 	}
7740Sstevel@tonic-gate #endif
7750Sstevel@tonic-gate 
BIO_socket_nbio(int s,int mode)7760Sstevel@tonic-gate int BIO_socket_nbio(int s, int mode)
7770Sstevel@tonic-gate 	{
7780Sstevel@tonic-gate 	int ret= -1;
7790Sstevel@tonic-gate 	int l;
7800Sstevel@tonic-gate 
7810Sstevel@tonic-gate 	l=mode;
7820Sstevel@tonic-gate #ifdef FIONBIO
7830Sstevel@tonic-gate 	ret=BIO_socket_ioctl(s,FIONBIO,&l);
7840Sstevel@tonic-gate #endif
7850Sstevel@tonic-gate 	return(ret == 0);
7860Sstevel@tonic-gate 	}
787