ports

morpheus ports
git clone git://git.2f30.org/ports
Log | Files | Refs | LICENSE

openssl-1.0.1e-ipv6.patch (18596B)


      1 http://rt.openssl.org/Ticket/Display.html?id=2051
      2 user/pass: guest/guest
      3 
      4 Index: apps/s_apps.h
      5 ===================================================================
      6 RCS file: /v/openssl/cvs/openssl/apps/s_apps.h,v
      7 retrieving revision 1.21.2.1
      8 diff -u -r1.21.2.1 s_apps.h
      9 --- apps/s_apps.h	4 Sep 2009 17:42:04 -0000	1.21.2.1
     10 +++ apps/s_apps.h	28 Dec 2011 00:28:14 -0000
     11 @@ -148,7 +148,7 @@
     12  #define PORT_STR        "4433"
     13  #define PROTOCOL        "tcp"
     14  
     15 -int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context);
     16 +int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context, int use_ipv4, int use_ipv6);
     17  #ifdef HEADER_X509_H
     18  int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
     19  #endif
     20 @@ -156,7 +156,7 @@
     21  int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
     22  int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key);
     23  #endif
     24 -int init_client(int *sock, char *server, int port, int type);
     25 +int init_client(int *sock, char *server, int port, int type, int use_ipv4, int use_ipv6);
     26  int should_retry(int i);
     27  int extract_port(char *str, short *port_ptr);
     28  int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p);
     29 Index: apps/s_client.c
     30 ===================================================================
     31 RCS file: /v/openssl/cvs/openssl/apps/s_client.c,v
     32 retrieving revision 1.123.2.6.2.10
     33 diff -u -r1.123.2.6.2.10 s_client.c
     34 --- apps/s_client.c	14 Dec 2011 22:18:02 -0000	1.123.2.6.2.10
     35 +++ apps/s_client.c	28 Dec 2011 00:28:14 -0000
     36 @@ -285,6 +285,10 @@
     37  	{
     38  	BIO_printf(bio_err,"usage: s_client args\n");
     39  	BIO_printf(bio_err,"\n");
     40 +	BIO_printf(bio_err," -4             - use IPv4 only\n");
     41 +#if OPENSSL_USE_IPV6
     42 +	BIO_printf(bio_err," -6             - use IPv6 only\n");
     43 +#endif
     44  	BIO_printf(bio_err," -host host     - use -connect instead\n");
     45  	BIO_printf(bio_err," -port port     - use -connect instead\n");
     46  	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
     47 @@ -564,6 +567,7 @@
     48  	int sbuf_len,sbuf_off;
     49  	fd_set readfds,writefds;
     50  	short port=PORT;
     51 +	int use_ipv4, use_ipv6;
     52  	int full_log=1;
     53  	char *host=SSL_HOST_NAME;
     54  	char *cert_file=NULL,*key_file=NULL;
     55 @@ -609,7 +613,11 @@
     56  #endif
     57  	char *sess_in = NULL;
     58  	char *sess_out = NULL;
     59 -	struct sockaddr peer;
     60 +#if OPENSSL_USE_IPV6
     61 +	struct sockaddr_storage peer;
     62 +#else
     63 +	struct sockaddr_in peer;
     64 +#endif
     65  	int peerlen = sizeof(peer);
     66  	int enable_timeouts = 0 ;
     67  	long socket_mtu = 0;
     68 @@ -630,6 +638,12 @@
     69  	meth=SSLv2_client_method();
     70  #endif
     71  
     72 +	use_ipv4 = 1;
     73 +#if OPENSSL_USE_IPV6
     74 +	use_ipv6 = 1;
     75 +#else
     76 +	use_ipv6 = 0;
     77 +#endif
     78  	apps_startup();
     79  	c_Pause=0;
     80  	c_quiet=0;
     81 @@ -951,6 +961,18 @@
     82  			jpake_secret = *++argv;
     83  			}
     84  #endif
     85 +		else if (strcmp(*argv,"-4") == 0)
     86 +			{
     87 +			use_ipv4 = 1;
     88 +			use_ipv6 = 0;
     89 +			}
     90 +#if OPENSSL_USE_IPV6
     91 +		else if (strcmp(*argv,"-6") == 0)
     92 +			{
     93 +			use_ipv4 = 0;
     94 +			use_ipv6 = 1;
     95 +			}
     96 +#endif
     97  #ifndef OPENSSL_NO_SRTP
     98  		else if (strcmp(*argv,"-use_srtp") == 0)
     99  			{
    100 @@ -1259,7 +1276,7 @@
    101  
    102  re_start:
    103  
    104 -	if (init_client(&s,host,port,socket_type) == 0)
    105 +	if (init_client(&s,host,port,socket_type,use_ipv4,use_ipv6) == 0)
    106  		{
    107  		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
    108  		SHUTDOWN(s);
    109 @@ -1285,7 +1302,7 @@
    110  		{
    111  
    112  		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
    113 -		if (getsockname(s, &peer, (void *)&peerlen) < 0)
    114 +		if (getsockname(s, (struct sockaddr *)&peer, (void *)&peerlen) < 0)
    115  			{
    116  			BIO_printf(bio_err, "getsockname:errno=%d\n",
    117  				get_last_socket_error());
    118 ===================================================================
    119 RCS file: /v/openssl/cvs/openssl/apps/s_server.c,v
    120 retrieving revision 1.136.2.15.2.13
    121 diff -u -r1.136.2.15.2.13 s_server.c
    122 --- apps/s_server.c	27 Dec 2011 14:23:22 -0000	1.136.2.15.2.13
    123 +++ apps/s_server.c	28 Dec 2011 00:28:14 -0000
    124 @@ -558,6 +558,10 @@
    125  # endif
    126          BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list");
    127  #endif
    128 +	BIO_printf(bio_err," -4            - use IPv4 only\n");
    129 +#if OPENSSL_USE_IPV6
    130 +	BIO_printf(bio_err," -6            - use IPv6 only\n");
    131 +#endif
    132  	BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
    133  	BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
    134  	}
    135 @@ -943,6 +947,7 @@
    136  	int state=0;
    137  	const SSL_METHOD *meth=NULL;
    138  	int socket_type=SOCK_STREAM;
    139 +	int use_ipv4, use_ipv6;
    140  	ENGINE *e=NULL;
    141  	char *inrand=NULL;
    142  	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
    143 @@ -981,6 +986,12 @@
    144    /*  #error no SSL version enabled */
    145  #endif
    146  
    147 +	use_ipv4 = 1;
    148 +#if OPENSSL_USE_IPV6
    149 +	use_ipv6 = 1;
    150 +#else
    151 +	use_ipv6 = 0;
    152 +#endif
    153  	local_argc=argc;
    154  	local_argv=argv;
    155  
    156 @@ -1329,6 +1340,18 @@
    157  			jpake_secret = *(++argv);
    158  			}
    159  #endif
    160 +		else if (strcmp(*argv,"-4") == 0)
    161 +			{
    162 +			use_ipv4 = 1;
    163 +			use_ipv6 = 0;
    164 +			}
    165 +#if OPENSSL_USE_IPV6
    166 +		else if (strcmp(*argv,"-6") == 0)
    167 +			{
    168 +			use_ipv4 = 0;
    169 +			use_ipv6 = 1;
    170 +			}
    171 +#endif
    172  #ifndef OPENSSL_NO_SRTP
    173  		else if (strcmp(*argv,"-use_srtp") == 0)
    174  			{
    175 @@ -1884,9 +1907,9 @@
    176  	BIO_printf(bio_s_out,"ACCEPT\n");
    177  	(void)BIO_flush(bio_s_out);
    178  	if (www)
    179 -		do_server(port,socket_type,&accept_socket,www_body, context);
    180 +		do_server(port,socket_type,&accept_socket,www_body, context, use_ipv4, use_ipv6);
    181  	else
    182 -		do_server(port,socket_type,&accept_socket,sv_body, context);
    183 +		do_server(port,socket_type,&accept_socket,sv_body, context, use_ipv4, use_ipv6);
    184  	print_stats(bio_s_out,ctx);
    185  	ret=0;
    186  end:
    187 Index: apps/s_socket.c
    188 ===================================================================
    189 RCS file: /v/openssl/cvs/openssl/apps/s_socket.c,v
    190 retrieving revision 1.43.2.3.2.2
    191 diff -u -r1.43.2.3.2.2 s_socket.c
    192 --- apps/s_socket.c	2 Dec 2011 14:39:40 -0000	1.43.2.3.2.2
    193 +++ apps/s_socket.c	28 Dec 2011 00:28:14 -0000
    194 @@ -97,16 +97,16 @@
    195  #include "netdb.h"
    196  #endif
    197  
    198 -static struct hostent *GetHostByName(char *name);
    199 +static struct hostent *GetHostByName(char *name, int domain);
    200  #if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
    201  static void ssl_sock_cleanup(void);
    202  #endif
    203  static int ssl_sock_init(void);
    204 -static int init_client_ip(int *sock,unsigned char ip[4], int port, int type);
    205 -static int init_server(int *sock, int port, int type);
    206 -static int init_server_long(int *sock, int port,char *ip, int type);
    207 +static int init_client_ip(int *sock,unsigned char *ip, int port, int type, int domain);
    208 +static int init_server(int *sock, int port, int type, int use_ipv4, int use_ipv6);
    209 +static int init_server_long(int *sock, int port,char *ip, int type, int use_ipv4, int use_ipv6);
    210  static int do_accept(int acc_sock, int *sock, char **host);
    211 -static int host_ip(char *str, unsigned char ip[4]);
    212 +static int host_ip(char *str, unsigned char *ip, int domain);
    213  
    214  #ifdef OPENSSL_SYS_WIN16
    215  #define SOCKET_PROTOCOL	0 /* more microsoft stupidity */
    216 @@ -234,38 +234,68 @@
    217  	return(1);
    218  	}
    219  
    220 -int init_client(int *sock, char *host, int port, int type)
    221 +int init_client(int *sock, char *host, int port, int type, int use_ipv4, int use_ipv6)
    222  	{
    223 +#if OPENSSL_USE_IPV6
    224 +	unsigned char ip[16];
    225 +#else
    226  	unsigned char ip[4];
    227 +#endif
    228  
    229 -	memset(ip, '\0', sizeof ip);
    230 -	if (!host_ip(host,&(ip[0])))
    231 -		return 0;
    232 -	return init_client_ip(sock,ip,port,type);
    233 -	}
    234 -
    235 -static int init_client_ip(int *sock, unsigned char ip[4], int port, int type)
    236 -	{
    237 -	unsigned long addr;
    238 +	if (use_ipv4)
    239 +		if (host_ip(host,ip,AF_INET))
    240 +			return(init_client_ip(sock,ip,port,type,AF_INET));
    241 +#if OPENSSL_USE_IPV6
    242 +	if (use_ipv6)
    243 +		if (host_ip(host,ip,AF_INET6))
    244 +			return(init_client_ip(sock,ip,port,type,AF_INET6));
    245 +#endif
    246 +	return 0;
    247 +	}
    248 +
    249 +static int init_client_ip(int *sock, unsigned char ip[4], int port, int type, int domain)
    250 +	{
    251 +#if OPENSSL_USE_IPV6
    252 +	struct sockaddr_storage them;
    253 +	struct sockaddr_in *them_in = (struct sockaddr_in *)&them;
    254 +	struct sockaddr_in6 *them_in6 = (struct sockaddr_in6 *)&them;
    255 +#else
    256  	struct sockaddr_in them;
    257 +	struct sockaddr_in *them_in = &them;
    258 +#endif
    259 +	socklen_t addr_len;
    260  	int s,i;
    261  
    262  	if (!ssl_sock_init()) return(0);
    263  
    264  	memset((char *)&them,0,sizeof(them));
    265 -	them.sin_family=AF_INET;
    266 -	them.sin_port=htons((unsigned short)port);
    267 -	addr=(unsigned long)
    268 -		((unsigned long)ip[0]<<24L)|
    269 -		((unsigned long)ip[1]<<16L)|
    270 -		((unsigned long)ip[2]<< 8L)|
    271 -		((unsigned long)ip[3]);
    272 -	them.sin_addr.s_addr=htonl(addr);
    273 +	if (domain == AF_INET)
    274 +		{
    275 +		addr_len = (socklen_t)sizeof(struct sockaddr_in);
    276 +		them_in->sin_family=AF_INET;
    277 +		them_in->sin_port=htons((unsigned short)port);
    278 +#ifndef BIT_FIELD_LIMITS
    279 +		memcpy(&them_in->sin_addr.s_addr, ip, 4);
    280 +#else
    281 +		memcpy(&them_in->sin_addr, ip, 4);
    282 +#endif
    283 +		}
    284 +	else
    285 +#if OPENSSL_USE_IPV6
    286 +		{
    287 +		addr_len = (socklen_t)sizeof(struct sockaddr_in6);
    288 +		them_in6->sin6_family=AF_INET6;
    289 +		them_in6->sin6_port=htons((unsigned short)port);
    290 +		memcpy(&(them_in6->sin6_addr), ip, sizeof(struct in6_addr));
    291 +		}
    292 +#else
    293 +		return(0);
    294 +#endif
    295  
    296  	if (type == SOCK_STREAM)
    297 -		s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
    298 +		s=socket(domain,SOCK_STREAM,SOCKET_PROTOCOL);
    299  	else /* ( type == SOCK_DGRAM) */
    300 -		s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    301 +		s=socket(domain,SOCK_DGRAM,IPPROTO_UDP);
    302  			
    303  	if (s == INVALID_SOCKET) { perror("socket"); return(0); }
    304  
    305 @@ -277,29 +315,27 @@
    306  		if (i < 0) { perror("keepalive"); return(0); }
    307  		}
    308  #endif
    309 -
    310 -	if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
    311 +	if (connect(s,(struct sockaddr *)&them,addr_len) == -1)
    312  		{ closesocket(s); perror("connect"); return(0); }
    313  	*sock=s;
    314  	return(1);
    315  	}
    316  
    317 -int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context)
    318 +int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context, int use_ipv4, int use_ipv6)
    319  	{
    320  	int sock;
    321  	char *name = NULL;
    322  	int accept_socket = 0;
    323  	int i;
    324  
    325 -	if (!init_server(&accept_socket,port,type)) return(0);
    326 -
    327 +	if (!init_server(&accept_socket,port,type, use_ipv4, use_ipv6)) return(0);
    328  	if (ret != NULL)
    329  		{
    330  		*ret=accept_socket;
    331  		/* return(1);*/
    332  		}
    333 -  	for (;;)
    334 -  		{
    335 +	for (;;)
    336 +		{
    337  		if (type==SOCK_STREAM)
    338  			{
    339  			if (do_accept(accept_socket,&sock,&name) == 0)
    340 @@ -322,41 +358,88 @@
    341  		}
    342  	}
    343  
    344 -static int init_server_long(int *sock, int port, char *ip, int type)
    345 +static int init_server_long(int *sock, int port, char *ip, int type, int use_ipv4, int use_ipv6)
    346  	{
    347  	int ret=0;
    348 +	int domain;
    349 +#if OPENSSL_USE_IPV6
    350 +	struct sockaddr_storage server;
    351 +	struct sockaddr_in *server_in = (struct sockaddr_in *)&server;
    352 +	struct sockaddr_in6 *server_in6 = (struct sockaddr_in6 *)&server;
    353 +#else
    354  	struct sockaddr_in server;
    355 +	struct sockaddr_in *server_in = &server;
    356 +#endif
    357 +	socklen_t addr_len;
    358  	int s= -1;
    359  
    360 +	if (!use_ipv4 && !use_ipv6)
    361 +		goto err;
    362 +#if OPENSSL_USE_IPV6
    363 +	/* we are fine here */
    364 +#else
    365 +	if (use_ipv6)
    366 +		goto err;
    367 +#endif
    368  	if (!ssl_sock_init()) return(0);
    369  
    370 -	memset((char *)&server,0,sizeof(server));
    371 -	server.sin_family=AF_INET;
    372 -	server.sin_port=htons((unsigned short)port);
    373 -	if (ip == NULL)
    374 -		server.sin_addr.s_addr=INADDR_ANY;
    375 -	else
    376 -/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */
    377 -#ifndef BIT_FIELD_LIMITS
    378 -		memcpy(&server.sin_addr.s_addr,ip,4);
    379 +#if OPENSSL_USE_IPV6
    380 +	domain = use_ipv6 ? AF_INET6 : AF_INET;
    381  #else
    382 -		memcpy(&server.sin_addr,ip,4);
    383 +	domain = AF_INET;
    384  #endif
    385 -	
    386 -		if (type == SOCK_STREAM)
    387 -			s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
    388 -		else /* type == SOCK_DGRAM */
    389 -			s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
    390 +	if (type == SOCK_STREAM)
    391 +		s=socket(domain,SOCK_STREAM,SOCKET_PROTOCOL);
    392 +	else /* type == SOCK_DGRAM */
    393 +		s=socket(domain, SOCK_DGRAM,IPPROTO_UDP);
    394  
    395  	if (s == INVALID_SOCKET) goto err;
    396  #if defined SOL_SOCKET && defined SO_REUSEADDR
    397 +	{
    398 +	int j = 1;
    399 +	setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
    400 +		   (void *) &j, sizeof j);
    401 +	}
    402 +#endif
    403 +#if OPENSSL_USE_IPV6
    404 +	if ((use_ipv4 == 0) && (use_ipv6 == 1))
    405  		{
    406 -		int j = 1;
    407 -		setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
    408 -			   (void *) &j, sizeof j);
    409 +		const int on = 1;
    410 +
    411 +		setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
    412 +		           (const void *) &on, sizeof(int));
    413  		}
    414  #endif
    415 -	if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
    416 +	if (domain == AF_INET)
    417 +		{
    418 +		addr_len = (socklen_t)sizeof(struct sockaddr_in);
    419 +		memset(server_in, 0, sizeof(struct sockaddr_in));
    420 +		server_in->sin_family=AF_INET;
    421 +		server_in->sin_port = htons((unsigned short)port);
    422 +		if (ip == NULL)
    423 +			server_in->sin_addr.s_addr = htonl(INADDR_ANY);
    424 +		else
    425 +/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */
    426 +#ifndef BIT_FIELD_LIMITS
    427 +			memcpy(&server_in->sin_addr.s_addr, ip, 4);
    428 +#else
    429 +			memcpy(&server_in->sin_addr, ip, 4);
    430 +#endif
    431 +		}
    432 +#if OPENSSL_USE_IPV6
    433 +	else
    434 +		{
    435 +		addr_len = (socklen_t)sizeof(struct sockaddr_in6);
    436 +		memset(server_in6, 0, sizeof(struct sockaddr_in6));
    437 +		server_in6->sin6_family = AF_INET6;
    438 +		server_in6->sin6_port = htons((unsigned short)port);
    439 +		if (ip == NULL)
    440 +			server_in6->sin6_addr = in6addr_any;
    441 +		else
    442 +			memcpy(&server_in6->sin6_addr, ip, sizeof(struct in6_addr));
    443 +		}
    444 +#endif
    445 +	if (bind(s, (struct sockaddr *)&server, addr_len) == -1)
    446  		{
    447  #ifndef OPENSSL_SYS_WINDOWS
    448  		perror("bind");
    449 @@ -375,16 +458,23 @@
    450  	return(ret);
    451  	}
    452  
    453 -static int init_server(int *sock, int port, int type)
    454 +static int init_server(int *sock, int port, int type, int use_ipv4, int use_ipv6)
    455  	{
    456 -	return(init_server_long(sock, port, NULL, type));
    457 +	return(init_server_long(sock, port, NULL, type, use_ipv4, use_ipv6));
    458  	}
    459  
    460  static int do_accept(int acc_sock, int *sock, char **host)
    461  	{
    462  	int ret;
    463  	struct hostent *h1,*h2;
    464 -	static struct sockaddr_in from;
    465 +#if OPENSSL_USE_IPV6
    466 +	struct sockaddr_storage from;
    467 +	struct sockaddr_in *from_in = (struct sockaddr_in *)&from;
    468 +	struct sockaddr_in6 *from_in6 = (struct sockaddr_in6 *)&from;
    469 +#else
    470 +	struct sockaddr_in from;
    471 +	struct sockaddr_in *from_in = &from;
    472 +#endif
    473  	int len;
    474  /*	struct linger ling; */
    475  
    476 @@ -431,13 +521,23 @@
    477  */
    478  
    479  	if (host == NULL) goto end;
    480 +#if OPENSSL_USE_IPV6
    481 +	if (from.ss_family == AF_INET)
    482 +#else
    483 +	if (from.sin_family == AF_INET)
    484 +#endif
    485  #ifndef BIT_FIELD_LIMITS
    486 -	/* I should use WSAAsyncGetHostByName() under windows */
    487 -	h1=gethostbyaddr((char *)&from.sin_addr.s_addr,
    488 -		sizeof(from.sin_addr.s_addr),AF_INET);
    489 +		/* I should use WSAAsyncGetHostByName() under windows */
    490 +		h1=gethostbyaddr((char *)&from_in->sin_addr.s_addr,
    491 +		                 sizeof(from_in->sin_addr.s_addr), AF_INET);
    492  #else
    493 -	h1=gethostbyaddr((char *)&from.sin_addr,
    494 -		sizeof(struct in_addr),AF_INET);
    495 +		h1=gethostbyaddr((char *)&from_in->sin_addr,
    496 +		                 sizeof(struct in_addr), AF_INET);
    497 +#endif
    498 +#if OPENSSL_USE_IPV6
    499 +	else
    500 +		h1=gethostbyaddr((char *)&from_in6->sin6_addr,
    501 +		                 sizeof(struct in6_addr), AF_INET6);
    502  #endif
    503  	if (h1 == NULL)
    504  		{
    505 @@ -454,15 +554,23 @@
    506  			}
    507  		BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
    508  
    509 -		h2=GetHostByName(*host);
    510 +#if OPENSSL_USE_IPV6
    511 +		h2=GetHostByName(*host, from.ss_family);
    512 +#else
    513 +		h2=GetHostByName(*host, from.sin_family);
    514 +#endif
    515  		if (h2 == NULL)
    516  			{
    517  			BIO_printf(bio_err,"gethostbyname failure\n");
    518  			return(0);
    519  			}
    520 -		if (h2->h_addrtype != AF_INET)
    521 +#if OPENSSL_USE_IPV6
    522 +		if (h2->h_addrtype != from.ss_family)
    523 +#else
    524 +		if (h2->h_addrtype != from.sin_family)
    525 +#endif
    526  			{
    527 -			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
    528 +			BIO_printf(bio_err,"gethostbyname addr address is not correct\n");
    529  			return(0);
    530  			}
    531  		}
    532 @@ -477,7 +585,7 @@
    533  	char *h,*p;
    534  
    535  	h=str;
    536 -	p=strchr(str,':');
    537 +	p=strrchr(str,':');
    538  	if (p == NULL)
    539  		{
    540  		BIO_printf(bio_err,"no port defined\n");
    541 @@ -485,7 +593,7 @@
    542  		}
    543  	*(p++)='\0';
    544  
    545 -	if ((ip != NULL) && !host_ip(str,ip))
    546 +	if ((ip != NULL) && !host_ip(str,ip,AF_INET))
    547  		goto err;
    548  	if (host_ptr != NULL) *host_ptr=h;
    549  
    550 @@ -496,48 +604,58 @@
    551  	return(0);
    552  	}
    553  
    554 -static int host_ip(char *str, unsigned char ip[4])
    555 +static int host_ip(char *str, unsigned char *ip, int domain)
    556  	{
    557 -	unsigned int in[4]; 
    558 +	unsigned int in[4];
    559 +	unsigned long l;
    560  	int i;
    561  
    562 -	if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)
    563 +	if ((domain == AF_INET) &&
    564 +	    (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4))
    565  		{
    566 +		
    567  		for (i=0; i<4; i++)
    568  			if (in[i] > 255)
    569  				{
    570  				BIO_printf(bio_err,"invalid IP address\n");
    571  				goto err;
    572  				}
    573 -		ip[0]=in[0];
    574 -		ip[1]=in[1];
    575 -		ip[2]=in[2];
    576 -		ip[3]=in[3];
    577 -		}
    578 +		l=htonl((in[0]<<24L)|(in[1]<<16L)|(in[2]<<8L)|in[3]);
    579 +		memcpy(ip, &l, 4);
    580 +		return 1;
    581 +		}
    582 +#if OPENSSL_USE_IPV6
    583 +	else if ((domain == AF_INET6) &&
    584 +	         (inet_pton(AF_INET6, str, ip) == 1))
    585 +	         return 1;
    586 +#endif
    587  	else
    588  		{ /* do a gethostbyname */
    589  		struct hostent *he;
    590  
    591  		if (!ssl_sock_init()) return(0);
    592  
    593 -		he=GetHostByName(str);
    594 +		he=GetHostByName(str,domain);
    595  		if (he == NULL)
    596  			{
    597  			BIO_printf(bio_err,"gethostbyname failure\n");
    598  			goto err;
    599  			}
    600  		/* cast to short because of win16 winsock definition */
    601 -		if ((short)he->h_addrtype != AF_INET)
    602 +		if ((short)he->h_addrtype != domain)
    603  			{
    604 -			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
    605 +			BIO_printf(bio_err,"gethostbyname addr family is not correct\n");
    606  			return(0);
    607  			}
    608 -		ip[0]=he->h_addr_list[0][0];
    609 -		ip[1]=he->h_addr_list[0][1];
    610 -		ip[2]=he->h_addr_list[0][2];
    611 -		ip[3]=he->h_addr_list[0][3];
    612 +		if (domain == AF_INET)
    613 +			memset(ip, 0, 4);
    614 +#if OPENSSL_USE_IPV6
    615 +		else
    616 +			memset(ip, 0, 16);
    617 +#endif
    618 +		memcpy(ip, he->h_addr_list[0], he->h_length);
    619 +		return 1;
    620  		}
    621 -	return(1);
    622  err:
    623  	return(0);
    624  	}
    625 @@ -574,7 +692,7 @@
    626  static unsigned long ghbn_hits=0L;
    627  static unsigned long ghbn_miss=0L;
    628  
    629 -static struct hostent *GetHostByName(char *name)
    630 +static struct hostent *GetHostByName(char *name, int domain)
    631  	{
    632  	struct hostent *ret;
    633  	int i,lowi=0;
    634 @@ -589,14 +707,20 @@
    635  			}
    636  		if (ghbn_cache[i].order > 0)
    637  			{
    638 -			if (strncmp(name,ghbn_cache[i].name,128) == 0)
    639 +			if ((strncmp(name,ghbn_cache[i].name,128) == 0) &&
    640 +			    (ghbn_cache[i].ent.h_addrtype == domain))
    641  				break;
    642  			}
    643  		}
    644  	if (i == GHBN_NUM) /* no hit*/
    645  		{
    646  		ghbn_miss++;
    647 -		ret=gethostbyname(name);
    648 +		if (domain == AF_INET)
    649 +			ret=gethostbyname(name);
    650 +#if OPENSSL_USE_IPV6
    651 +		else
    652 +			ret=gethostbyname2(name, AF_INET6);
    653 +#endif
    654  		if (ret == NULL) return(NULL);
    655  		/* else add to cache */
    656  		if(strlen(name) < sizeof ghbn_cache[0].name)