/* crypto/bio/b_sock.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define USE_SOCKETS
#include "cryptlib.h"
#include <openssl/bio.h>
#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
#include <netdb.h>
#if defined(NETWARE_CLIB)
#include <sys/ioctl.h>
NETDB_DEFINE_CONTEXT
#endif
#endif

#ifndef OPENSSL_NO_SOCK

#include <openssl/dso.h>

#define SOCKET_PROTOCOL IPPROTO_TCP

#ifdef SO_MAXCONN
#define MAX_LISTEN  SO_MAXCONN
#elif defined(SOMAXCONN)
#define MAX_LISTEN  SOMAXCONN
#else
#define MAX_LISTEN  32
#endif

#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
static int wsa_init_done=0;
#endif

/*
 * WSAAPI specifier is required to make indirect calls to run-time
 * linked WinSock 2 functions used in this module, to be specific
 * [get|free]addrinfo and getnameinfo. This is because WinSock uses
 * uses non-C calling convention, __stdcall vs. __cdecl, on x86
 * Windows. On non-WinSock platforms WSAAPI needs to be void.
 */
#ifndef WSAAPI
#define WSAAPI
#endif

#if 0
static unsigned long BIO_ghbn_hits=0L;
static unsigned long BIO_ghbn_miss=0L;

#define GHBN_NUM	4
static struct ghbn_cache_st
	{
	char name[129];
	struct hostent *ent;
	unsigned long order;
	} ghbn_cache[GHBN_NUM];
#endif

static int get_ip(const char *str,unsigned char *ip);
#if 0
static void ghbn_free(struct hostent *a);
static struct hostent *ghbn_dup(struct hostent *a);
#endif
int BIO_get_host_ip(const char *str, unsigned char *ip)
	{
	int i;
	int err = 1;
	int locked = 0;
	struct hostent *he;

	i=get_ip(str,ip);
	if (i < 0)
		{
		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
		goto err;
		}

	/* At this point, we have something that is most probably correct
	   in some way, so let's init the socket. */
	if (BIO_sock_init() != 1)
		return 0; /* don't generate another error code here */

	/* If the string actually contained an IP address, we need not do
	   anything more */
	if (i > 0) return(1);

	/* do a gethostbyname */
	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
	locked = 1;
	he=BIO_gethostbyname(str);
	if (he == NULL)
		{
		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
		goto err;
		}

	/* cast to short because of win16 winsock definition */
	if ((short)he->h_addrtype != AF_INET)
		{
		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
		goto err;
		}
	for (i=0; i<4; i++)
		ip[i]=he->h_addr_list[0][i];
	err = 0;

 err:
	if (locked)
		CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
	if (err)
		{
		ERR_add_error_data(2,"host=",str);
		return 0;
		}
	else
		return 1;
	}

int BIO_get_port(const char *str, unsigned short *port_ptr)
	{
	int i;
	struct servent *s;

	if (str == NULL)
		{
		BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
		return(0);
		}
	i=atoi(str);
	if (i != 0)
		*port_ptr=(unsigned short)i;
	else
		{
		CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
		/* Note: under VMS with SOCKETSHR, it seems like the first
		 * parameter is 'char *', instead of 'const char *'
		 */
#ifndef CONST_STRICT
		s=getservbyname((char *)str,"tcp");
#else
		s=getservbyname(str,"tcp");
#endif
		if(s != NULL)
			*port_ptr=ntohs((unsigned short)s->s_port);
		CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
		if(s == NULL)
			{
			if (strcmp(str,"http") == 0)
				*port_ptr=80;
			else if (strcmp(str,"telnet") == 0)
				*port_ptr=23;
			else if (strcmp(str,"socks") == 0)
				*port_ptr=1080;
			else if (strcmp(str,"https") == 0)
				*port_ptr=443;
			else if (strcmp(str,"ssl") == 0)
				*port_ptr=443;
			else if (strcmp(str,"ftp") == 0)
				*port_ptr=21;
			else if (strcmp(str,"gopher") == 0)
				*port_ptr=70;
#if 0
			else if (strcmp(str,"wais") == 0)
				*port_ptr=21;
#endif
			else
				{
				SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
				ERR_add_error_data(3,"service='",str,"'");
				return(0);
				}
			}
		}
	return(1);
	}

