Hi All, I want to use the s_server with IPv6. But I am unable to find an ipv6 patch for the following openssl version: openssl-0.9.8k Can anybody please provide me the URL or Link from where I can download the same? Thanks in advance. PS: I tried using the attached patch. It is built for openssl-0.9.8b version. Patching returned the following errors: #patch -p0 </root/Desktop/ipv6.patch can't find file to patch at input line 8 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |Index: apps/s_apps.h |=================================================================== |RCS file: /v/openssl/cvs/openssl/apps/s_apps.h,v |retrieving revision 1.22 |diff -u -r1.22 s_apps.h |--- apps/s_apps.h 4 Sep 2009 17:42:52 -0000 1.22 |+++ apps/s_apps.h 22 Sep 2009 12:16:58 -0000 -------------------------- File to patch: [r...@chaitra chaitra]# cd openssl-0.9.8k [r...@chaitra openssl-0.9.8k]# patch -p0 </root/Desktop/ipv6.patch patching file apps/s_apps.h patching file apps/s_cb.c Hunk #1 FAILED at 692. Hunk #2 FAILED at 713. Hunk #3 FAILED at 738. Hunk #4 FAILED at 782. Hunk #5 FAILED at 796. Hunk #6 FAILED at 821. 6 out of 6 hunks FAILED -- saving rejects to file apps/s_cb.c.rej patching file apps/s_client.c Hunk #1 succeeded at 192 (offset -87 lines). Hunk #2 succeeded at 385 (offset -7 lines). Hunk #3 succeeded at 346 with fuzz 1 (offset -89 lines). Hunk #4 succeeded at 448 (offset -7 lines). Hunk #5 succeeded at 610 (offset -116 lines). Hunk #6 FAILED at 857. Hunk #7 FAILED at 876. 2 out of 7 hunks FAILED -- saving rejects to file apps/s_client.c.rej patching file apps/s_server.c Hunk #1 succeeded at 406 (offset -86 lines). Hunk #2 FAILED at 769. Hunk #3 succeeded at 879 (offset -4 lines). Hunk #4 succeeded at 1096 (offset -109 lines). Hunk #5 succeeded at 1654 with fuzz 2 (offset -54 lines). 1 out of 5 hunks FAILED -- saving rejects to file apps/s_server.c.rej patching file apps/s_socket.c Hunk #2 FAILED at 228. Hunk #3 FAILED at 309. Hunk #4 succeeded at 354 (offset 2 lines). Hunk #6 succeeded at 517 (offset 2 lines). Hunk #8 succeeded at 582 (offset 2 lines). Hunk #10 succeeded at 601 (offset 2 lines). Hunk #12 succeeded at 704 (offset 2 lines). 2 out of 12 hunks FAILED -- saving rejects to file apps/s_socket.c.rej patching file crypto/bio/bss_dgram.c Hunk #1 succeeded at 100 (offset -8 lines). Hunk #2 succeeded at 183 (offset -95 lines). Hunk #3 FAILED at 200. Hunk #4 succeeded at 310 (offset -10 lines). Hunk #5 succeeded at 327 (offset -101 lines). Hunk #6 FAILED at 436. 2 out of 6 hunks FAILED -- saving rejects to file crypto/bio/bss_dgram.c.rej -- Thanks & Regards Chaitra Shankar |
Index: apps/s_apps.h =================================================================== RCS file: /v/openssl/cvs/openssl/apps/s_apps.h,v retrieving revision 1.22 diff -u -r1.22 s_apps.h --- apps/s_apps.h 4 Sep 2009 17:42:52 -0000 1.22 +++ apps/s_apps.h 22 Sep 2009 12:16:58 -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_cb.c =================================================================== RCS file: /v/openssl/cvs/openssl/apps/s_cb.c,v retrieving revision 1.30 diff -u -r1.30 s_cb.c --- apps/s_cb.c 4 Sep 2009 17:42:52 -0000 1.30 +++ apps/s_cb.c 22 Sep 2009 12:16:59 -0000 @@ -692,8 +692,12 @@ { unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned int length, resultlength; +#if OPENSSL_USE_IPV6 + struct sockaddr_storage peer; +#else struct sockaddr_in peer; - +#endif + /* Initialize a random secret */ if (!cookie_initialized) { @@ -709,8 +713,24 @@ (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); /* Create buffer with peer's address and port */ +#if OPENSSL_USE_IPV6 + switch (peer.ss_family) + { + case AF_INET: + length = sizeof(struct in_addr); + break; + case AF_INET6: + length = sizeof(struct in6_addr); + break; + default: + OPENSSL_assert(0); + break; + } + length += sizeof(in_port_t); +#else length = sizeof(peer.sin_addr); length += sizeof(peer.sin_port); +#endif buffer = OPENSSL_malloc(length); if (buffer == NULL) @@ -718,9 +738,34 @@ BIO_printf(bio_err,"out of memory\n"); return 0; } - - memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); - memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); + +#if OPENSSL_USE_IPV6 + switch (peer.ss_family) + { + case AF_INET: + memcpy(buffer, + &(((struct sockaddr_in *)&peer)->sin_port), + sizeof(in_port_t)); + memcpy(buffer + sizeof(in_port_t), + &(((struct sockaddr_in *)&peer)->sin_addr), + sizeof(struct in_addr)); + break; + case AF_INET6: + memcpy(buffer, + &(((struct sockaddr_in6 *)&peer)->sin6_port), + sizeof(in_port_t)); + memcpy(buffer + sizeof(in_port_t), + &(((struct sockaddr_in6 *)&peer)->sin6_addr), + sizeof(struct in6_addr)); + break; + default: + OPENSSL_assert(0); + break; + } +#else + memcpy(buffer, &peer.sin_port, sizeof(peer.sin_port)); + memcpy(buffer + sizeof(peer.sin_port), &peer.sin_addr, sizeof(peer.sin_addr)); +#endif /* Calculate HMAC of buffer using the secret */ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, @@ -737,8 +782,12 @@ { unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned int length, resultlength; +#if OPENSSL_USE_IPV6 + struct sockaddr_storage peer; +#else struct sockaddr_in peer; - +#endif + /* If secret isn't initialized yet, the cookie can't be valid */ if (!cookie_initialized) return 0; @@ -747,8 +796,24 @@ (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); /* Create buffer with peer's address and port */ +#if OPENSSL_USE_IPV6 + switch (peer.ss_family) + { + case AF_INET: + length = sizeof(struct in_addr); + break; + case AF_INET6: + length = sizeof(struct in6_addr); + break; + default: + OPENSSL_assert(0); + break; + } + length += sizeof(in_port_t); +#else length = sizeof(peer.sin_addr); length += sizeof(peer.sin_port); +#endif buffer = OPENSSL_malloc(length); if (buffer == NULL) @@ -756,15 +821,40 @@ BIO_printf(bio_err,"out of memory\n"); return 0; } - - memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); - memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); + +#if OPENSSL_USE_IPV6 + switch (peer.ss_family) + { + case AF_INET: + memcpy(buffer, + &(((struct sockaddr_in *)&peer)->sin_port), + sizeof(in_port_t)); + memcpy(buffer + sizeof(in_port_t), + &(((struct sockaddr_in *)&peer)->sin_addr), + sizeof(struct in_addr)); + break; + case AF_INET6: + memcpy(buffer, + &(((struct sockaddr_in6 *)&peer)->sin6_port), + sizeof(in_port_t)); + memcpy(buffer + sizeof(in_port_t), + &(((struct sockaddr_in6 *)&peer)->sin6_addr), + sizeof(struct in6_addr)); + break; + default: + OPENSSL_assert(0); + break; + } +#else + memcpy(buffer, &peer.sin_port, sizeof(peer.sin_port)); + memcpy(buffer + sizeof(peer.sin_port), &peer.sin_addr, sizeof(peer.sin_addr)); +#endif /* Calculate HMAC of buffer using the secret */ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, buffer, length, result, &resultlength); OPENSSL_free(buffer); - + if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) return 1; Index: apps/s_client.c =================================================================== RCS file: /v/openssl/cvs/openssl/apps/s_client.c,v retrieving revision 1.126 diff -u -r1.126 s_client.c --- apps/s_client.c 12 Aug 2009 13:19:53 -0000 1.126 +++ apps/s_client.c 22 Sep 2009 12:17:00 -0000 @@ -279,6 +279,9 @@ { BIO_printf(bio_err,"usage: s_client args\n"); BIO_printf(bio_err,"\n"); +#if OPENSSL_USE_IPV6 + BIO_printf(bio_err," -6 - use IPv6\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); @@ -389,6 +392,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; @@ -431,7 +435,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; @@ -447,6 +455,8 @@ meth=SSLv2_client_method(); #endif + use_ipv4 = 1; + use_ipv6 = 0; apps_startup(); c_Pause=0; c_quiet=0; @@ -716,6 +726,13 @@ jpake_secret = *++argv; } #endif +#if OPENSSL_USE_IPV6 + else if (strcmp(*argv,"-6") == 0) + { + use_ipv4 = 0; + use_ipv6 = 1; + } +#endif else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -956,7 +973,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); @@ -975,14 +992,14 @@ goto end; } } -#endif +#endif if (c_Pause & 0x01) con->debug=1; if ( SSL_version(con) == DTLS1_VERSION) { 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()); Index: apps/s_server.c =================================================================== RCS file: /v/openssl/cvs/openssl/apps/s_server.c,v retrieving revision 1.144 diff -u -r1.144 s_server.c --- apps/s_server.c 4 Sep 2009 17:42:52 -0000 1.144 +++ apps/s_server.c 22 Sep 2009 12:17:01 -0000 @@ -492,6 +492,10 @@ BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n"); BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n"); #endif + BIO_printf(bio_err," -4 - use IPv4 only\n"); +#if OPENSSL_USE_IPV6 + BIO_printf(bio_err," -6 - use IPv6 only\n"); +#endif } static int local_argc=0; @@ -851,6 +855,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; @@ -878,6 +883,12 @@ meth=SSLv2_server_method(); #endif + use_ipv4 = 1; +#if OPENSSL_USE_IPV6 + use_ipv6 = 1; +#else + use_ipv6 = 0; +#endif local_argc=argc; local_argv=argv; @@ -1194,6 +1205,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 else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -1685,9 +1708,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 diff -u -r1.43 s_socket.c --- apps/s_socket.c 12 Nov 2008 03:57:47 -0000 1.43 +++ apps/s_socket.c 22 Sep 2009 12:17:02 -0000 @@ -91,16 +91,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 */ @@ -228,39 +228,76 @@ 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 - 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 && !use_ipv6) + return 0; +#if OPENSSL_USE_IPV6 + /* we are fine here */ +#else + if (use_ipv6) + return 0; +#endif + 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, 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); } @@ -272,29 +309,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) @@ -317,41 +352,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,i; + 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 (beck...@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 (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 (beck...@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,sizeof(server)) == -1) + if (bind(s, (struct sockaddr *)&server, addr_len) == -1) { #ifndef OPENSSL_SYS_WINDOWS perror("bind"); @@ -371,16 +453,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,i; 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; */ @@ -426,13 +515,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) { @@ -449,16 +548,24 @@ } 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); } i=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); } } @@ -473,7 +580,7 @@ char *h,*p; h=str; - p=strchr(str,':'); + p=strrchr(str,':'); if (p == NULL) { BIO_printf(bio_err,"no port defined\n"); @@ -481,7 +588,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; @@ -492,48 +599,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); } @@ -570,7 +687,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; @@ -585,14 +702,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) Index: crypto/bio/bss_dgram.c =================================================================== RCS file: /v/openssl/cvs/openssl/crypto/bio/bss_dgram.c,v retrieving revision 1.23 diff -u -r1.23 bss_dgram.c --- crypto/bio/bss_dgram.c 22 Sep 2009 11:34:45 -0000 1.23 +++ crypto/bio/bss_dgram.c 22 Sep 2009 12:17:02 -0000 @@ -108,7 +108,11 @@ typedef struct bio_dgram_data_st { - struct sockaddr peer; +#if OPENSSL_USE_IPV6 + struct sockaddr_storage peer; +#else + struct sockaddr_in peer; +#endif unsigned int connected; unsigned int _errno; unsigned int mtu; @@ -274,7 +278,11 @@ int ret=0; bio_dgram_data *data = (bio_dgram_data *)b->ptr; - struct sockaddr peer; +#if OPENSSL_USE_IPV6 + struct sockaddr_storage peer; +#else + struct sockaddr_in peer; +#endif int peerlen = sizeof(peer); if (out != NULL) @@ -287,7 +295,7 @@ * compiler warnings. */ dgram_adjust_rcv_timeout(b); - ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); + ret=recvfrom(b->num,out,outl,0,(struct sockaddr *)&peer,(void *)&peerlen); dgram_reset_rcv_timeout(b); if ( ! data->connected && ret >= 0) @@ -312,13 +320,28 @@ bio_dgram_data *data = (bio_dgram_data *)b->ptr; clear_socket_error(); - if ( data->connected ) - ret=writesocket(b->num,in,inl); - else + if ( data->connected ) + ret=writesocket(b->num,in,inl); + else +#if OPENSSL_USE_IPV6 + if (data->peer.ss_family == AF_INET) #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) - ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer)); + ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in)); #else - ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer)); + ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in)); +#endif + else +#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) + ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in6)); +#else + ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in6)); +#endif +#else +#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) + ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in)); +#else + ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in)); +#endif #endif BIO_clear_retry_flags(b); @@ -405,7 +428,11 @@ else { #endif - memcpy(&(data->peer),to, sizeof(struct sockaddr)); +#if OPENSSL_USE_IPV6 + memcpy(&(data->peer),to, sizeof(struct sockaddr_storage)); +#else + memcpy(&(data->peer),to, sizeof(struct sockaddr_in)); +#endif #if 0 } #endif @@ -510,27 +537,44 @@ if ( to != NULL) { data->connected = 1; - memcpy(&(data->peer),to, sizeof(struct sockaddr)); +#if OPENSSL_USE_IPV6 + memcpy(&(data->peer),to, sizeof(struct sockaddr_storage)); +#else + memcpy(&(data->peer),to, sizeof(struct sockaddr_in)); +#endif } else { data->connected = 0; - memset(&(data->peer), 0x00, sizeof(struct sockaddr)); +#if OPENSSL_USE_IPV6 + memset(&(data->peer), 0x00, sizeof(struct sockaddr_storage)); +#else + memset(&(data->peer), 0x00, sizeof(struct sockaddr_in)); +#endif } break; - case BIO_CTRL_DGRAM_GET_PEER: - to = (struct sockaddr *) ptr; + case BIO_CTRL_DGRAM_GET_PEER: + to = (struct sockaddr *) ptr; - memcpy(to, &(data->peer), sizeof(struct sockaddr)); - ret = sizeof(struct sockaddr); - break; - case BIO_CTRL_DGRAM_SET_PEER: - to = (struct sockaddr *) ptr; +#if OPENSSL_USE_IPV6 + memcpy(to, &(data->peer), sizeof(struct sockaddr_storage)); + ret = sizeof(struct sockaddr_storage); +#else + memcpy(to, &(data->peer), sizeof(struct sockaddr_in)); + ret = sizeof(struct sockaddr_in); +#endif + break; + case BIO_CTRL_DGRAM_SET_PEER: + to = (struct sockaddr *) ptr; - memcpy(&(data->peer), to, sizeof(struct sockaddr)); - break; +#if OPENSSL_USE_IPV6 + memcpy(&(data->peer), to, sizeof(struct sockaddr_storage)); +#else + memcpy(&(data->peer), to, sizeof(struct sockaddr_in)); +#endif + break; case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: - memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); break; #if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: