155714Skris/* crypto/bio/b_sock.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include <stdlib.h>
6155714Skris#include <errno.h>
6255714Skris#define USE_SOCKETS
6355714Skris#include "cryptlib.h"
6455714Skris#include <openssl/bio.h>
65160814Ssimon#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
66194206Ssimon#include <netdb.h>
67194206Ssimon#if defined(NETWARE_CLIB)
68194206Ssimon#include <sys/ioctl.h>
69194206SsimonNETDB_DEFINE_CONTEXT
70160814Ssimon#endif
71194206Ssimon#endif
7255714Skris
73160814Ssimon#ifndef OPENSSL_NO_SOCK
74160814Ssimon
75238405Sjkim#include <openssl/dso.h>
76238405Sjkim
7755714Skris#define SOCKET_PROTOCOL IPPROTO_TCP
7855714Skris
7955714Skris#ifdef SO_MAXCONN
80100928Snectar#define MAX_LISTEN  SO_MAXCONN
81100928Snectar#elif defined(SOMAXCONN)
8255714Skris#define MAX_LISTEN  SOMAXCONN
8355714Skris#else
8455714Skris#define MAX_LISTEN  32
8555714Skris#endif
8655714Skris
87160814Ssimon#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
8855714Skrisstatic int wsa_init_done=0;
8955714Skris#endif
9055714Skris
91238405Sjkim/*
92238405Sjkim * WSAAPI specifier is required to make indirect calls to run-time
93238405Sjkim * linked WinSock 2 functions used in this module, to be specific
94238405Sjkim * [get|free]addrinfo and getnameinfo. This is because WinSock uses
95238405Sjkim * uses non-C calling convention, __stdcall vs. __cdecl, on x86
96238405Sjkim * Windows. On non-WinSock platforms WSAAPI needs to be void.
97238405Sjkim */
98238405Sjkim#ifndef WSAAPI
99238405Sjkim#define WSAAPI
100238405Sjkim#endif
101238405Sjkim
102109998Smarkm#if 0
10355714Skrisstatic unsigned long BIO_ghbn_hits=0L;
10455714Skrisstatic unsigned long BIO_ghbn_miss=0L;
10555714Skris
10655714Skris#define GHBN_NUM	4
10755714Skrisstatic struct ghbn_cache_st
10855714Skris	{
10955714Skris	char name[129];
11055714Skris	struct hostent *ent;
11155714Skris	unsigned long order;
11255714Skris	} ghbn_cache[GHBN_NUM];
113109998Smarkm#endif
11455714Skris
11555714Skrisstatic int get_ip(const char *str,unsigned char *ip);
11689837Skris#if 0
11755714Skrisstatic void ghbn_free(struct hostent *a);
11855714Skrisstatic struct hostent *ghbn_dup(struct hostent *a);
11989837Skris#endif
12055714Skrisint BIO_get_host_ip(const char *str, unsigned char *ip)
12155714Skris	{
12255714Skris	int i;
12355714Skris	int err = 1;
12455714Skris	int locked = 0;
12555714Skris	struct hostent *he;
12655714Skris
12755714Skris	i=get_ip(str,ip);
12855714Skris	if (i < 0)
12955714Skris		{
13055714Skris		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
13155714Skris		goto err;
13255714Skris		}
13355714Skris
13468651Skris	/* At this point, we have something that is most probably correct
13568651Skris	   in some way, so let's init the socket. */
13672613Skris	if (BIO_sock_init() != 1)
13772613Skris		return 0; /* don't generate another error code here */
13855714Skris
13968651Skris	/* If the string actually contained an IP address, we need not do
14068651Skris	   anything more */
14168651Skris	if (i > 0) return(1);
14268651Skris
14368651Skris	/* do a gethostbyname */
14455714Skris	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
14555714Skris	locked = 1;
14655714Skris	he=BIO_gethostbyname(str);
14755714Skris	if (he == NULL)
14855714Skris		{
14955714Skris		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
15055714Skris		goto err;
15155714Skris		}
15255714Skris
15355714Skris	/* cast to short because of win16 winsock definition */
15455714Skris	if ((short)he->h_addrtype != AF_INET)
15555714Skris		{
15655714Skris		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
15755714Skris		goto err;
15855714Skris		}
15955714Skris	for (i=0; i<4; i++)
16055714Skris		ip[i]=he->h_addr_list[0][i];
16155714Skris	err = 0;
16255714Skris
16355714Skris err:
16455714Skris	if (locked)
16555714Skris		CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
16655714Skris	if (err)
16755714Skris		{
16855714Skris		ERR_add_error_data(2,"host=",str);
16955714Skris		return 0;
17055714Skris		}
17155714Skris	else
17255714Skris		return 1;
17355714Skris	}
17455714Skris
17555714Skrisint BIO_get_port(const char *str, unsigned short *port_ptr)
17655714Skris	{
17755714Skris	int i;
17855714Skris	struct servent *s;
17955714Skris
18055714Skris	if (str == NULL)
18155714Skris		{
18255714Skris		BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
18355714Skris		return(0);
18455714Skris		}
18555714Skris	i=atoi(str);
18655714Skris	if (i != 0)
18755714Skris		*port_ptr=(unsigned short)i;
18855714Skris	else
18955714Skris		{
19055714Skris		CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
19159191Skris		/* Note: under VMS with SOCKETSHR, it seems like the first
19259191Skris		 * parameter is 'char *', instead of 'const char *'
19359191Skris		 */
19459191Skris#ifndef CONST_STRICT
195194206Ssimon		s=getservbyname((char *)str,"tcp");
196194206Ssimon#else
197194206Ssimon		s=getservbyname(str,"tcp");
19859191Skris#endif
19955714Skris		if(s != NULL)
20055714Skris			*port_ptr=ntohs((unsigned short)s->s_port);
20155714Skris		CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
20255714Skris		if(s == NULL)
20355714Skris			{
20455714Skris			if (strcmp(str,"http") == 0)
20555714Skris				*port_ptr=80;
20655714Skris			else if (strcmp(str,"telnet") == 0)
20755714Skris				*port_ptr=23;
20855714Skris			else if (strcmp(str,"socks") == 0)
20955714Skris				*port_ptr=1080;
21055714Skris			else if (strcmp(str,"https") == 0)
21155714Skris				*port_ptr=443;
21255714Skris			else if (strcmp(str,"ssl") == 0)
21355714Skris				*port_ptr=443;
21455714Skris			else if (strcmp(str,"ftp") == 0)
21555714Skris				*port_ptr=21;
21655714Skris			else if (strcmp(str,"gopher") == 0)
21755714Skris				*port_ptr=70;
21855714Skris#if 0
21955714Skris			else if (strcmp(str,"wais") == 0)
22055714Skris				*port_ptr=21;
22155714Skris#endif
22255714Skris			else
22355714Skris				{
22455714Skris				SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
22555714Skris				ERR_add_error_data(3,"service='",str,"'");
22655714Skris				return(0);
22755714Skris				}
22855714Skris			}
22955714Skris		}
23055714Skris	return(1);
23155714Skris	}
23255714Skris
23355714Skrisint BIO_sock_error(int sock)
23455714Skris	{
23555714Skris	int j,i;
23655714Skris	int size;
23755714Skris
238238405Sjkim#if defined(OPENSSL_SYS_BEOS_R5)
239238405Sjkim	return 0;
240238405Sjkim#endif
241238405Sjkim
24255714Skris	size=sizeof(int);
24355714Skris	/* Note: under Windows the third parameter is of type (char *)
24455714Skris	 * whereas under other systems it is (void *) if you don't have
24555714Skris	 * a cast it will choke the compiler: if you do have a cast then
24655714Skris	 * you can either go for (char *) or (void *).
24755714Skris	 */
24855714Skris	i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
24955714Skris	if (i < 0)
25055714Skris		return(1);
25155714Skris	else
25255714Skris		return(j);
25355714Skris	}
25455714Skris
255109998Smarkm#if 0
25655714Skrislong BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
25755714Skris	{
25855714Skris	int i;
25955714Skris	char **p;
26055714Skris
26155714Skris	switch (cmd)
26255714Skris		{
26355714Skris	case BIO_GHBN_CTRL_HITS:
26455714Skris		return(BIO_ghbn_hits);
26555714Skris		/* break; */
26655714Skris	case BIO_GHBN_CTRL_MISSES:
26755714Skris		return(BIO_ghbn_miss);
26855714Skris		/* break; */
26955714Skris	case BIO_GHBN_CTRL_CACHE_SIZE:
27055714Skris		return(GHBN_NUM);
27155714Skris		/* break; */
27255714Skris	case BIO_GHBN_CTRL_GET_ENTRY:
27355714Skris		if ((iarg >= 0) && (iarg <GHBN_NUM) &&
27455714Skris			(ghbn_cache[iarg].order > 0))
27555714Skris			{
27655714Skris			p=(char **)parg;
27755714Skris			if (p == NULL) return(0);
27855714Skris			*p=ghbn_cache[iarg].name;
27955714Skris			ghbn_cache[iarg].name[128]='\0';
28055714Skris			return(1);
28155714Skris			}
28255714Skris		return(0);
28355714Skris		/* break; */
28455714Skris	case BIO_GHBN_CTRL_FLUSH:
28555714Skris		for (i=0; i<GHBN_NUM; i++)
28655714Skris			ghbn_cache[i].order=0;
28755714Skris		break;
28855714Skris	default:
28955714Skris		return(0);
29055714Skris		}
29155714Skris	return(1);
29255714Skris	}
293109998Smarkm#endif
29455714Skris
29589837Skris#if 0
29655714Skrisstatic struct hostent *ghbn_dup(struct hostent *a)
29755714Skris	{
29855714Skris	struct hostent *ret;
29955714Skris	int i,j;
30055714Skris
30155714Skris	MemCheck_off();
30268651Skris	ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
30355714Skris	if (ret == NULL) return(NULL);
30455714Skris	memset(ret,0,sizeof(struct hostent));
30555714Skris
30655714Skris	for (i=0; a->h_aliases[i] != NULL; i++)
30755714Skris		;
30855714Skris	i++;
30968651Skris	ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
31055714Skris	if (ret->h_aliases == NULL)
31155714Skris		goto err;
31255714Skris	memset(ret->h_aliases, 0, i*sizeof(char *));
31355714Skris
31455714Skris	for (i=0; a->h_addr_list[i] != NULL; i++)
31555714Skris		;
31655714Skris	i++;
31768651Skris	ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
31855714Skris	if (ret->h_addr_list == NULL)
31955714Skris		goto err;
32055714Skris	memset(ret->h_addr_list, 0, i*sizeof(char *));
32155714Skris
32255714Skris	j=strlen(a->h_name)+1;
32368651Skris	if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
32459191Skris	memcpy((char *)ret->h_name,a->h_name,j);
32555714Skris	for (i=0; a->h_aliases[i] != NULL; i++)
32655714Skris		{
32755714Skris		j=strlen(a->h_aliases[i])+1;
32868651Skris		if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
32959191Skris		memcpy(ret->h_aliases[i],a->h_aliases[i],j);
33055714Skris		}
33155714Skris	ret->h_length=a->h_length;
33255714Skris	ret->h_addrtype=a->h_addrtype;
33355714Skris	for (i=0; a->h_addr_list[i] != NULL; i++)
33455714Skris		{
33568651Skris		if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
33655714Skris			goto err;
33755714Skris		memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
33855714Skris		}
33955714Skris	if (0)
34055714Skris		{
34155714Skriserr:
34255714Skris		if (ret != NULL)
34355714Skris			ghbn_free(ret);
34455714Skris		ret=NULL;
34555714Skris		}
34655714Skris	MemCheck_on();
34755714Skris	return(ret);
34855714Skris	}
34955714Skris
35055714Skrisstatic void ghbn_free(struct hostent *a)
35155714Skris	{
35255714Skris	int i;
35355714Skris
35455714Skris	if(a == NULL)
35555714Skris	    return;
35655714Skris
35755714Skris	if (a->h_aliases != NULL)
35855714Skris		{
35955714Skris		for (i=0; a->h_aliases[i] != NULL; i++)
36068651Skris			OPENSSL_free(a->h_aliases[i]);
36168651Skris		OPENSSL_free(a->h_aliases);
36255714Skris		}
36355714Skris	if (a->h_addr_list != NULL)
36455714Skris		{
36555714Skris		for (i=0; a->h_addr_list[i] != NULL; i++)
36668651Skris			OPENSSL_free(a->h_addr_list[i]);
36768651Skris		OPENSSL_free(a->h_addr_list);
36855714Skris		}
36968651Skris	if (a->h_name != NULL) OPENSSL_free(a->h_name);
37068651Skris	OPENSSL_free(a);
37155714Skris	}
372109998Smarkm
37389837Skris#endif
37455714Skris
37555714Skrisstruct hostent *BIO_gethostbyname(const char *name)
37655714Skris	{
37789837Skris#if 1
37889837Skris	/* Caching gethostbyname() results forever is wrong,
37989837Skris	 * so we have to let the true gethostbyname() worry about this */
380194206Ssimon#if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
381194206Ssimon	return gethostbyname((char*)name);
382194206Ssimon#else
38389837Skris	return gethostbyname(name);
384194206Ssimon#endif
38589837Skris#else
38655714Skris	struct hostent *ret;
38755714Skris	int i,lowi=0,j;
38855714Skris	unsigned long low= (unsigned long)-1;
38955714Skris
39055714Skris
39189837Skris#  if 0
39289837Skris	/* It doesn't make sense to use locking here: The function interface
39389837Skris	 * is not thread-safe, because threads can never be sure when
39489837Skris	 * some other thread destroys the data they were given a pointer to.
39589837Skris	 */
39655714Skris	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
39789837Skris#  endif
39855714Skris	j=strlen(name);
39955714Skris	if (j < 128)
40055714Skris		{
40155714Skris		for (i=0; i<GHBN_NUM; i++)
40255714Skris			{
40355714Skris			if (low > ghbn_cache[i].order)
40455714Skris				{
40555714Skris				low=ghbn_cache[i].order;
40655714Skris				lowi=i;
40755714Skris				}
40855714Skris			if (ghbn_cache[i].order > 0)
40955714Skris				{
41055714Skris				if (strncmp(name,ghbn_cache[i].name,128) == 0)
41155714Skris					break;
41255714Skris				}
41355714Skris			}
41455714Skris		}
41555714Skris	else
41655714Skris		i=GHBN_NUM;
41755714Skris
41855714Skris	if (i == GHBN_NUM) /* no hit*/
41955714Skris		{
42055714Skris		BIO_ghbn_miss++;
42159191Skris		/* Note: under VMS with SOCKETSHR, it seems like the first
42259191Skris		 * parameter is 'char *', instead of 'const char *'
42359191Skris		 */
42489837Skris#  ifndef CONST_STRICT
425194206Ssimon		ret=gethostbyname((char *)name);
426194206Ssimon#  else
427194206Ssimon		ret=gethostbyname(name);
42889837Skris#  endif
42955714Skris
43055714Skris		if (ret == NULL)
43155714Skris			goto end;
43255714Skris		if (j > 128) /* too big to cache */
43355714Skris			{
43489837Skris#  if 0
43589837Skris			/* If we were trying to make this function thread-safe (which
43689837Skris			 * is bound to fail), we'd have to give up in this case
43789837Skris			 * (or allocate more memory). */
43855714Skris			ret = NULL;
43989837Skris#  endif
44055714Skris			goto end;
44155714Skris			}
44255714Skris
44355714Skris		/* else add to cache */
44455714Skris		if (ghbn_cache[lowi].ent != NULL)
44555714Skris			ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
44655714Skris		ghbn_cache[lowi].name[0] = '\0';
44755714Skris
44855714Skris		if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
44955714Skris			{
45055714Skris			BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
45155714Skris			goto end;
45255714Skris			}
45355714Skris		strncpy(ghbn_cache[lowi].name,name,128);
45455714Skris		ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
45555714Skris		}
45655714Skris	else
45755714Skris		{
45855714Skris		BIO_ghbn_hits++;
45955714Skris		ret= ghbn_cache[i].ent;
46055714Skris		ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
46155714Skris		}
46255714Skrisend:
46389837Skris#  if 0
46455714Skris	CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
46589837Skris#  endif
46689837Skris	return(ret);
46755714Skris#endif
46855714Skris	}
46955714Skris
47089837Skris
47155714Skrisint BIO_sock_init(void)
47255714Skris	{
473109998Smarkm#ifdef OPENSSL_SYS_WINDOWS
47455714Skris	static struct WSAData wsa_state;
47555714Skris
47655714Skris	if (!wsa_init_done)
47755714Skris		{
47855714Skris		int err;
47955714Skris
48055714Skris		wsa_init_done=1;
48155714Skris		memset(&wsa_state,0,sizeof(wsa_state));
482238405Sjkim		/* Not making wsa_state available to the rest of the
483238405Sjkim		 * code is formally wrong. But the structures we use
484238405Sjkim		 * are [beleived to be] invariable among Winsock DLLs,
485238405Sjkim		 * while API availability is [expected to be] probed
486238405Sjkim		 * at run-time with DSO_global_lookup. */
487238405Sjkim		if (WSAStartup(0x0202,&wsa_state)!=0)
48855714Skris			{
48955714Skris			err=WSAGetLastError();
49055714Skris			SYSerr(SYS_F_WSASTARTUP,err);
49155714Skris			BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
49255714Skris			return(-1);
49355714Skris			}
49455714Skris		}
495109998Smarkm#endif /* OPENSSL_SYS_WINDOWS */
496109998Smarkm#ifdef WATT32
497109998Smarkm	extern int _watt_do_exit;
498109998Smarkm	_watt_do_exit = 0;    /* don't make sock_init() call exit() */
499109998Smarkm	if (sock_init())
500109998Smarkm		return (-1);
501109998Smarkm#endif
502160814Ssimon
503160814Ssimon#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
504160814Ssimon    WORD wVerReq;
505160814Ssimon    WSADATA wsaData;
506160814Ssimon    int err;
507160814Ssimon
508160814Ssimon    if (!wsa_init_done)
509160814Ssimon    {
510160814Ssimon        wsa_init_done=1;
511160814Ssimon        wVerReq = MAKEWORD( 2, 0 );
512160814Ssimon        err = WSAStartup(wVerReq,&wsaData);
513160814Ssimon        if (err != 0)
514160814Ssimon        {
515160814Ssimon            SYSerr(SYS_F_WSASTARTUP,err);
516160814Ssimon            BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
517160814Ssimon            return(-1);
518160814Ssimon			}
519160814Ssimon		}
520160814Ssimon#endif
521160814Ssimon
52255714Skris	return(1);
52355714Skris	}
52455714Skris
52555714Skrisvoid BIO_sock_cleanup(void)
52655714Skris	{
527109998Smarkm#ifdef OPENSSL_SYS_WINDOWS
52855714Skris	if (wsa_init_done)
52955714Skris		{
53055714Skris		wsa_init_done=0;
531238405Sjkim#if 0		/* this call is claimed to be non-present in Winsock2 */
532238405Sjkim		WSACancelBlockingCall();
533109998Smarkm#endif
53455714Skris		WSACleanup();
53555714Skris		}
536160814Ssimon#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
537160814Ssimon   if (wsa_init_done)
538160814Ssimon        {
539160814Ssimon        wsa_init_done=0;
540160814Ssimon        WSACleanup();
541160814Ssimon		}
54255714Skris#endif
54355714Skris	}
54455714Skris
545109998Smarkm#if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
54655714Skris
547111147Snectarint BIO_socket_ioctl(int fd, long type, void *arg)
54855714Skris	{
54955714Skris	int i;
55055714Skris
551109998Smarkm#ifdef __DJGPP__
552109998Smarkm	i=ioctlsocket(fd,type,(char *)arg);
553109998Smarkm#else
554238405Sjkim# if defined(OPENSSL_SYS_VMS)
555238405Sjkim	/* 2011-02-18 SMS.
556238405Sjkim	 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
557238405Sjkim	 * observe that all the consumers pass in an "unsigned long *",
558238405Sjkim	 * so we arrange a local copy with a short pointer, and use
559238405Sjkim	 * that, instead.
560238405Sjkim	 */
561238405Sjkim#  if __INITIAL_POINTER_SIZE == 64
562238405Sjkim#   define ARG arg_32p
563238405Sjkim#   pragma pointer_size save
564238405Sjkim#   pragma pointer_size 32
565238405Sjkim	unsigned long arg_32;
566238405Sjkim	unsigned long *arg_32p;
567238405Sjkim#   pragma pointer_size restore
568238405Sjkim	arg_32p = &arg_32;
569238405Sjkim	arg_32 = *((unsigned long *) arg);
570238405Sjkim#  else /* __INITIAL_POINTER_SIZE == 64 */
571238405Sjkim#   define ARG arg
572238405Sjkim#  endif /* __INITIAL_POINTER_SIZE == 64 [else] */
573238405Sjkim# else /* defined(OPENSSL_SYS_VMS) */
574238405Sjkim#  define ARG arg
575238405Sjkim# endif /* defined(OPENSSL_SYS_VMS) [else] */
576238405Sjkim
577238405Sjkim	i=ioctlsocket(fd,type,ARG);
578109998Smarkm#endif /* __DJGPP__ */
57955714Skris	if (i < 0)
58055714Skris		SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
58155714Skris	return(i);
58255714Skris	}
58355714Skris#endif /* __VMS_VER */
58455714Skris
58555714Skris/* The reason I have implemented this instead of using sscanf is because
58655714Skris * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
58755714Skrisstatic int get_ip(const char *str, unsigned char ip[4])
58855714Skris	{
58955714Skris	unsigned int tmp[4];
59055714Skris	int num=0,c,ok=0;
59155714Skris
59255714Skris	tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
59355714Skris
59455714Skris	for (;;)
59555714Skris		{
59655714Skris		c= *(str++);
59755714Skris		if ((c >= '0') && (c <= '9'))
59855714Skris			{
59955714Skris			ok=1;
60055714Skris			tmp[num]=tmp[num]*10+c-'0';
601109998Smarkm			if (tmp[num] > 255) return(0);
60255714Skris			}
60355714Skris		else if (c == '.')
60455714Skris			{
60555714Skris			if (!ok) return(-1);
606109998Smarkm			if (num == 3) return(0);
60755714Skris			num++;
60855714Skris			ok=0;
60955714Skris			}
610109998Smarkm		else if (c == '\0' && (num == 3) && ok)
61155714Skris			break;
61255714Skris		else
61355714Skris			return(0);
61455714Skris		}
61555714Skris	ip[0]=tmp[0];
61655714Skris	ip[1]=tmp[1];
61755714Skris	ip[2]=tmp[2];
61855714Skris	ip[3]=tmp[3];
61955714Skris	return(1);
62055714Skris	}
62155714Skris
62255714Skrisint BIO_get_accept_socket(char *host, int bind_mode)
62355714Skris	{
62455714Skris	int ret=0;
625238405Sjkim	union {
626238405Sjkim		struct sockaddr sa;
627238405Sjkim		struct sockaddr_in sa_in;
628238405Sjkim#if OPENSSL_USE_IPV6
629238405Sjkim		struct sockaddr_in6 sa_in6;
630238405Sjkim#endif
631238405Sjkim	} server,client;
632238405Sjkim	int s=INVALID_SOCKET,cs,addrlen;
63355714Skris	unsigned char ip[4];
63455714Skris	unsigned short port;
63572613Skris	char *str=NULL,*e;
636238405Sjkim	char *h,*p;
63755714Skris	unsigned long l;
63855714Skris	int err_num;
63955714Skris
64072613Skris	if (BIO_sock_init() != 1) return(INVALID_SOCKET);
64155714Skris
64255714Skris	if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
64355714Skris
64455714Skris	h=p=NULL;
64555714Skris	h=str;
64655714Skris	for (e=str; *e; e++)
64755714Skris		{
64855714Skris		if (*e == ':')
64955714Skris			{
650238405Sjkim			p=e;
65155714Skris			}
65255714Skris		else if (*e == '/')
65355714Skris			{
65455714Skris			*e='\0';
65555714Skris			break;
65655714Skris			}
65755714Skris		}
658238405Sjkim	if (p)	*p++='\0';	/* points at last ':', '::port' is special [see below] */
659238405Sjkim	else	p=h,h=NULL;
66055714Skris
661238405Sjkim#ifdef EAI_FAMILY
662238405Sjkim	do {
663238405Sjkim	static union {	void *p;
664238405Sjkim			int (WSAAPI *f)(const char *,const char *,
665238405Sjkim				 const struct addrinfo *,
666238405Sjkim				 struct addrinfo **);
667238405Sjkim			} p_getaddrinfo = {NULL};
668238405Sjkim	static union {	void *p;
669238405Sjkim			void (WSAAPI *f)(struct addrinfo *);
670238405Sjkim			} p_freeaddrinfo = {NULL};
671238405Sjkim	struct addrinfo *res,hint;
672238405Sjkim
673238405Sjkim	if (p_getaddrinfo.p==NULL)
67455714Skris		{
675238405Sjkim		if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL ||
676238405Sjkim		    (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL)
677238405Sjkim			p_getaddrinfo.p=(void*)-1;
67855714Skris		}
679238405Sjkim	if (p_getaddrinfo.p==(void *)-1) break;
68055714Skris
681238405Sjkim	/* '::port' enforces IPv6 wildcard listener. Some OSes,
682238405Sjkim	 * e.g. Solaris, default to IPv6 without any hint. Also
683238405Sjkim	 * note that commonly IPv6 wildchard socket can service
684238405Sjkim	 * IPv4 connections just as well...  */
685238405Sjkim	memset(&hint,0,sizeof(hint));
686238405Sjkim	hint.ai_flags = AI_PASSIVE;
687238405Sjkim	if (h)
688238405Sjkim		{
689238405Sjkim		if (strchr(h,':'))
690238405Sjkim			{
691238405Sjkim			if (h[1]=='\0') h=NULL;
692238405Sjkim#if OPENSSL_USE_IPV6
693238405Sjkim			hint.ai_family = AF_INET6;
694238405Sjkim#else
695238405Sjkim			h=NULL;
696238405Sjkim#endif
697238405Sjkim			}
698238405Sjkim	    	else if (h[0]=='*' && h[1]=='\0')
699238405Sjkim			{
700238405Sjkim			hint.ai_family = AF_INET;
701238405Sjkim			h=NULL;
702238405Sjkim			}
703238405Sjkim		}
704238405Sjkim
705238405Sjkim	if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;
706238405Sjkim
707238405Sjkim	addrlen = res->ai_addrlen<=sizeof(server) ?
708238405Sjkim			res->ai_addrlen :
709238405Sjkim			sizeof(server);
710238405Sjkim	memcpy(&server, res->ai_addr, addrlen);
711238405Sjkim
712238405Sjkim	(*p_freeaddrinfo.f)(res);
713238405Sjkim	goto again;
714238405Sjkim	} while (0);
715238405Sjkim#endif
716238405Sjkim
71772613Skris	if (!BIO_get_port(p,&port)) goto err;
71855714Skris
71955714Skris	memset((char *)&server,0,sizeof(server));
720238405Sjkim	server.sa_in.sin_family=AF_INET;
721238405Sjkim	server.sa_in.sin_port=htons(port);
722238405Sjkim	addrlen = sizeof(server.sa_in);
72355714Skris
724238405Sjkim	if (h == NULL || strcmp(h,"*") == 0)
725238405Sjkim		server.sa_in.sin_addr.s_addr=INADDR_ANY;
72655714Skris	else
72755714Skris		{
72872613Skris                if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
72955714Skris		l=(unsigned long)
73055714Skris			((unsigned long)ip[0]<<24L)|
73155714Skris			((unsigned long)ip[1]<<16L)|
73255714Skris			((unsigned long)ip[2]<< 8L)|
73355714Skris			((unsigned long)ip[3]);
734238405Sjkim		server.sa_in.sin_addr.s_addr=htonl(l);
73555714Skris		}
73655714Skris
73755714Skrisagain:
738238405Sjkim	s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
73955714Skris	if (s == INVALID_SOCKET)
74055714Skris		{
74155714Skris		SYSerr(SYS_F_SOCKET,get_last_socket_error());
74255714Skris		ERR_add_error_data(3,"port='",host,"'");
74355714Skris		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
74455714Skris		goto err;
74555714Skris		}
74655714Skris
74755714Skris#ifdef SO_REUSEADDR
74855714Skris	if (bind_mode == BIO_BIND_REUSEADDR)
74955714Skris		{
75055714Skris		int i=1;
75155714Skris
75255714Skris		ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
75355714Skris		bind_mode=BIO_BIND_NORMAL;
75455714Skris		}
75555714Skris#endif
756238405Sjkim	if (bind(s,&server.sa,addrlen) == -1)
75755714Skris		{
75855714Skris#ifdef SO_REUSEADDR
75955714Skris		err_num=get_last_socket_error();
76055714Skris		if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
761215697Ssimon#ifdef OPENSSL_SYS_WINDOWS
762215697Ssimon			/* Some versions of Windows define EADDRINUSE to
763215697Ssimon			 * a dummy value.
764215697Ssimon			 */
765215697Ssimon			(err_num == WSAEADDRINUSE))
766215697Ssimon#else
76755714Skris			(err_num == EADDRINUSE))
768215697Ssimon#endif
76955714Skris			{
770238405Sjkim			client = server;
771238405Sjkim			if (h == NULL || strcmp(h,"*") == 0)
772238405Sjkim				{
773238405Sjkim#if OPENSSL_USE_IPV6
774238405Sjkim				if (client.sa.sa_family == AF_INET6)
775238405Sjkim					{
776238405Sjkim					memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr));
777238405Sjkim					client.sa_in6.sin6_addr.s6_addr[15]=1;
778238405Sjkim					}
779238405Sjkim				else
780238405Sjkim#endif
781238405Sjkim				if (client.sa.sa_family == AF_INET)
782238405Sjkim					{
783238405Sjkim					client.sa_in.sin_addr.s_addr=htonl(0x7F000001);
784238405Sjkim					}
785238405Sjkim				else	goto err;
786238405Sjkim				}
787238405Sjkim			cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
78855714Skris			if (cs != INVALID_SOCKET)
78955714Skris				{
79055714Skris				int ii;
791238405Sjkim				ii=connect(cs,&client.sa,addrlen);
79255714Skris				closesocket(cs);
79355714Skris				if (ii == INVALID_SOCKET)
79455714Skris					{
79555714Skris					bind_mode=BIO_BIND_REUSEADDR;
79655714Skris					closesocket(s);
79755714Skris					goto again;
79855714Skris					}
79955714Skris				/* else error */
80055714Skris				}
80155714Skris			/* else error */
80255714Skris			}
80355714Skris#endif
80455714Skris		SYSerr(SYS_F_BIND,err_num);
80555714Skris		ERR_add_error_data(3,"port='",host,"'");
80655714Skris		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
80755714Skris		goto err;
80855714Skris		}
80955714Skris	if (listen(s,MAX_LISTEN) == -1)
81055714Skris		{
81155714Skris		SYSerr(SYS_F_BIND,get_last_socket_error());
81255714Skris		ERR_add_error_data(3,"port='",host,"'");
81355714Skris		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
81455714Skris		goto err;
81555714Skris		}
81655714Skris	ret=1;
81755714Skriserr:
81868651Skris	if (str != NULL) OPENSSL_free(str);
81955714Skris	if ((ret == 0) && (s != INVALID_SOCKET))
82055714Skris		{
82155714Skris		closesocket(s);
82255714Skris		s= INVALID_SOCKET;
82355714Skris		}
82455714Skris	return(s);
82555714Skris	}
82655714Skris
82755714Skrisint BIO_accept(int sock, char **addr)
82855714Skris	{
82955714Skris	int ret=INVALID_SOCKET;
83055714Skris	unsigned long l;
83155714Skris	unsigned short port;
83255714Skris	char *p;
83355714Skris
834238405Sjkim	struct {
835238405Sjkim	/*
836238405Sjkim	 * As for following union. Trouble is that there are platforms
837238405Sjkim	 * that have socklen_t and there are platforms that don't, on
838238405Sjkim	 * some platforms socklen_t is int and on some size_t. So what
839238405Sjkim	 * one can do? One can cook #ifdef spaghetti, which is nothing
840238405Sjkim	 * but masochistic. Or one can do union between int and size_t.
841238405Sjkim	 * One naturally does it primarily for 64-bit platforms where
842238405Sjkim	 * sizeof(int) != sizeof(size_t). But would it work? Note that
843238405Sjkim	 * if size_t member is initialized to 0, then later int member
844238405Sjkim	 * assignment naturally does the job on little-endian platforms
845238405Sjkim	 * regardless accept's expectations! What about big-endians?
846238405Sjkim	 * If accept expects int*, then it works, and if size_t*, then
847238405Sjkim	 * length value would appear as unreasonably large. But this
848238405Sjkim	 * won't prevent it from filling in the address structure. The
849238405Sjkim	 * trouble of course would be if accept returns more data than
850238405Sjkim	 * actual buffer can accomodate and overwrite stack... That's
851238405Sjkim	 * where early OPENSSL_assert comes into picture. Besides, the
852238405Sjkim	 * only 64-bit big-endian platform found so far that expects
853238405Sjkim	 * size_t* is HP-UX, where stack grows towards higher address.
854238405Sjkim	 * <appro>
85555714Skris	 */
856238405Sjkim	union { size_t s; int i; } len;
857238405Sjkim	union {
858238405Sjkim		struct sockaddr sa;
859238405Sjkim		struct sockaddr_in sa_in;
860238405Sjkim#if OPENSSL_USE_IPV6
861238405Sjkim		struct sockaddr_in6 sa_in6;
862238405Sjkim#endif
863238405Sjkim		} from;
864238405Sjkim	} sa;
865238405Sjkim
866238405Sjkim	sa.len.s=0;
867238405Sjkim	sa.len.i=sizeof(sa.from);
868238405Sjkim	memset(&sa.from,0,sizeof(sa.from));
869238405Sjkim	ret=accept(sock,&sa.from.sa,(void *)&sa.len);
870238405Sjkim	if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
871238405Sjkim		{
872238405Sjkim		OPENSSL_assert(sa.len.s<=sizeof(sa.from));
873238405Sjkim		sa.len.i = (int)sa.len.s;
874238405Sjkim		/* use sa.len.i from this point */
875238405Sjkim		}
87655714Skris	if (ret == INVALID_SOCKET)
87755714Skris		{
878109998Smarkm		if(BIO_sock_should_retry(ret)) return -2;
87955714Skris		SYSerr(SYS_F_ACCEPT,get_last_socket_error());
88055714Skris		BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
88155714Skris		goto end;
88255714Skris		}
88355714Skris
88455714Skris	if (addr == NULL) goto end;
88555714Skris
886238405Sjkim#ifdef EAI_FAMILY
887238405Sjkim	do {
888238405Sjkim	char   h[NI_MAXHOST],s[NI_MAXSERV];
889238405Sjkim	size_t nl;
890238405Sjkim	static union {	void *p;
891238405Sjkim			int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/,
892238405Sjkim				 char *,size_t,char *,size_t,int);
893238405Sjkim			} p_getnameinfo = {NULL};
894238405Sjkim			/* 2nd argument to getnameinfo is specified to
895238405Sjkim			 * be socklen_t. Unfortunately there is a number
896238405Sjkim			 * of environments where socklen_t is not defined.
897238405Sjkim			 * As it's passed by value, it's safe to pass it
898238405Sjkim			 * as size_t... <appro> */
899238405Sjkim
900238405Sjkim	if (p_getnameinfo.p==NULL)
901238405Sjkim		{
902238405Sjkim		if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL)
903238405Sjkim			p_getnameinfo.p=(void*)-1;
904238405Sjkim		}
905238405Sjkim	if (p_getnameinfo.p==(void *)-1) break;
906238405Sjkim
907238405Sjkim	if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s),
908238405Sjkim	    NI_NUMERICHOST|NI_NUMERICSERV)) break;
909238405Sjkim	nl = strlen(h)+strlen(s)+2;
910238405Sjkim	p = *addr;
911238405Sjkim	if (p)	{ *p = '\0'; p = OPENSSL_realloc(p,nl);	}
912238405Sjkim	else	{ p = OPENSSL_malloc(nl);		}
913238405Sjkim	if (p==NULL)
914238405Sjkim		{
915238405Sjkim		BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
916238405Sjkim		goto end;
917238405Sjkim		}
918238405Sjkim	*addr = p;
919238405Sjkim	BIO_snprintf(*addr,nl,"%s:%s",h,s);
920238405Sjkim	goto end;
921238405Sjkim	} while(0);
922238405Sjkim#endif
923238405Sjkim	if (sa.from.sa.sa_family != AF_INET) goto end;
924238405Sjkim	l=ntohl(sa.from.sa_in.sin_addr.s_addr);
925238405Sjkim	port=ntohs(sa.from.sa_in.sin_port);
92655714Skris	if (*addr == NULL)
92755714Skris		{
92868651Skris		if ((p=OPENSSL_malloc(24)) == NULL)
92955714Skris			{
93055714Skris			BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
93155714Skris			goto end;
93255714Skris			}
93355714Skris		*addr=p;
93455714Skris		}
935127128Snectar	BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
936127128Snectar		     (unsigned char)(l>>24L)&0xff,
937127128Snectar		     (unsigned char)(l>>16L)&0xff,
938127128Snectar		     (unsigned char)(l>> 8L)&0xff,
939127128Snectar		     (unsigned char)(l     )&0xff,
940127128Snectar		     port);
94155714Skrisend:
94255714Skris	return(ret);
94355714Skris	}
94455714Skris
94555714Skrisint BIO_set_tcp_ndelay(int s, int on)
94655714Skris	{
94755714Skris	int ret=0;
94855714Skris#if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
94955714Skris	int opt;
95055714Skris
95155714Skris#ifdef SOL_TCP
95255714Skris	opt=SOL_TCP;
95355714Skris#else
95455714Skris#ifdef IPPROTO_TCP
95555714Skris	opt=IPPROTO_TCP;
95655714Skris#endif
95755714Skris#endif
95855714Skris
95955714Skris	ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
96055714Skris#endif
96155714Skris	return(ret == 0);
96255714Skris	}
96355714Skris
96455714Skrisint BIO_socket_nbio(int s, int mode)
96555714Skris	{
96655714Skris	int ret= -1;
967111147Snectar	int l;
96855714Skris
96955714Skris	l=mode;
97055714Skris#ifdef FIONBIO
97155714Skris	ret=BIO_socket_ioctl(s,FIONBIO,&l);
97255714Skris#endif
97355714Skris	return(ret == 0);
97455714Skris	}
975238405Sjkim#endif
976