int BIO_sock_error(int sock)
	{
	int j,i;
	int size;
		 
#if defined(OPENSSL_SYS_BEOS_R5)
	return 0;
#endif
		 
	size=sizeof(int);
	/* Note: under Windows the third parameter is of type (char *)
	 * whereas under other systems it is (void *) if you don't have
	 * a cast it will choke the compiler: if you do have a cast then
	 * you can either go for (char *) or (void *).
	 */
	i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
	if (i < 0)
		return(1);
	else
		return(j);
	}

#if 0
long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
	{
	int i;
	char **p;

	switch (cmd)
		{
	case BIO_GHBN_CTRL_HITS:
		return(BIO_ghbn_hits);
		/* break; */
	case BIO_GHBN_CTRL_MISSES:
		return(BIO_ghbn_miss);
		/* break; */
	case BIO_GHBN_CTRL_CACHE_SIZE:
		return(GHBN_NUM);
		/* break; */
	case BIO_GHBN_CTRL_GET_ENTRY:
		if ((iarg >= 0) && (iarg <GHBN_NUM) &&
			(ghbn_cache[iarg].order > 0))
			{
			p=(char **)parg;
			if (p == NULL) return(0);
			*p=ghbn_cache[iarg].name;
			ghbn_cache[iarg].name[128]='\0';
			return(1);
			}
		return(0);
		/* break; */
	case BIO_GHBN_CTRL_FLUSH:
		for (i=0; i<GHBN_NUM; i++)
			ghbn_cache[i].order=0;
		break;
	default:
		return(0);
		}
	return(1);
	}
#endif

#if 0
static struct hostent *ghbn_dup(struct hostent *a)
	{
	struct hostent *ret;
	int i,j;

	MemCheck_off();
	ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
	if (ret == NULL) return(NULL);
	memset(ret,0,sizeof(struct hostent));

	for (i=0; a->h_aliases[i] != NULL; i++)
		;
	i++;
	ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
	if (ret->h_aliases == NULL)
		goto err;
	memset(ret->h_aliases, 0, i*sizeof(char *));

	for (i=0; a->h_addr_list[i] != NULL; i++)
		;
	i++;
	ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
	if (ret->h_addr_list == NULL)
		goto err;
	memset(ret->h_addr_list, 0, i*sizeof(char *));

	j=strlen(a->h_name)+1;
	if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
	memcpy((char *)ret->h_name,a->h_name,j);
	for (i=0; a->h_aliases[i] != NULL; i++)
		{
		j=strlen(a->h_aliases[i])+1;
		if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
		memcpy(ret->h_aliases[i],a->h_aliases[i],j);
		}
	ret->h_length=a->h_length;
	ret->h_addrtype=a->h_addrtype;
	for (i=0; a->h_addr_list[i] != NULL; i++)
		{
		if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
			goto err;
		memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
		}
	if (0)
		{
err:	
		if (ret != NULL)
			ghbn_free(ret);
		ret=NULL;
		}
	MemCheck_on();
	return(ret);
	}

static void ghbn_free(struct hostent *a)
	{
	int i;

	if(a == NULL)
	    return;

	if (a->h_aliases != NULL)
		{
		for (i=0; a->h_aliases[i] != NULL; i++)
			OPENSSL_free(a->h_aliases[i]);
		OPENSSL_free(a->h_aliases);
		}
	if (a->h_addr_list != NULL)
		{
		for (i=0; a->h_addr_list[i] != NULL; i++)
			OPENSSL_free(a->h_addr_list[i]);
		OPENSSL_free(a->h_addr_list);
		}
	if (a->h_name != NULL) OPENSSL_free(a->h_name);
	OPENSSL_free(a);
	}

