os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/s_socket.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/s_socket.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,624 @@
     1.4 +/* apps/s_socket.c -  socket-related functions used by s_client and s_server */
     1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
     1.6 + * All rights reserved.
     1.7 + *
     1.8 + * This package is an SSL implementation written
     1.9 + * by Eric Young (eay@cryptsoft.com).
    1.10 + * The implementation was written so as to conform with Netscapes SSL.
    1.11 + * 
    1.12 + * This library is free for commercial and non-commercial use as long as
    1.13 + * the following conditions are aheared to.  The following conditions
    1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.15 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.16 + * included with this distribution is covered by the same copyright terms
    1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.18 + * 
    1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.20 + * the code are not to be removed.
    1.21 + * If this package is used in a product, Eric Young should be given attribution
    1.22 + * as the author of the parts of the library used.
    1.23 + * This can be in the form of a textual message at program startup or
    1.24 + * in documentation (online or textual) provided with the package.
    1.25 + * 
    1.26 + * Redistribution and use in source and binary forms, with or without
    1.27 + * modification, are permitted provided that the following conditions
    1.28 + * are met:
    1.29 + * 1. Redistributions of source code must retain the copyright
    1.30 + *    notice, this list of conditions and the following disclaimer.
    1.31 + * 2. Redistributions in binary form must reproduce the above copyright
    1.32 + *    notice, this list of conditions and the following disclaimer in the
    1.33 + *    documentation and/or other materials provided with the distribution.
    1.34 + * 3. All advertising materials mentioning features or use of this software
    1.35 + *    must display the following acknowledgement:
    1.36 + *    "This product includes cryptographic software written by
    1.37 + *     Eric Young (eay@cryptsoft.com)"
    1.38 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.39 + *    being used are not cryptographic related :-).
    1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.41 + *    the apps directory (application code) you must include an acknowledgement:
    1.42 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.43 + * 
    1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.47 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.54 + * SUCH DAMAGE.
    1.55 + * 
    1.56 + * The licence and distribution terms for any publically available version or
    1.57 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
    1.58 + * copied and put under another distribution licence
    1.59 + * [including the GNU Public Licence.]
    1.60 + */
    1.61 +
    1.62 +#include <stdio.h>
    1.63 +#include <stdlib.h>
    1.64 +#include <string.h>
    1.65 +#include <errno.h>
    1.66 +
    1.67 +
    1.68 +/* With IPv6, it looks like Digital has mixed up the proper order of
    1.69 +   recursive header file inclusion, resulting in the compiler complaining
    1.70 +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
    1.71 +   is needed to have fileno() declared correctly...  So let's define u_int */
    1.72 +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
    1.73 +#define __U_INT
    1.74 +typedef unsigned int u_int;
    1.75 +#endif
    1.76 +
    1.77 +#define USE_SOCKETS
    1.78 +#define NON_MAIN
    1.79 +#include "apps.h"
    1.80 +#undef USE_SOCKETS
    1.81 +#undef NON_MAIN
    1.82 +#include "s_apps.h"
    1.83 +#include <openssl/ssl.h>
    1.84 +
    1.85 +#ifdef FLAT_INC
    1.86 +#include "e_os.h"
    1.87 +#else
    1.88 +#ifndef SYMBIAN
    1.89 +#include "../e_os.h"
    1.90 +#else
    1.91 +#include "e_os.h"
    1.92 +#endif
    1.93 +#endif
    1.94 +
    1.95 +
    1.96 +#ifndef OPENSSL_NO_SOCK
    1.97 +
    1.98 +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
    1.99 +#include "netdb.h"
   1.100 +#endif
   1.101 +
   1.102 +static struct hostent *GetHostByName(char *name);
   1.103 +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
   1.104 +static void ssl_sock_cleanup(void);
   1.105 +#endif
   1.106 +static int ssl_sock_init(void);
   1.107 +static int init_client_ip(int *sock,unsigned char ip[4], int port, int type);
   1.108 +static int init_server(int *sock, int port, int type);
   1.109 +static int init_server_long(int *sock, int port,char *ip, int type);
   1.110 +static int do_accept(int acc_sock, int *sock, char **host);
   1.111 +static int host_ip(char *str, unsigned char ip[4]);
   1.112 +
   1.113 +#ifdef OPENSSL_SYS_WIN16
   1.114 +#define SOCKET_PROTOCOL	0 /* more microsoft stupidity */
   1.115 +#else
   1.116 +#define SOCKET_PROTOCOL	IPPROTO_TCP
   1.117 +#endif
   1.118 +
   1.119 +#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
   1.120 +static int wsa_init_done=0;
   1.121 +#endif
   1.122 +
   1.123 +#ifdef OPENSSL_SYS_WINDOWS
   1.124 +static struct WSAData wsa_state;
   1.125 +static int wsa_init_done=0;
   1.126 +
   1.127 +#ifdef OPENSSL_SYS_WIN16
   1.128 +static HWND topWnd=0;
   1.129 +static FARPROC lpTopWndProc=NULL;
   1.130 +static FARPROC lpTopHookProc=NULL;
   1.131 +extern HINSTANCE _hInstance;  /* nice global CRT provides */
   1.132 +
   1.133 +
   1.134 +static LONG FAR PASCAL topHookProc(HWND hwnd, UINT message, WPARAM wParam,
   1.135 +	     LPARAM lParam)
   1.136 +	{
   1.137 +	if (hwnd == topWnd)
   1.138 +		{
   1.139 +		switch(message)
   1.140 +			{
   1.141 +		case WM_DESTROY:
   1.142 +		case WM_CLOSE:
   1.143 +			SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopWndProc);
   1.144 +			ssl_sock_cleanup();
   1.145 +			break;
   1.146 +			}
   1.147 +		}
   1.148 +	return CallWindowProc(lpTopWndProc,hwnd,message,wParam,lParam);
   1.149 +	}
   1.150 +
   1.151 +static BOOL CALLBACK enumproc(HWND hwnd,LPARAM lParam)
   1.152 +	{
   1.153 +	topWnd=hwnd;
   1.154 +	return(FALSE);
   1.155 +	}
   1.156 +
   1.157 +#endif /* OPENSSL_SYS_WIN32 */
   1.158 +#endif /* OPENSSL_SYS_WINDOWS */
   1.159 +
   1.160 +#ifdef OPENSSL_SYS_WINDOWS
   1.161 +static void ssl_sock_cleanup(void)
   1.162 +	{
   1.163 +	if (wsa_init_done)
   1.164 +		{
   1.165 +		wsa_init_done=0;
   1.166 +#ifndef OPENSSL_SYS_WINCE
   1.167 +		WSACancelBlockingCall();
   1.168 +#endif
   1.169 +		WSACleanup();
   1.170 +		}
   1.171 +	}
   1.172 +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
   1.173 +static void sock_cleanup(void)
   1.174 +    {
   1.175 +    if (wsa_init_done)
   1.176 +        {
   1.177 +        wsa_init_done=0;
   1.178 +		WSACleanup();
   1.179 +		}
   1.180 +	}
   1.181 +#endif
   1.182 +
   1.183 +static int ssl_sock_init(void)
   1.184 +	{
   1.185 +#ifdef WATT32
   1.186 +	extern int _watt_do_exit;
   1.187 +	_watt_do_exit = 0;
   1.188 +	if (sock_init())
   1.189 +		return (0);
   1.190 +#elif defined(OPENSSL_SYS_WINDOWS)
   1.191 +	if (!wsa_init_done)
   1.192 +		{
   1.193 +		int err;
   1.194 +	  
   1.195 +#ifdef SIGINT
   1.196 +	//	signal(SIGINT,(void (*)(int))ssl_sock_cleanup);
   1.197 +#endif
   1.198 +		wsa_init_done=1;
   1.199 +		memset(&wsa_state,0,sizeof(wsa_state));
   1.200 +		if (WSAStartup(0x0101,&wsa_state)!=0)
   1.201 +			{
   1.202 +			err=WSAGetLastError();
   1.203 +			BIO_printf(bio_err,"unable to start WINSOCK, error code=%d\n",err);
   1.204 +			return(0);
   1.205 +			}
   1.206 +
   1.207 +#ifdef OPENSSL_SYS_WIN16
   1.208 +		EnumTaskWindows(GetCurrentTask(),enumproc,0L);
   1.209 +		lpTopWndProc=(FARPROC)GetWindowLong(topWnd,GWL_WNDPROC);
   1.210 +		lpTopHookProc=MakeProcInstance((FARPROC)topHookProc,_hInstance);
   1.211 +
   1.212 +		SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopHookProc);
   1.213 +#endif /* OPENSSL_SYS_WIN16 */
   1.214 +		}
   1.215 +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
   1.216 +   WORD wVerReq;
   1.217 +   WSADATA wsaData;
   1.218 +   int err;
   1.219 +
   1.220 +   if (!wsa_init_done)
   1.221 +      {
   1.222 +   
   1.223 +# ifdef SIGINT
   1.224 +    //  signal(SIGINT,(void (*)(int))sock_cleanup);
   1.225 +# endif
   1.226 +
   1.227 +      wsa_init_done=1;
   1.228 +      wVerReq = MAKEWORD( 2, 0 );
   1.229 +      err = WSAStartup(wVerReq,&wsaData);
   1.230 +      if (err != 0)
   1.231 +         {
   1.232 +         BIO_printf(bio_err,"unable to start WINSOCK2, error code=%d\n",err);
   1.233 +         return(0);
   1.234 +         }
   1.235 +      }
   1.236 +#endif /* OPENSSL_SYS_WINDOWS */
   1.237 +	return(1);
   1.238 +	}
   1.239 +
   1.240 +int init_client(int *sock, char *host, int port, int type)
   1.241 +	{
   1.242 +	unsigned char ip[4];
   1.243 +	short p=0;
   1.244 +
   1.245 +	if (!host_ip(host,&(ip[0])))
   1.246 +		{
   1.247 +		return(0);
   1.248 +		}
   1.249 +	if (p != 0) port=p;
   1.250 +	return(init_client_ip(sock,ip,port,type));
   1.251 +	}
   1.252 +
   1.253 +static int init_client_ip(int *sock, unsigned char ip[4], int port, int type)
   1.254 +	{
   1.255 +	unsigned long addr;
   1.256 +	struct sockaddr_in them;
   1.257 +	int s,i;
   1.258 +
   1.259 +	if (!ssl_sock_init()) return(0);
   1.260 +
   1.261 +	memset((char *)&them,0,sizeof(them));
   1.262 +	them.sin_family=AF_INET;
   1.263 +	them.sin_port=htons((unsigned short)port);
   1.264 +	addr=(unsigned long)
   1.265 +		((unsigned long)ip[0]<<24L)|
   1.266 +		((unsigned long)ip[1]<<16L)|
   1.267 +		((unsigned long)ip[2]<< 8L)|
   1.268 +		((unsigned long)ip[3]);
   1.269 +	them.sin_addr.s_addr=htonl(addr);
   1.270 +
   1.271 +	if (type == SOCK_STREAM)
   1.272 +		s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
   1.273 +	else /* ( type == SOCK_DGRAM) */
   1.274 +		s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
   1.275 +			
   1.276 +	if (s == INVALID_SOCKET) { perror("socket"); return(0); }
   1.277 +
   1.278 +#ifndef OPENSSL_SYS_MPE
   1.279 +	if (type == SOCK_STREAM)
   1.280 +		{
   1.281 +		i=0;
   1.282 +		i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
   1.283 +		if (i < 0) { perror("keepalive"); return(0); }
   1.284 +		}
   1.285 +#endif
   1.286 +
   1.287 +	if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
   1.288 +		{ close(s); perror("connect"); return(0); }
   1.289 +	*sock=s;
   1.290 +	return(1);
   1.291 +	}
   1.292 +
   1.293 +int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context)
   1.294 +	{
   1.295 +	int sock;
   1.296 +	char *name = NULL;
   1.297 +	int accept_socket;
   1.298 +	int i;
   1.299 +
   1.300 +	if (!init_server(&accept_socket,port,type)) return(0);
   1.301 +
   1.302 +	if (ret != NULL)
   1.303 +		{
   1.304 +		*ret=accept_socket;
   1.305 +		/* return(1);*/
   1.306 +		}
   1.307 +  	for (;;)
   1.308 +  		{
   1.309 +		if (type==SOCK_STREAM)
   1.310 +			{
   1.311 +			if (do_accept(accept_socket,&sock,&name) == 0)
   1.312 +				{
   1.313 +				SHUTDOWN(accept_socket);
   1.314 +				return(0);
   1.315 +				}
   1.316 +			}
   1.317 +		else
   1.318 +			sock = accept_socket;
   1.319 +		i=(*cb)(name,sock, context);
   1.320 +		if (name != NULL) OPENSSL_free(name);
   1.321 +		if (type==SOCK_STREAM)
   1.322 +			SHUTDOWN2(sock);
   1.323 +		if (i < 0)
   1.324 +			{
   1.325 +			SHUTDOWN2(accept_socket);
   1.326 +			return(i);
   1.327 +			}
   1.328 +		}
   1.329 +	}
   1.330 +
   1.331 +static int init_server_long(int *sock, int port, char *ip, int type)
   1.332 +	{
   1.333 +	int ret=0;
   1.334 +	struct sockaddr_in server;
   1.335 +	int s= -1,i;
   1.336 +
   1.337 +	if (!ssl_sock_init()) return(0);
   1.338 +
   1.339 +	memset((char *)&server,0,sizeof(server));
   1.340 +	server.sin_family=AF_INET;
   1.341 +	server.sin_port=htons((unsigned short)port);
   1.342 +	if (ip == NULL)
   1.343 +		server.sin_addr.s_addr=INADDR_ANY;
   1.344 +	else
   1.345 +/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */
   1.346 +#ifndef BIT_FIELD_LIMITS
   1.347 +		memcpy(&server.sin_addr.s_addr,ip,4);
   1.348 +#else
   1.349 +		memcpy(&server.sin_addr,ip,4);
   1.350 +#endif
   1.351 +	
   1.352 +		if (type == SOCK_STREAM)
   1.353 +			s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
   1.354 +		else /* type == SOCK_DGRAM */
   1.355 +			s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
   1.356 +
   1.357 +	if (s == INVALID_SOCKET) goto err;
   1.358 +#if defined SOL_SOCKET && defined SO_REUSEADDR
   1.359 +		{
   1.360 +		int j = 1;
   1.361 +		setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
   1.362 +			   (void *) &j, sizeof j);
   1.363 +		}
   1.364 +#endif
   1.365 +	if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
   1.366 +		{
   1.367 +#ifndef OPENSSL_SYS_WINDOWS
   1.368 +		perror("bind");
   1.369 +#endif
   1.370 +		goto err;
   1.371 +		}
   1.372 +	/* Make it 128 for linux */
   1.373 +	if (type==SOCK_STREAM && listen(s,128) == -1) goto err;
   1.374 +	i=0;
   1.375 +	*sock=s;
   1.376 +	ret=1;
   1.377 +err:
   1.378 +	if ((ret == 0) && (s != -1))
   1.379 +		{
   1.380 +		SHUTDOWN(s);
   1.381 +		}
   1.382 +	return(ret);
   1.383 +	}
   1.384 +
   1.385 +static int init_server(int *sock, int port, int type)
   1.386 +	{
   1.387 +	return(init_server_long(sock, port, NULL, type));
   1.388 +	}
   1.389 +
   1.390 +static int do_accept(int acc_sock, int *sock, char **host)
   1.391 +	{
   1.392 +	int ret,i;
   1.393 +	struct hostent *h1,*h2;
   1.394 +	static struct sockaddr_in from;
   1.395 +	int len;
   1.396 +/*	struct linger ling; */
   1.397 +
   1.398 +	if (!ssl_sock_init()) return(0);
   1.399 +
   1.400 +#ifndef OPENSSL_SYS_WINDOWS
   1.401 +redoit:
   1.402 +#endif
   1.403 +
   1.404 +	memset((char *)&from,0,sizeof(from));
   1.405 +	len=sizeof(from);
   1.406 +	/* Note: under VMS with SOCKETSHR the fourth parameter is currently
   1.407 +	 * of type (int *) whereas under other systems it is (void *) if
   1.408 +	 * you don't have a cast it will choke the compiler: if you do
   1.409 +	 * have a cast then you can either go for (int *) or (void *).
   1.410 +	 */
   1.411 +	ret=accept(acc_sock,(struct sockaddr *)&from,(void *)&len);
   1.412 +	if (ret == INVALID_SOCKET)
   1.413 +		{
   1.414 +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
   1.415 +		i=WSAGetLastError();
   1.416 +		BIO_printf(bio_err,"accept error %d\n",i);
   1.417 +#else
   1.418 +		if (errno == EINTR)
   1.419 +			{
   1.420 +			/*check_timeout(); */
   1.421 +			goto redoit;
   1.422 +			}
   1.423 +		fprintf(stderr,"errno=%d ",errno);
   1.424 +//		perror("accept");
   1.425 +
   1.426 +#endif
   1.427 +		return(0);
   1.428 +		}
   1.429 +
   1.430 +/*
   1.431 +	ling.l_onoff=1;
   1.432 +	ling.l_linger=0;
   1.433 +	i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling));
   1.434 +	if (i < 0) { perror("linger"); return(0); }
   1.435 +	i=0;
   1.436 +	i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
   1.437 +	if (i < 0) { perror("keepalive"); return(0); }
   1.438 +*/
   1.439 +
   1.440 +	if (host == NULL) goto end;
   1.441 +#ifndef BIT_FIELD_LIMITS
   1.442 +	/* I should use WSAAsyncGetHostByName() under windows */
   1.443 +	h1=gethostbyaddr((char *)&from.sin_addr.s_addr,
   1.444 +		sizeof(from.sin_addr.s_addr),AF_INET);
   1.445 +#else
   1.446 +	h1=gethostbyaddr((char *)&from.sin_addr,
   1.447 +		sizeof(struct in_addr),AF_INET);
   1.448 +#endif
   1.449 +	if (h1 == NULL)
   1.450 +		{
   1.451 +		BIO_printf(bio_err,"bad gethostbyaddr\n");
   1.452 +		*host=NULL;
   1.453 +		/* return(0); */
   1.454 +		}
   1.455 +	else
   1.456 +		{
   1.457 +		if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL)
   1.458 +			{
   1.459 +			perror("OPENSSL_malloc");
   1.460 +			return(0);
   1.461 +			}
   1.462 +		BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
   1.463 +
   1.464 +		h2=GetHostByName(*host);
   1.465 +		if (h2 == NULL)
   1.466 +			{
   1.467 +			BIO_printf(bio_err,"gethostbyname failure\n");
   1.468 +			return(0);
   1.469 +			}
   1.470 +		i=0;
   1.471 +		if (h2->h_addrtype != AF_INET)
   1.472 +			{
   1.473 +			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
   1.474 +			return(0);
   1.475 +			}
   1.476 +		}
   1.477 +end:
   1.478 +	*sock=ret;
   1.479 +	return(1);
   1.480 +	}
   1.481 +
   1.482 +int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
   1.483 +	     short *port_ptr)
   1.484 +	{
   1.485 +	char *h,*p;
   1.486 +
   1.487 +	h=str;
   1.488 +	p=strchr(str,':');
   1.489 +	if (p == NULL)
   1.490 +		{
   1.491 +		BIO_printf(bio_err,"no port defined\n");
   1.492 +		return(0);
   1.493 +		}
   1.494 +	*(p++)='\0';
   1.495 +
   1.496 +	if ((ip != NULL) && !host_ip(str,ip))
   1.497 +		goto err;
   1.498 +	if (host_ptr != NULL) *host_ptr=h;
   1.499 +
   1.500 +	if (!extract_port(p,port_ptr))
   1.501 +		goto err;
   1.502 +	return(1);
   1.503 +err:
   1.504 +	return(0);
   1.505 +	}
   1.506 +
   1.507 +static int host_ip(char *str, unsigned char ip[4])
   1.508 +	{
   1.509 +	unsigned int in[4]; 
   1.510 +	int i;
   1.511 +
   1.512 +	if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)
   1.513 +		{
   1.514 +		for (i=0; i<4; i++)
   1.515 +			if (in[i] > 255)
   1.516 +				{
   1.517 +				BIO_printf(bio_err,"invalid IP address\n");
   1.518 +				goto err;
   1.519 +				}
   1.520 +		ip[0]=in[0];
   1.521 +		ip[1]=in[1];
   1.522 +		ip[2]=in[2];
   1.523 +		ip[3]=in[3];
   1.524 +		}
   1.525 +	else
   1.526 +		{ /* do a gethostbyname */
   1.527 +		struct hostent *he;
   1.528 +
   1.529 +		if (!ssl_sock_init()) return(0);
   1.530 +
   1.531 +		he=GetHostByName(str);
   1.532 +		if (he == NULL)
   1.533 +			{
   1.534 +			BIO_printf(bio_err,"gethostbyname failure\n");
   1.535 +			goto err;
   1.536 +			}
   1.537 +		/* cast to short because of win16 winsock definition */
   1.538 +		if ((short)he->h_addrtype != AF_INET)
   1.539 +			{
   1.540 +			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
   1.541 +			return(0);
   1.542 +			}
   1.543 +		ip[0]=he->h_addr_list[0][0];
   1.544 +		ip[1]=he->h_addr_list[0][1];
   1.545 +		ip[2]=he->h_addr_list[0][2];
   1.546 +		ip[3]=he->h_addr_list[0][3];
   1.547 +		}
   1.548 +	return(1);
   1.549 +err:
   1.550 +	return(0);
   1.551 +	}
   1.552 +
   1.553 +int extract_port(char *str, short *port_ptr)
   1.554 +	{
   1.555 +	int i;
   1.556 +	struct servent *s;
   1.557 +
   1.558 +	i=atoi(str);
   1.559 +	if (i != 0)
   1.560 +		*port_ptr=(unsigned short)i;
   1.561 +	else
   1.562 +		{
   1.563 +		s=getservbyname(str,"tcp");
   1.564 +		if (s == NULL)
   1.565 +			{
   1.566 +			BIO_printf(bio_err,"getservbyname failure for %s\n",str);
   1.567 +			return(0);
   1.568 +			}
   1.569 +		*port_ptr=ntohs((unsigned short)s->s_port);
   1.570 +		}
   1.571 +	return(1);
   1.572 +	}
   1.573 +
   1.574 +#define GHBN_NUM	4
   1.575 +static struct ghbn_cache_st
   1.576 +	{
   1.577 +	char name[128];
   1.578 +	struct hostent ent;
   1.579 +	unsigned long order;
   1.580 +	} ghbn_cache[GHBN_NUM];
   1.581 +
   1.582 +static unsigned long ghbn_hits=0L;
   1.583 +static unsigned long ghbn_miss=0L;
   1.584 +
   1.585 +static struct hostent *GetHostByName(char *name)
   1.586 +	{
   1.587 +	struct hostent *ret;
   1.588 +	int i,lowi=0;
   1.589 +	unsigned long low= (unsigned long)-1;
   1.590 +
   1.591 +	for (i=0; i<GHBN_NUM; i++)
   1.592 +		{
   1.593 +		if (low > ghbn_cache[i].order)
   1.594 +			{
   1.595 +			low=ghbn_cache[i].order;
   1.596 +			lowi=i;
   1.597 +			}
   1.598 +		if (ghbn_cache[i].order > 0)
   1.599 +			{
   1.600 +			if (strncmp(name,ghbn_cache[i].name,128) == 0)
   1.601 +				break;
   1.602 +			}
   1.603 +		}
   1.604 +	if (i == GHBN_NUM) /* no hit*/
   1.605 +		{
   1.606 +		ghbn_miss++;
   1.607 +		ret=gethostbyname(name);
   1.608 +		if (ret == NULL) return(NULL);
   1.609 +		/* else add to cache */
   1.610 +		if(strlen(name) < sizeof ghbn_cache[0].name)
   1.611 +			{
   1.612 +			strcpy(ghbn_cache[lowi].name,name);
   1.613 +			memcpy((char *)&(ghbn_cache[lowi].ent),ret,sizeof(struct hostent));
   1.614 +			ghbn_cache[lowi].order=ghbn_miss+ghbn_hits;
   1.615 +			}
   1.616 +		return(ret);
   1.617 +		}
   1.618 +	else
   1.619 +		{
   1.620 +		ghbn_hits++;
   1.621 +		ret= &(ghbn_cache[i].ent);
   1.622 +		ghbn_cache[i].order=ghbn_miss+ghbn_hits;
   1.623 +		return(ret);
   1.624 +		}
   1.625 +	}
   1.626 +
   1.627 +#endif