| http://rt.openssl.org/Ticket/Display.html?id=2051 |
| user/pass: guest/guest |
| |
| Index: apps/s_apps.h |
| =================================================================== |
| RCS file: /v/openssl/cvs/openssl/apps/s_apps.h,v |
| retrieving revision 1.21.2.1 |
| diff -u -r1.21.2.1 s_apps.h |
| --- apps/s_apps.h 4 Sep 2009 17:42:04 -0000 1.21.2.1 |
| +++ apps/s_apps.h 28 Dec 2011 00:28:14 -0000 |
| @@ -148,7 +148,7 @@ |
| #define PORT_STR "4433" |
| #define PROTOCOL "tcp" |
| |
| -int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); |
| +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); |
| #ifdef HEADER_X509_H |
| int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); |
| #endif |
| @@ -156,7 +156,7 @@ |
| int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); |
| int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); |
| #endif |
| -int init_client(int *sock, char *server, int port, int type); |
| +int init_client(int *sock, char *server, int port, int type, int use_ipv4, int use_ipv6); |
| int should_retry(int i); |
| int extract_port(char *str, short *port_ptr); |
| int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p); |
| Index: apps/s_client.c |
| =================================================================== |
| RCS file: /v/openssl/cvs/openssl/apps/s_client.c,v |
| retrieving revision 1.123.2.6.2.10 |
| diff -u -r1.123.2.6.2.10 s_client.c |
| --- apps/s_client.c 14 Dec 2011 22:18:02 -0000 1.123.2.6.2.10 |
| +++ apps/s_client.c 28 Dec 2011 00:28:14 -0000 |
| @@ -285,6 +285,10 @@ |
| { |
| BIO_printf(bio_err,"usage: s_client args\n"); |
| BIO_printf(bio_err,"\n"); |
| + BIO_printf(bio_err," -4 - use IPv4 only\n"); |
| +#if OPENSSL_USE_IPV6 |
| + BIO_printf(bio_err," -6 - use IPv6 only\n"); |
| +#endif |
| BIO_printf(bio_err," -host host - use -connect instead\n"); |
| BIO_printf(bio_err," -port port - use -connect instead\n"); |
| BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); |
| @@ -564,6 +567,7 @@ |
| int sbuf_len,sbuf_off; |
| fd_set readfds,writefds; |
| short port=PORT; |
| + int use_ipv4, use_ipv6; |
| int full_log=1; |
| char *host=SSL_HOST_NAME; |
| char *cert_file=NULL,*key_file=NULL; |
| @@ -609,7 +613,11 @@ |
| #endif |
| char *sess_in = NULL; |
| char *sess_out = NULL; |
| - struct sockaddr peer; |
| +#if OPENSSL_USE_IPV6 |
| + struct sockaddr_storage peer; |
| +#else |
| + struct sockaddr_in peer; |
| +#endif |
| int peerlen = sizeof(peer); |
| int enable_timeouts = 0 ; |
| long socket_mtu = 0; |
| @@ -630,6 +638,12 @@ |
| meth=SSLv2_client_method(); |
| #endif |
| |
| + use_ipv4 = 1; |
| +#if OPENSSL_USE_IPV6 |
| + use_ipv6 = 1; |
| +#else |
| + use_ipv6 = 0; |
| +#endif |
| apps_startup(); |
| c_Pause=0; |
| c_quiet=0; |
| @@ -951,6 +961,18 @@ |
| jpake_secret = *++argv; |
| } |
| #endif |
| + else if (strcmp(*argv,"-4") == 0) |
| + { |
| + use_ipv4 = 1; |
| + use_ipv6 = 0; |
| + } |
| +#if OPENSSL_USE_IPV6 |
| + else if (strcmp(*argv,"-6") == 0) |
| + { |
| + use_ipv4 = 0; |
| + use_ipv6 = 1; |
| + } |
| +#endif |
| #ifndef OPENSSL_NO_SRTP |
| else if (strcmp(*argv,"-use_srtp") == 0) |
| { |
| @@ -1259,7 +1276,7 @@ |
| |
| re_start: |
| |
| - if (init_client(&s,host,port,socket_type) == 0) |
| + if (init_client(&s,host,port,socket_type,use_ipv4,use_ipv6) == 0) |
| { |
| BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); |
| SHUTDOWN(s); |
| @@ -1285,7 +1302,7 @@ |
| { |
| |
| sbio=BIO_new_dgram(s,BIO_NOCLOSE); |
| - if (getsockname(s, &peer, (void *)&peerlen) < 0) |
| + if (getsockname(s, (struct sockaddr *)&peer, (void *)&peerlen) < 0) |
| { |
| BIO_printf(bio_err, "getsockname:errno=%d\n", |
| get_last_socket_error()); |
| =================================================================== |
| RCS file: /v/openssl/cvs/openssl/apps/s_server.c,v |
| retrieving revision 1.136.2.15.2.13 |
| diff -u -r1.136.2.15.2.13 s_server.c |
| --- apps/s_server.c 27 Dec 2011 14:23:22 -0000 1.136.2.15.2.13 |
| +++ apps/s_server.c 28 Dec 2011 00:28:14 -0000 |
| @@ -558,6 +558,10 @@ |
| # endif |
| BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list"); |
| #endif |
| + BIO_printf(bio_err," -4 - use IPv4 only\n"); |
| +#if OPENSSL_USE_IPV6 |
| + BIO_printf(bio_err," -6 - use IPv6 only\n"); |
| +#endif |
| BIO_printf(bio_err," -keymatexport label - Export keying material using label\n"); |
| BIO_printf(bio_err," -keymatexportlen len - Export len bytes of keying material (default 20)\n"); |
| } |
| @@ -943,6 +947,7 @@ |
| int state=0; |
| const SSL_METHOD *meth=NULL; |
| int socket_type=SOCK_STREAM; |
| + int use_ipv4, use_ipv6; |
| ENGINE *e=NULL; |
| char *inrand=NULL; |
| int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; |
| @@ -981,6 +986,12 @@ |
| /* #error no SSL version enabled */ |
| #endif |
| |
| + use_ipv4 = 1; |
| +#if OPENSSL_USE_IPV6 |
| + use_ipv6 = 1; |
| +#else |
| + use_ipv6 = 0; |
| +#endif |
| local_argc=argc; |
| local_argv=argv; |
| |
| @@ -1329,6 +1340,18 @@ |
| jpake_secret = *(++argv); |
| } |
| #endif |
| + else if (strcmp(*argv,"-4") == 0) |
| + { |
| + use_ipv4 = 1; |
| + use_ipv6 = 0; |
| + } |
| +#if OPENSSL_USE_IPV6 |
| + else if (strcmp(*argv,"-6") == 0) |
| + { |
| + use_ipv4 = 0; |
| + use_ipv6 = 1; |
| + } |
| +#endif |
| #ifndef OPENSSL_NO_SRTP |
| else if (strcmp(*argv,"-use_srtp") == 0) |
| { |
| @@ -1884,9 +1907,9 @@ |
| BIO_printf(bio_s_out,"ACCEPT\n"); |
| (void)BIO_flush(bio_s_out); |
| if (www) |
| - do_server(port,socket_type,&accept_socket,www_body, context); |
| + do_server(port,socket_type,&accept_socket,www_body, context, use_ipv4, use_ipv6); |
| else |
| - do_server(port,socket_type,&accept_socket,sv_body, context); |
| + do_server(port,socket_type,&accept_socket,sv_body, context, use_ipv4, use_ipv6); |
| print_stats(bio_s_out,ctx); |
| ret=0; |
| end: |
| Index: apps/s_socket.c |
| =================================================================== |
| RCS file: /v/openssl/cvs/openssl/apps/s_socket.c,v |
| retrieving revision 1.43.2.3.2.2 |
| diff -u -r1.43.2.3.2.2 s_socket.c |
| --- apps/s_socket.c 2 Dec 2011 14:39:40 -0000 1.43.2.3.2.2 |
| +++ apps/s_socket.c 28 Dec 2011 00:28:14 -0000 |
| @@ -97,16 +97,16 @@ |
| #include "netdb.h" |
| #endif |
| |
| -static struct hostent *GetHostByName(char *name); |
| +static struct hostent *GetHostByName(char *name, int domain); |
| #if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) |
| static void ssl_sock_cleanup(void); |
| #endif |
| static int ssl_sock_init(void); |
| -static int init_client_ip(int *sock,unsigned char ip[4], int port, int type); |
| -static int init_server(int *sock, int port, int type); |
| -static int init_server_long(int *sock, int port,char *ip, int type); |
| +static int init_client_ip(int *sock,unsigned char *ip, int port, int type, int domain); |
| +static int init_server(int *sock, int port, int type, int use_ipv4, int use_ipv6); |
| +static int init_server_long(int *sock, int port,char *ip, int type, int use_ipv4, int use_ipv6); |
| static int do_accept(int acc_sock, int *sock, char **host); |
| -static int host_ip(char *str, unsigned char ip[4]); |
| +static int host_ip(char *str, unsigned char *ip, int domain); |
| |
| #ifdef OPENSSL_SYS_WIN16 |
| #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ |
| @@ -234,38 +234,68 @@ |
| return(1); |
| } |
| |
| -int init_client(int *sock, char *host, int port, int type) |
| +int init_client(int *sock, char *host, int port, int type, int use_ipv4, int use_ipv6) |
| { |
| +#if OPENSSL_USE_IPV6 |
| + unsigned char ip[16]; |
| +#else |
| unsigned char ip[4]; |
| +#endif |
| |
| - memset(ip, '\0', sizeof ip); |
| - if (!host_ip(host,&(ip[0]))) |
| - return 0; |
| - return init_client_ip(sock,ip,port,type); |
| - } |
| - |
| -static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) |
| - { |
| - unsigned long addr; |
| + if (use_ipv4) |
| + if (host_ip(host,ip,AF_INET)) |
| + return(init_client_ip(sock,ip,port,type,AF_INET)); |
| +#if OPENSSL_USE_IPV6 |
| + if (use_ipv6) |
| + if (host_ip(host,ip,AF_INET6)) |
| + return(init_client_ip(sock,ip,port,type,AF_INET6)); |
| +#endif |
| + return 0; |
| + } |
| + |
| +static int init_client_ip(int *sock, unsigned char ip[4], int port, int type, int domain) |
| + { |
| +#if OPENSSL_USE_IPV6 |
| + struct sockaddr_storage them; |
| + struct sockaddr_in *them_in = (struct sockaddr_in *)&them; |
| + struct sockaddr_in6 *them_in6 = (struct sockaddr_in6 *)&them; |
| +#else |
| struct sockaddr_in them; |
| + struct sockaddr_in *them_in = &them; |
| +#endif |
| + socklen_t addr_len; |
| int s,i; |
| |
| if (!ssl_sock_init()) return(0); |
| |
| memset((char *)&them,0,sizeof(them)); |
| - them.sin_family=AF_INET; |
| - them.sin_port=htons((unsigned short)port); |
| - addr=(unsigned long) |
| - ((unsigned long)ip[0]<<24L)| |
| - ((unsigned long)ip[1]<<16L)| |
| - ((unsigned long)ip[2]<< 8L)| |
| - ((unsigned long)ip[3]); |
| - them.sin_addr.s_addr=htonl(addr); |
| + if (domain == AF_INET) |
| + { |
| + addr_len = (socklen_t)sizeof(struct sockaddr_in); |
| + them_in->sin_family=AF_INET; |
| + them_in->sin_port=htons((unsigned short)port); |
| +#ifndef BIT_FIELD_LIMITS |
| + memcpy(&them_in->sin_addr.s_addr, ip, 4); |
| +#else |
| + memcpy(&them_in->sin_addr, ip, 4); |
| +#endif |
| + } |
| + else |
| +#if OPENSSL_USE_IPV6 |
| + { |
| + addr_len = (socklen_t)sizeof(struct sockaddr_in6); |
| + them_in6->sin6_family=AF_INET6; |
| + them_in6->sin6_port=htons((unsigned short)port); |
| + memcpy(&(them_in6->sin6_addr), ip, sizeof(struct in6_addr)); |
| + } |
| +#else |
| + return(0); |
| +#endif |
| |
| if (type == SOCK_STREAM) |
| - s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); |
| + s=socket(domain,SOCK_STREAM,SOCKET_PROTOCOL); |
| else /* ( type == SOCK_DGRAM) */ |
| - s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); |
| + s=socket(domain,SOCK_DGRAM,IPPROTO_UDP); |
| |
| if (s == INVALID_SOCKET) { perror("socket"); return(0); } |
| |
| @@ -277,29 +315,27 @@ |
| if (i < 0) { perror("keepalive"); return(0); } |
| } |
| #endif |
| - |
| - if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) |
| + if (connect(s,(struct sockaddr *)&them,addr_len) == -1) |
| { closesocket(s); perror("connect"); return(0); } |
| *sock=s; |
| return(1); |
| } |
| |
| -int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) |
| +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) |
| { |
| int sock; |
| char *name = NULL; |
| int accept_socket = 0; |
| int i; |
| |
| - if (!init_server(&accept_socket,port,type)) return(0); |
| - |
| + if (!init_server(&accept_socket,port,type, use_ipv4, use_ipv6)) return(0); |
| if (ret != NULL) |
| { |
| *ret=accept_socket; |
| /* return(1);*/ |
| } |
| - for (;;) |
| - { |
| + for (;;) |
| + { |
| if (type==SOCK_STREAM) |
| { |
| if (do_accept(accept_socket,&sock,&name) == 0) |
| @@ -322,41 +358,88 @@ |
| } |
| } |
| |
| -static int init_server_long(int *sock, int port, char *ip, int type) |
| +static int init_server_long(int *sock, int port, char *ip, int type, int use_ipv4, int use_ipv6) |
| { |
| int ret=0; |
| + int domain; |
| +#if OPENSSL_USE_IPV6 |
| + struct sockaddr_storage server; |
| + struct sockaddr_in *server_in = (struct sockaddr_in *)&server; |
| + struct sockaddr_in6 *server_in6 = (struct sockaddr_in6 *)&server; |
| +#else |
| struct sockaddr_in server; |
| + struct sockaddr_in *server_in = &server; |
| +#endif |
| + socklen_t addr_len; |
| int s= -1; |
| |
| + if (!use_ipv4 && !use_ipv6) |
| + goto err; |
| +#if OPENSSL_USE_IPV6 |
| + /* we are fine here */ |
| +#else |
| + if (use_ipv6) |
| + goto err; |
| +#endif |
| if (!ssl_sock_init()) return(0); |
| |
| - memset((char *)&server,0,sizeof(server)); |
| - server.sin_family=AF_INET; |
| - server.sin_port=htons((unsigned short)port); |
| - if (ip == NULL) |
| - server.sin_addr.s_addr=INADDR_ANY; |
| - else |
| -/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */ |
| -#ifndef BIT_FIELD_LIMITS |
| - memcpy(&server.sin_addr.s_addr,ip,4); |
| +#if OPENSSL_USE_IPV6 |
| + domain = use_ipv6 ? AF_INET6 : AF_INET; |
| #else |
| - memcpy(&server.sin_addr,ip,4); |
| + domain = AF_INET; |
| #endif |
| - |
| - if (type == SOCK_STREAM) |
| - s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); |
| - else /* type == SOCK_DGRAM */ |
| - s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP); |
| + if (type == SOCK_STREAM) |
| + s=socket(domain,SOCK_STREAM,SOCKET_PROTOCOL); |
| + else /* type == SOCK_DGRAM */ |
| + s=socket(domain, SOCK_DGRAM,IPPROTO_UDP); |
| |
| if (s == INVALID_SOCKET) goto err; |
| #if defined SOL_SOCKET && defined SO_REUSEADDR |
| + { |
| + int j = 1; |
| + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, |
| + (void *) &j, sizeof j); |
| + } |
| +#endif |
| +#if OPENSSL_USE_IPV6 |
| + if ((use_ipv4 == 0) && (use_ipv6 == 1)) |
| { |
| - int j = 1; |
| - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, |
| - (void *) &j, sizeof j); |
| + const int on = 1; |
| + |
| + setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, |
| + (const void *) &on, sizeof(int)); |
| } |
| #endif |
| - if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) |
| + if (domain == AF_INET) |
| + { |
| + addr_len = (socklen_t)sizeof(struct sockaddr_in); |
| + memset(server_in, 0, sizeof(struct sockaddr_in)); |
| + server_in->sin_family=AF_INET; |
| + server_in->sin_port = htons((unsigned short)port); |
| + if (ip == NULL) |
| + server_in->sin_addr.s_addr = htonl(INADDR_ANY); |
| + else |
| +/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */ |
| +#ifndef BIT_FIELD_LIMITS |
| + memcpy(&server_in->sin_addr.s_addr, ip, 4); |
| +#else |
| + memcpy(&server_in->sin_addr, ip, 4); |
| +#endif |
| + } |
| +#if OPENSSL_USE_IPV6 |
| + else |
| + { |
| + addr_len = (socklen_t)sizeof(struct sockaddr_in6); |
| + memset(server_in6, 0, sizeof(struct sockaddr_in6)); |
| + server_in6->sin6_family = AF_INET6; |
| + server_in6->sin6_port = htons((unsigned short)port); |
| + if (ip == NULL) |
| + server_in6->sin6_addr = in6addr_any; |
| + else |
| + memcpy(&server_in6->sin6_addr, ip, sizeof(struct in6_addr)); |
| + } |
| +#endif |
| + if (bind(s, (struct sockaddr *)&server, addr_len) == -1) |
| { |
| #ifndef OPENSSL_SYS_WINDOWS |
| perror("bind"); |
| @@ -375,16 +458,23 @@ |
| return(ret); |
| } |
| |
| -static int init_server(int *sock, int port, int type) |
| +static int init_server(int *sock, int port, int type, int use_ipv4, int use_ipv6) |
| { |
| - return(init_server_long(sock, port, NULL, type)); |
| + return(init_server_long(sock, port, NULL, type, use_ipv4, use_ipv6)); |
| } |
| |
| static int do_accept(int acc_sock, int *sock, char **host) |
| { |
| int ret; |
| struct hostent *h1,*h2; |
| - static struct sockaddr_in from; |
| +#if OPENSSL_USE_IPV6 |
| + struct sockaddr_storage from; |
| + struct sockaddr_in *from_in = (struct sockaddr_in *)&from; |
| + struct sockaddr_in6 *from_in6 = (struct sockaddr_in6 *)&from; |
| +#else |
| + struct sockaddr_in from; |
| + struct sockaddr_in *from_in = &from; |
| +#endif |
| int len; |
| /* struct linger ling; */ |
| |
| @@ -431,13 +521,23 @@ |
| */ |
| |
| if (host == NULL) goto end; |
| +#if OPENSSL_USE_IPV6 |
| + if (from.ss_family == AF_INET) |
| +#else |
| + if (from.sin_family == AF_INET) |
| +#endif |
| #ifndef BIT_FIELD_LIMITS |
| - /* I should use WSAAsyncGetHostByName() under windows */ |
| - h1=gethostbyaddr((char *)&from.sin_addr.s_addr, |
| - sizeof(from.sin_addr.s_addr),AF_INET); |
| + /* I should use WSAAsyncGetHostByName() under windows */ |
| + h1=gethostbyaddr((char *)&from_in->sin_addr.s_addr, |
| + sizeof(from_in->sin_addr.s_addr), AF_INET); |
| #else |
| - h1=gethostbyaddr((char *)&from.sin_addr, |
| - sizeof(struct in_addr),AF_INET); |
| + h1=gethostbyaddr((char *)&from_in->sin_addr, |
| + sizeof(struct in_addr), AF_INET); |
| +#endif |
| +#if OPENSSL_USE_IPV6 |
| + else |
| + h1=gethostbyaddr((char *)&from_in6->sin6_addr, |
| + sizeof(struct in6_addr), AF_INET6); |
| #endif |
| if (h1 == NULL) |
| { |
| @@ -454,15 +554,23 @@ |
| } |
| BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1); |
| |
| - h2=GetHostByName(*host); |
| +#if OPENSSL_USE_IPV6 |
| + h2=GetHostByName(*host, from.ss_family); |
| +#else |
| + h2=GetHostByName(*host, from.sin_family); |
| +#endif |
| if (h2 == NULL) |
| { |
| BIO_printf(bio_err,"gethostbyname failure\n"); |
| return(0); |
| } |
| - if (h2->h_addrtype != AF_INET) |
| +#if OPENSSL_USE_IPV6 |
| + if (h2->h_addrtype != from.ss_family) |
| +#else |
| + if (h2->h_addrtype != from.sin_family) |
| +#endif |
| { |
| - BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); |
| + BIO_printf(bio_err,"gethostbyname addr address is not correct\n"); |
| return(0); |
| } |
| } |
| @@ -477,7 +585,7 @@ |
| char *h,*p; |
| |
| h=str; |
| - p=strchr(str,':'); |
| + p=strrchr(str,':'); |
| if (p == NULL) |
| { |
| BIO_printf(bio_err,"no port defined\n"); |
| @@ -485,7 +593,7 @@ |
| } |
| *(p++)='\0'; |
| |
| - if ((ip != NULL) && !host_ip(str,ip)) |
| + if ((ip != NULL) && !host_ip(str,ip,AF_INET)) |
| goto err; |
| if (host_ptr != NULL) *host_ptr=h; |
| |
| @@ -496,48 +604,58 @@ |
| return(0); |
| } |
| |
| -static int host_ip(char *str, unsigned char ip[4]) |
| +static int host_ip(char *str, unsigned char *ip, int domain) |
| { |
| - unsigned int in[4]; |
| + unsigned int in[4]; |
| + unsigned long l; |
| int i; |
| |
| - if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4) |
| + if ((domain == AF_INET) && |
| + (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)) |
| { |
| + |
| for (i=0; i<4; i++) |
| if (in[i] > 255) |
| { |
| BIO_printf(bio_err,"invalid IP address\n"); |
| goto err; |
| } |
| - ip[0]=in[0]; |
| - ip[1]=in[1]; |
| - ip[2]=in[2]; |
| - ip[3]=in[3]; |
| - } |
| + l=htonl((in[0]<<24L)|(in[1]<<16L)|(in[2]<<8L)|in[3]); |
| + memcpy(ip, &l, 4); |
| + return 1; |
| + } |
| +#if OPENSSL_USE_IPV6 |
| + else if ((domain == AF_INET6) && |
| + (inet_pton(AF_INET6, str, ip) == 1)) |
| + return 1; |
| +#endif |
| else |
| { /* do a gethostbyname */ |
| struct hostent *he; |
| |
| if (!ssl_sock_init()) return(0); |
| |
| - he=GetHostByName(str); |
| + he=GetHostByName(str,domain); |
| if (he == NULL) |
| { |
| BIO_printf(bio_err,"gethostbyname failure\n"); |
| goto err; |
| } |
| /* cast to short because of win16 winsock definition */ |
| - if ((short)he->h_addrtype != AF_INET) |
| + if ((short)he->h_addrtype != domain) |
| { |
| - BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); |
| + BIO_printf(bio_err,"gethostbyname addr family is not correct\n"); |
| return(0); |
| } |
| - ip[0]=he->h_addr_list[0][0]; |
| - ip[1]=he->h_addr_list[0][1]; |
| - ip[2]=he->h_addr_list[0][2]; |
| - ip[3]=he->h_addr_list[0][3]; |
| + if (domain == AF_INET) |
| + memset(ip, 0, 4); |
| +#if OPENSSL_USE_IPV6 |
| + else |
| + memset(ip, 0, 16); |
| +#endif |
| + memcpy(ip, he->h_addr_list[0], he->h_length); |
| + return 1; |
| } |
| - return(1); |
| err: |
| return(0); |
| } |
| @@ -574,7 +692,7 @@ |
| static unsigned long ghbn_hits=0L; |
| static unsigned long ghbn_miss=0L; |
| |
| -static struct hostent *GetHostByName(char *name) |
| +static struct hostent *GetHostByName(char *name, int domain) |
| { |
| struct hostent *ret; |
| int i,lowi=0; |
| @@ -589,14 +707,20 @@ |
| } |
| if (ghbn_cache[i].order > 0) |
| { |
| - if (strncmp(name,ghbn_cache[i].name,128) == 0) |
| + if ((strncmp(name,ghbn_cache[i].name,128) == 0) && |
| + (ghbn_cache[i].ent.h_addrtype == domain)) |
| break; |
| } |
| } |
| if (i == GHBN_NUM) /* no hit*/ |
| { |
| ghbn_miss++; |
| - ret=gethostbyname(name); |
| + if (domain == AF_INET) |
| + ret=gethostbyname(name); |
| +#if OPENSSL_USE_IPV6 |
| + else |
| + ret=gethostbyname2(name, AF_INET6); |
| +#endif |
| if (ret == NULL) return(NULL); |
| /* else add to cache */ |
| if(strlen(name) < sizeof ghbn_cache[0].name) |