#endif

struct hostent *BIO_gethostbyname(const char *name)
	{
#if 1
	/* Caching gethostbyname() results forever is wrong,
	 * so we have to let the true gethostbyname() worry about this */
#if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
	return gethostbyname((char*)name);
#else
	return gethostbyname(name);
#endif
#else
	struct hostent *ret;
	int i,lowi=0,j;
	unsigned long low= (unsigned long)-1;


#  if 0
	/* It doesn't make sense to use locking here: The function interface
	 * is not thread-safe, because threads can never be sure when
	 * some other thread destroys the data they were given a pointer to.
	 */
	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
#  endif
	j=strlen(name);
	if (j < 128)
		{
		for (i=0; i<GHBN_NUM; i++)
			{
			if (low > ghbn_cache[i].order)
				{
				low=ghbn_cache[i].order;
				lowi=i;
				}
			if (ghbn_cache[i].order > 0)
				{
				if (strncmp(name,ghbn_cache[i].name,128) == 0)
					break;
				}
			}
		}
	else
		i=GHBN_NUM;

	if (i == GHBN_NUM) /* no hit*/
		{
		BIO_ghbn_miss++;
		/* Note: under VMS with SOCKETSHR, it seems like the first
		 * parameter is 'char *', instead of 'const char *'
		 */
#  ifndef CONST_STRICT
		ret=gethostbyname((char *)name);
#  else
		ret=gethostbyname(name);
#  endif

		if (ret == NULL)
			goto end;
		if (j > 128) /* too big to cache */
			{
#  if 0
			/* If we were trying to make this function thread-safe (which
			 * is bound to fail), we'd have to give up in this case
			 * (or allocate more memory). */
			ret = NULL;
#  endif
			goto end;
			}

		/* else add to cache */
		if (ghbn_cache[lowi].ent != NULL)
			ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
		ghbn_cache[lowi].name[0] = '\0';

		if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
			{
			BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
			goto end;
			}
		strncpy(ghbn_cache[lowi].name,name,128);
		ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
		}
	else
		{
		BIO_ghbn_hits++;
		ret= ghbn_cache[i].ent;
		ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
		}
end:
#  if 0
	CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
#  endif
	return(ret);
#endif
	}


int BIO_sock_init(void)
	{
#ifdef OPENSSL_SYS_WINDOWS
	static struct WSAData wsa_state;

	if (!wsa_init_done)
		{
		int err;
	  
		wsa_init_done=1;
		memset(&wsa_state,0,sizeof(wsa_state));
		/* Not making wsa_state available to the rest of the
		 * code is formally wrong. But the structures we use
		 * are [beleived to be] invariable among Winsock DLLs,
		 * while API availability is [expected to be] probed
		 * at run-time with DSO_global_lookup. */
		if (WSAStartup(0x0202,&wsa_state)!=0)
			{
			err=WSAGetLastError();
			SYSerr(SYS_F_WSASTARTUP,err);
			BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
			return(-1);
			}
		}
#endif /* OPENSSL_SYS_WINDOWS */
#ifdef WATT32
	extern int _watt_do_exit;
	_watt_do_exit = 0;    /* don't make sock_init() call exit() */
	if (sock_init())
		return (-1);
#endif

#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
    WORD wVerReq;
    WSADATA wsaData;
    int err;

    if (!wsa_init_done)
    {
        wsa_init_done=1;
        wVerReq = MAKEWORD( 2, 0 );
        err = WSAStartup(wVerReq,&wsaData);
        if (err != 0)
        {
            SYSerr(SYS_F_WSASTARTUP,err);
            BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
            return(-1);
			}
		}
#endif

	return(1);
	}

