summaryrefslogtreecommitdiffstats
path: root/bin/fedora-dirk-ipv6.diff
diff options
context:
space:
mode:
Diffstat (limited to 'bin/fedora-dirk-ipv6.diff')
-rw-r--r--bin/fedora-dirk-ipv6.diff531
1 files changed, 531 insertions, 0 deletions
diff --git a/bin/fedora-dirk-ipv6.diff b/bin/fedora-dirk-ipv6.diff
new file mode 100644
index 0000000..9e4ee24
--- /dev/null
+++ b/bin/fedora-dirk-ipv6.diff
@@ -0,0 +1,531 @@
+--- a/apps/s_apps.h
++++ b/apps/s_apps.h
+@@ -151,7 +151,7 @@ typedef fd_mask fd_set;
+ #define PORT_STR "4433"
+ #define PROTOCOL "tcp"
+
+-int do_server(int port, int type, int *ret,
++int do_server(char *port, int type, int *ret,
+ int (*cb) (char *hostname, int s, int stype,
+ unsigned char *context), unsigned char *context,
+ int naccept);
+@@ -167,11 +167,10 @@ int ssl_print_point_formats(BIO *out, SSL *s);
+ int ssl_print_curves(BIO *out, SSL *s, int noshared);
+ #endif
+ int ssl_print_tmp_key(BIO *out, SSL *s);
+-int init_client(int *sock, char *server, int port, int type);
++int init_client(int *sock, char *server, char *port, int type);
+ 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);
++int extract_host_port(char *str, char **host_ptr, char **port_ptr);
+
+ long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
+ int argi, long argl, long ret);
+
+--- a/apps/s_client.c
++++ b/apps/s_client.c
+@@ -678,7 +678,7 @@ int MAIN(int argc, char **argv)
+ int cbuf_len, cbuf_off;
+ int sbuf_len, sbuf_off;
+ fd_set readfds, writefds;
+- short port = PORT;
++ char *port_str = PORT_STR;
+ char *http_proxy_str = NULL, *connect_str = NULL;
+ int full_log = 1;
+ char *host = SSL_HOST_NAME;
+@@ -803,9 +803,7 @@ int MAIN(int argc, char **argv)
+ } else if (strcmp(*argv, "-port") == 0) {
+ if (--argc < 1)
+ goto bad;
+- port = atoi(*(++argv));
+- if (port == 0)
+- goto bad;
++ port_str = *(++argv);
+ } else if (strcmp(*argv, "-connect") == 0) {
+ if (--argc < 1)
+ goto bad;
+@@ -1156,10 +1154,10 @@ int MAIN(int argc, char **argv)
+ }
+
+ if (http_proxy_str) {
+- if (!extract_host_port(http_proxy_str, &host, NULL, &port))
++ if (!extract_host_port(http_proxy_str, &host, &port_str))
+ goto bad;
+ } else if (connect_str) {
+- if (!extract_host_port(connect_str, &host, NULL, &port))
++ if (!extract_host_port(connect_str, &host, &port_str))
+ goto bad;
+ }
+
+@@ -1456,7 +1454,7 @@ int MAIN(int argc, char **argv)
+
+ re_start:
+
+- if (init_client(&s, host, port, socket_type) == 0) {
++ if (init_client(&s, host, port_str, socket_type) == 0) {
+ BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
+ SHUTDOWN(s);
+ goto end;
+
+--- a/apps/s_server.c
++++ b/apps/s_server.c
+@@ -1093,7 +1093,7 @@ int MAIN(int argc, char *argv[])
+ {
+ X509_VERIFY_PARAM *vpm = NULL;
+ int badarg = 0;
+- short port = PORT;
++ char *port_str = PORT_STR;
+ char *CApath = NULL, *CAfile = NULL;
+ char *chCApath = NULL, *chCAfile = NULL;
+ char *vfyCApath = NULL, *vfyCAfile = NULL;
+@@ -1180,7 +1180,8 @@ int MAIN(int argc, char *argv[])
+ if ((strcmp(*argv, "-port") == 0) || (strcmp(*argv, "-accept") == 0)) {
+ if (--argc < 1)
+ goto bad;
+- if (!extract_port(*(++argv), &port))
++ port_str = *(++argv);
++ if (port_str == NULL || *port_str == '\0')
+ goto bad;
+ } else if (strcmp(*argv, "-naccept") == 0) {
+ if (--argc < 1)
+@@ -2056,13 +2057,13 @@ int MAIN(int argc, char *argv[])
+ BIO_printf(bio_s_out, "ACCEPT\n");
+ (void)BIO_flush(bio_s_out);
+ if (rev)
+- do_server(port, socket_type, &accept_socket, rev_body, context,
++ do_server(port_str, socket_type, &accept_socket, rev_body, context,
+ naccept);
+ else if (www)
+- do_server(port, socket_type, &accept_socket, www_body, context,
++ do_server(port_str, socket_type, &accept_socket, www_body, context,
+ naccept);
+ else
+- do_server(port, socket_type, &accept_socket, sv_body, context,
++ do_server(port_str, socket_type, &accept_socket, sv_body, context,
+ naccept);
+ print_stats(bio_s_out, ctx);
+ ret = 0;
+
+--- a/apps/s_socket.c
++++ b/apps/s_socket.c
+@@ -106,9 +106,7 @@ static struct hostent *GetHostByName(char *name);
+ 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_server(int *sock, char *port, int type);
+ static int do_accept(int acc_sock, int *sock, char **host);
+ static int host_ip(char *str, unsigned char ip[4]);
+
+@@ -231,65 +229,66 @@ static int ssl_sock_init(void)
+ return (1);
+ }
+
+-int init_client(int *sock, char *host, int port, int type)
++int init_client(int *sock, char *host, char *port, int type)
+ {
+- unsigned char ip[4];
+-
+- 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;
+- struct sockaddr_in them;
+- int s, i;
++ struct addrinfo *res, *res0, hints;
++ char *failed_call = NULL;
++ int s;
++ int e;
+
+ 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 (type == SOCK_STREAM)
+- s = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL);
+- else /* ( type == SOCK_DGRAM) */
+- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
++ memset(&hints, '\0', sizeof(hints));
++ hints.ai_socktype = type;
++ hints.ai_flags = AI_ADDRCONFIG;
+
+- if (s == INVALID_SOCKET) {
+- perror("socket");
++ e = getaddrinfo(host, port, &hints, &res);
++ if (e) {
++ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e));
++ if (e == EAI_SYSTEM)
++ perror("getaddrinfo");
+ return (0);
+ }
++
++ res0 = res;
++ while (res) {
++ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
++ if (s == INVALID_SOCKET) {
++ failed_call = "socket";
++ goto nextres;
++ }
+ # if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
+- if (type == SOCK_STREAM) {
+- i = 0;
+- i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i));
+- if (i < 0) {
+- closesocket(s);
+- perror("keepalive");
+- return (0);
++ if (type == SOCK_STREAM) {
++ int i = 0;
++ i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
++ (char *)&i, sizeof(i));
++ if (i < 0) {
++ failed_call = "keepalive";
++ goto nextres;
++ }
+ }
+- }
+ # endif
++ if (connect(s, (struct sockaddr *)res->ai_addr, res->ai_addrlen) == 0) {
++ freeaddrinfo(res0);
++ *sock = s;
++ return (1);
++ }
+
+- if (connect(s, (struct sockaddr *)&them, sizeof(them)) == -1) {
+- closesocket(s);
+- perror("connect");
+- return (0);
++ failed_call = "socket";
++ nextres:
++ if (s != INVALID_SOCKET)
++ close(s);
++ res = res->ai_next;
+ }
+- *sock = s;
+- return (1);
++ freeaddrinfo(res0);
++ closesocket(s);
++
++ perror(failed_call);
++ return (0);
+ }
+
+-int do_server(int port, int type, int *ret,
++int do_server(char *port, int type, int *ret,
+ int (*cb) (char *hostname, int s, int stype,
+ unsigned char *context), unsigned char *context,
+ int naccept)
+@@ -328,69 +327,89 @@ int do_server(int port, int type, int *ret,
+ }
+ }
+
+-static int init_server_long(int *sock, int port, char *ip, int type)
++static int init_server(int *sock, char *port, int type)
+ {
+- int ret = 0;
+- struct sockaddr_in server;
+- int s = -1;
++ struct addrinfo *res, *res0 = NULL, hints;
++ char *failed_call = NULL;
++ int s = INVALID_SOCKET;
++ int e;
+
+ 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);
+-# else
+- memcpy(&server.sin_addr, ip, 4);
+-# 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);
++ memset(&hints, '\0', sizeof(hints));
++ hints.ai_family = AF_INET6;
++ tryipv4:
++ hints.ai_socktype = type;
++ hints.ai_flags = AI_PASSIVE;
++
++ e = getaddrinfo(NULL, port, &hints, &res);
++ if (e) {
++ if (hints.ai_family == AF_INET) {
++ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e));
++ if (e == EAI_SYSTEM)
++ perror("getaddrinfo");
++ return (0);
++ } else
++ res = NULL;
++ }
+
+- if (s == INVALID_SOCKET)
+- goto err;
++ res0 = res;
++ while (res) {
++ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
++ if (s == INVALID_SOCKET) {
++ failed_call = "socket";
++ goto nextres;
++ }
++ if (hints.ai_family == AF_INET6) {
++ int j = 0;
++ setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&j, sizeof j);
++ }
+ # if defined SOL_SOCKET && defined SO_REUSEADDR
+- {
+- int j = 1;
+- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j);
+- }
+-# endif
+- if (bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) {
+-# ifndef OPENSSL_SYS_WINDOWS
+- perror("bind");
++ {
++ int j = 1;
++ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j);
++ }
+ # endif
+- goto err;
++
++ if (bind(s, (struct sockaddr *)res->ai_addr, res->ai_addrlen) == -1) {
++ failed_call = "bind";
++ goto nextres;
++ }
++ if (type == SOCK_STREAM && listen(s, 128) == -1) {
++ failed_call = "listen";
++ goto nextres;
++ }
++
++ *sock = s;
++ return (1);
++
++ nextres:
++ if (s != INVALID_SOCKET)
++ close(s);
++ res = res->ai_next;
+ }
+- /* Make it 128 for linux */
+- if (type == SOCK_STREAM && listen(s, 128) == -1)
+- goto err;
+- *sock = s;
+- ret = 1;
+- err:
+- if ((ret == 0) && (s != -1)) {
+- SHUTDOWN(s);
++ if (res0)
++ freeaddrinfo(res0);
++
++ if (s == INVALID_SOCKET) {
++ if (hints.ai_family == AF_INET6) {
++ hints.ai_family = AF_INET;
++ goto tryipv4;
++ }
++ perror("socket");
++ return (0);
+ }
+- return (ret);
+-}
+
+-static int init_server(int *sock, int port, int type)
+-{
+- return (init_server_long(sock, port, NULL, type));
++ perror(failed_call);
++ return (0);
+ }
+
+ static int do_accept(int acc_sock, int *sock, char **host)
+ {
++ static struct sockaddr_storage from;
++ char buffer[NI_MAXHOST];
+ int ret;
+- struct hostent *h1, *h2;
+- static struct sockaddr_in from;
+ int len;
+ /* struct linger ling; */
+
+@@ -432,134 +451,60 @@ static int do_accept(int acc_sock, int *sock, char **host)
+ ling.l_onoff=1;
+ ling.l_linger=0;
+ i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling));
+- if (i < 0) { perror("linger"); return(0); }
++ if (i < 0) { closesocket(ret); perror("linger"); return(0); }
+ i=0;
+ i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+- if (i < 0) { perror("keepalive"); return(0); }
++ if (i < 0) { closesocket(ret); perror("keepalive"); return(0); }
+ */
+
+ if (host == NULL)
+ goto end;
+-# 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);
+-# else
+- h1 = gethostbyaddr((char *)&from.sin_addr,
+- sizeof(struct in_addr), AF_INET);
+-# endif
+- if (h1 == NULL) {
+- BIO_printf(bio_err, "bad gethostbyaddr\n");
++
++ if (getnameinfo((struct sockaddr *)&from, sizeof(from),
++ buffer, sizeof(buffer), NULL, 0, 0)) {
++ BIO_printf(bio_err, "getnameinfo failed\n");
+ *host = NULL;
+ /* return(0); */
+ } else {
+- if ((*host = (char *)OPENSSL_malloc(strlen(h1->h_name) + 1)) == NULL) {
++ if ((*host = (char *)OPENSSL_malloc(strlen(buffer) + 1)) == NULL) {
+ perror("OPENSSL_malloc");
+ closesocket(ret);
+ return (0);
+ }
+- BUF_strlcpy(*host, h1->h_name, strlen(h1->h_name) + 1);
+-
+- h2 = GetHostByName(*host);
+- if (h2 == NULL) {
+- BIO_printf(bio_err, "gethostbyname failure\n");
+- closesocket(ret);
+- return (0);
+- }
+- if (h2->h_addrtype != AF_INET) {
+- BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n");
+- closesocket(ret);
+- return (0);
+- }
++ strcpy(*host, buffer);
+ }
+ end:
+ *sock = ret;
+ return (1);
+ }
+
+-int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
+- short *port_ptr)
++int extract_host_port(char *str, char **host_ptr, char **port_ptr)
+ {
+- char *h, *p;
+-
+- h = str;
+- p = strchr(str, ':');
++ char *h, *p, *x;
++
++ x = h = str;
++ if (*h == '[') {
++ h++;
++ p = strchr(h, ']');
++ if (p == NULL) {
++ BIO_printf(bio_err, "no ending bracket for IPv6 address\n");
++ return (0);
++ }
++ *(p++) = '\0';
++ x = p;
++ }
++ p = strchr(x, ':');
+ if (p == NULL) {
+ BIO_printf(bio_err, "no port defined\n");
+ return (0);
+ }
+ *(p++) = '\0';
+
+- if ((ip != NULL) && !host_ip(str, ip))
+- goto err;
+ if (host_ptr != NULL)
+ *host_ptr = h;
++ if (port_ptr != NULL)
++ *port_ptr = p;
+
+- if (!extract_port(p, port_ptr))
+- goto err;
+- return (1);
+- err:
+- return (0);
+-}
+-
+-static int host_ip(char *str, unsigned char ip[4])
+-{
+- unsigned int in[4];
+- int i;
+-
+- if (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];
+- } else { /* do a gethostbyname */
+- struct hostent *he;
+-
+- if (!ssl_sock_init())
+- return (0);
+-
+- he = GetHostByName(str);
+- 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) {
+- BIO_printf(bio_err, "gethostbyname addr is not AF_INET\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];
+- }
+- return (1);
+- err:
+- return (0);
+-}
+-
+-int extract_port(char *str, short *port_ptr)
+-{
+- int i;
+- struct servent *s;
+-
+- i = atoi(str);
+- if (i != 0)
+- *port_ptr = (unsigned short)i;
+- else {
+- s = getservbyname(str, "tcp");
+- if (s == NULL) {
+- BIO_printf(bio_err, "getservbyname failure for %s\n", str);
+- return (0);
+- }
+- *port_ptr = ntohs((unsigned short)s->s_port);
+- }
+ return (1);
+ }
+