void BIO_sock_cleanup(void)
	{
#ifdef OPENSSL_SYS_WINDOWS
	if (wsa_init_done)
		{
		wsa_init_done=0;
#if 0		/* this call is claimed to be non-present in Winsock2 */
		WSACancelBlockingCall();
#endif
		WSACleanup();
		}
#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
   if (wsa_init_done)
        {
        wsa_init_done=0;
        WSACleanup();
		}
#endif
	}

#if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000

int BIO_socket_ioctl(int fd, long type, void *arg)
	{
	int i;

#ifdef __DJGPP__
	i=ioctlsocket(fd,type,(char *)arg);
#else
	i=ioctlsocket(fd,type,arg);
#endif /* __DJGPP__ */
	if (i < 0)
		SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
	return(i);
	}
#endif /* __VMS_VER */

/* The reason I have implemented this instead of using sscanf is because
 * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
static int get_ip(const char *str, unsigned char ip[4])
	{
	unsigned int tmp[4];
	int num=0,c,ok=0;

	tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;

	for (;;)
		{
		c= *(str++);
		if ((c >= '0') && (c <= '9'))
			{
			ok=1;
			tmp[num]=tmp[num]*10+c-'0';
			if (tmp[num] > 255) return(0);
			}
		else if (c == '.')
			{
			if (!ok) return(-1);
			if (num == 3) return(0);
			num++;
			ok=0;
			}
		else if (c == '\0' && (num == 3) && ok)
			break;
		else
			return(0);
		}
	ip[0]=tmp[0];
	ip[1]=tmp[1];
	ip[2]=tmp[2];
	ip[3]=tmp[3];
	return(1);
	}

int BIO_get_accept_socket(char *host, int bind_mode)
	{
	int ret=0;
	union {
		struct sockaddr sa;
		struct sockaddr_in sa_in;
#if OPENSSL_USE_IPV6
		struct sockaddr_in6 sa_in6;
#endif
	} server,client;
	int s=INVALID_SOCKET,cs,addrlen;
	unsigned char ip[4];
	unsigned short port;
	char *str=NULL,*e;
	char *h,*p;
	unsigned long l;
	int err_num;

	if (BIO_sock_init() != 1) return(INVALID_SOCKET);

	if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);

	h=p=NULL;
	h=str;
	for (e=str; *e; e++)
		{
		if (*e == ':')
			{
			p=e;
			}
		else if (*e == '/')
			{
			*e='\0';
			break;
			}
		}
	if (p)	*p++='\0';	/* points at last ':', '::port' is special [see below] */
	else	p=h,h=NULL;

#ifdef EAI_FAMILY
	do {
	static union {	void *p;
			int (WSAAPI *f)(const char *,const char *,
				 const struct addrinfo *,
				 struct addrinfo **);
			} p_getaddrinfo = {NULL};
	static union {	void *p;
			void (WSAAPI *f)(struct addrinfo *);
			} p_freeaddrinfo = {NULL};
	struct addrinfo *res,hint;

	if (p_getaddrinfo.p==NULL)
		{
		if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL ||
		    (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL)
			p_getaddrinfo.p=(void*)-1;
		}
	if (p_getaddrinfo.p==(void *)-1) break;

	/* '::port' enforces IPv6 wildcard listener. Some OSes,
	 * e.g. Solaris, default to IPv6 without any hint. Also
	 * note that commonly IPv6 wildchard socket can service
	 * IPv4 connections just as well...  */
	memset(&hint,0,sizeof(hint));
	if (h)
		{
		if (strchr(h,':'))
			{
			if (h[1]=='\0') h=NULL;
#if OPENSSL_USE_IPV6
			hint.ai_family = AF_INET6;
#else
			h=NULL;
#endif
			}
	    	else if (h[0]=='*' && h[1]=='\0')
			h=NULL;
		}

	if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;

	addrlen = res->ai_addrlen<=sizeof(server) ?
			res->ai_addrlen :
			sizeof(server);
	memcpy(&server, res->ai_addr, addrlen);

	(*p_freeaddrinfo.f)(res);
	goto again;
	} while (0);
#endif

	if (!BIO_get_port(p,&port)) goto err;

	memset((char *)&server,0,sizeof(server));
	server.sa_in.sin_family=AF_INET;
	server.sa_in.sin_port=htons(port);
	addrlen = sizeof(server.sa_in);

	if (h == NULL || strcmp(h,"*") == 0)
		server.sa_in.sin_addr.s_addr=INADDR_ANY;
	else
		{
                if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
		l=(unsigned long)
			((unsigned long)ip[0]<<24L)|
			((unsigned long)ip[1]<<16L)|
			((unsigned long)ip[2]<< 8L)|
			((unsigned long)ip[3]);
		server.sa_in.sin_addr.s_addr=htonl(l);
		}

again:
	s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
	if (s == INVALID_SOCKET)
		{
		SYSerr(SYS_F_SOCKET,get_last_socket_error());
		ERR_add_error_data(3,"port='",host,"'");
		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
		goto err;
		}

#ifdef SO_REUSEADDR
	if (bind_mode == BIO_BIND_REUSEADDR)
		{
		int i=1;

		ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
		bind_mode=BIO_BIND_NORMAL;
		}
#endif
	if (bind(s,&server.sa,addrlen) == -1)
		{
#ifdef SO_REUSEADDR
		err_num=get_last_socket_error();
		if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
#ifdef OPENSSL_SYS_WINDOWS
			/* Some versions of Windows define EADDRINUSE to
			 * a dummy value.
			 */
			(err_num == WSAEADDRINUSE))
#else
			(err_num == EADDRINUSE))
#endif
			{
			client = server;
			if (h == NULL || strcmp(h,"*") == 0)
				{
#if OPENSSL_USE_IPV6
				if (client.sa.sa_family == AF_INET6)
					{
					memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr));
					client.sa_in6.sin6_addr.s6_addr[15]=1;
					}
				else
#endif
				if (client.sa.sa_family == AF_INET)
					{
					client.sa_in.sin_addr.s_addr=htonl(0x7F000001);
					}
				else	goto err;
				}
			cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
			if (cs != INVALID_SOCKET)
				{
				int ii;
				ii=connect(cs,&client.sa,addrlen);
				closesocket(cs);
				if (ii == INVALID_SOCKET)
					{
					bind_mode=BIO_BIND_REUSEADDR;
					closesocket(s);
					goto again;
					}
				/* else error */
				}
			/* else error */
			}
#endif
		SYSerr(SYS_F_BIND,err_num);
		ERR_add_error_data(3,"port='",host,"'");
		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
		goto err;
		}
	if (listen(s,MAX_LISTEN) == -1)
		{
		SYSerr(SYS_F_BIND,get_last_socket_error());
		ERR_add_error_data(3,"port='",host,"'");
		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
		goto err;
		}
	ret=1;
err:
	if (str != NULL) OPENSSL_free(str);
	if ((ret == 0) && (s != INVALID_SOCKET))
		{
		closesocket(s);
		s= INVALID_SOCKET;
		}
	return(s);
	}

int BIO_accept(int sock, char **addr)
	{
	int ret=INVALID_SOCKET;
	unsigned long l;
	unsigned short port;
	char *p;

	struct {
	/*
	 * As for following union. Trouble is that there are platforms
	 * that have socklen_t and there are platforms that don't, on
	 * some platforms socklen_t is int and on some size_t. So what
	 * one can do? One can cook #ifdef spaghetti, which is nothing
	 * but masochistic. Or one can do union between int and size_t.
	 * One naturally does it primarily for 64-bit platforms where
	 * sizeof(int) != sizeof(size_t). But would it work? Note that
	 * if size_t member is initialized to 0, then later int member
	 * assignment naturally does the job on little-endian platforms
	 * regardless accept's expectations! What about big-endians?
	 * If accept expects int*, then it works, and if size_t*, then
	 * length value would appear as unreasonably large. But this
	 * won't prevent it from filling in the address structure. The
	 * trouble of course would be if accept returns more data than
	 * actual buffer can accomodate and overwrite stack... That's
	 * where early OPENSSL_assert comes into picture. Besides, the
	 * only 64-bit big-endian platform found so far that expects
	 * size_t* is HP-UX, where stack grows towards higher address.
	 * <appro>
	 */
	union { size_t s; int i; } len;
	union {
		struct sockaddr sa;
		struct sockaddr_in sa_in;
#if OPENSSL_USE_IPV6
		struct sockaddr_in6 sa_in6;
#endif
		} from;
	} sa;

	sa.len.s=0;
	sa.len.i=sizeof(sa.from);
	memset(&sa.from,0,sizeof(sa.from));
	ret=accept(sock,&sa.from.sa,(void *)&sa.len);
	if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
		{
		OPENSSL_assert(sa.len.s<=sizeof(sa.from));
		sa.len.i = (int)sa.len.s;
		/* use sa.len.i from this point */
		}
	if (ret == INVALID_SOCKET)
		{
		if(BIO_sock_should_retry(ret)) return -2;
		SYSerr(SYS_F_ACCEPT,get_last_socket_error());
		BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
		goto end;
		}

	if (addr == NULL) goto end;

#ifdef EAI_FAMILY
	do {
	char   h[NI_MAXHOST],s[NI_MAXSERV];
	size_t nl;
	static union {	void *p;
			int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/,
				 char *,size_t,char *,size_t,int);
			} p_getnameinfo = {NULL};
			/* 2nd argument to getnameinfo is specified to
			 * be socklen_t. Unfortunately there is a number
			 * of environments where socklen_t is not defined.
			 * As it's passed by value, it's safe to pass it
			 * as size_t... <appro> */

	if (p_getnameinfo.p==NULL)
		{
		if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL)
			p_getnameinfo.p=(void*)-1;
		}
	if (p_getnameinfo.p==(void *)-1) break;

	if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s),
	    NI_NUMERICHOST|NI_NUMERICSERV)) break;
	nl = strlen(h)+strlen(s)+2;
	p = *addr;
	if (p)	{ *p = '\0'; p = OPENSSL_realloc(p,nl);	}
	else	{ p = OPENSSL_malloc(nl);		}
	if (p==NULL)
		{
		BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
		goto end;
		}
	*addr = p;
	BIO_snprintf(*addr,nl,"%s:%s",h,s);
	goto end;
	} while(0);
#endif
	if (sa.from.sa.sa_family != AF_INET) goto end;
	l=ntohl(sa.from.sa_in.sin_addr.s_addr);
	port=ntohs(sa.from.sa_in.sin_port);
	if (*addr == NULL)
		{
		if ((p=OPENSSL_malloc(24)) == NULL)
			{
			BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
			goto end;
			}
		*addr=p;
		}
	BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
		     (unsigned char)(l>>24L)&0xff,
		     (unsigned char)(l>>16L)&0xff,
		     (unsigned char)(l>> 8L)&0xff,
		     (unsigned char)(l     )&0xff,
		     port);
end:
	return(ret);
	}

int BIO_set_tcp_ndelay(int s, int on)
	{
	int ret=0;
#if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
	int opt;

#ifdef SOL_TCP
	opt=SOL_TCP;
#else
#ifdef IPPROTO_TCP
	opt=IPPROTO_TCP;
#endif
#endif
	
	ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
#endif
	return(ret == 0);
	}
#endif

int BIO_socket_nbio(int s, int mode)
	{
	int ret= -1;
	int l;

	l=mode;
#ifdef FIONBIO
	ret=BIO_socket_ioctl(s,FIONBIO,&l);
#endif
	return(ret == 0);
	}
