1--- a/apps/s_apps.h 2+++ b/apps/s_apps.h 3@@ -151,7 +151,7 @@ typedef fd_mask fd_set; 4 #define PORT_STR "4433" 5 #define PROTOCOL "tcp" 6 7-int do_server(int port, int type, int *ret, 8+int do_server(char *port, int type, int *ret, 9 int (*cb) (char *hostname, int s, int stype, 10 unsigned char *context), unsigned char *context, 11 int naccept); 12@@ -167,11 +167,10 @@ int ssl_print_point_formats(BIO *out, SSL *s); 13 int ssl_print_curves(BIO *out, SSL *s, int noshared); 14 #endif 15 int ssl_print_tmp_key(BIO *out, SSL *s); 16-int init_client(int *sock, char *server, int port, int type); 17+int init_client(int *sock, char *server, char *port, int type); 18 int should_retry(int i); 19 int extract_port(char *str, short *port_ptr); 20-int extract_host_port(char *str, char **host_ptr, unsigned char *ip, 21- short *p); 22+int extract_host_port(char *str, char **host_ptr, char **port_ptr); 23 24 long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, 25 int argi, long argl, long ret); 26 27--- a/apps/s_client.c 28+++ b/apps/s_client.c 29@@ -678,7 +678,7 @@ int MAIN(int argc, char **argv) 30 int cbuf_len, cbuf_off; 31 int sbuf_len, sbuf_off; 32 fd_set readfds, writefds; 33- short port = PORT; 34+ char *port_str = PORT_STR; 35 char *http_proxy_str = NULL, *connect_str = NULL; 36 int full_log = 1; 37 char *host = SSL_HOST_NAME; 38@@ -803,9 +803,7 @@ int MAIN(int argc, char **argv) 39 } else if (strcmp(*argv, "-port") == 0) { 40 if (--argc < 1) 41 goto bad; 42- port = atoi(*(++argv)); 43- if (port == 0) 44- goto bad; 45+ port_str = *(++argv); 46 } else if (strcmp(*argv, "-connect") == 0) { 47 if (--argc < 1) 48 goto bad; 49@@ -1156,10 +1154,10 @@ int MAIN(int argc, char **argv) 50 } 51 52 if (http_proxy_str) { 53- if (!extract_host_port(http_proxy_str, &host, NULL, &port)) 54+ if (!extract_host_port(http_proxy_str, &host, &port_str)) 55 goto bad; 56 } else if (connect_str) { 57- if (!extract_host_port(connect_str, &host, NULL, &port)) 58+ if (!extract_host_port(connect_str, &host, &port_str)) 59 goto bad; 60 } 61 62@@ -1456,7 +1454,7 @@ int MAIN(int argc, char **argv) 63 64 re_start: 65 66- if (init_client(&s, host, port, socket_type) == 0) { 67+ if (init_client(&s, host, port_str, socket_type) == 0) { 68 BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); 69 SHUTDOWN(s); 70 goto end; 71 72--- a/apps/s_server.c 73+++ b/apps/s_server.c 74@@ -1093,7 +1093,7 @@ int MAIN(int argc, char *argv[]) 75 { 76 X509_VERIFY_PARAM *vpm = NULL; 77 int badarg = 0; 78- short port = PORT; 79+ char *port_str = PORT_STR; 80 char *CApath = NULL, *CAfile = NULL; 81 char *chCApath = NULL, *chCAfile = NULL; 82 char *vfyCApath = NULL, *vfyCAfile = NULL; 83@@ -1180,7 +1180,8 @@ int MAIN(int argc, char *argv[]) 84 if ((strcmp(*argv, "-port") == 0) || (strcmp(*argv, "-accept") == 0)) { 85 if (--argc < 1) 86 goto bad; 87- if (!extract_port(*(++argv), &port)) 88+ port_str = *(++argv); 89+ if (port_str == NULL || *port_str == '\0') 90 goto bad; 91 } else if (strcmp(*argv, "-naccept") == 0) { 92 if (--argc < 1) 93@@ -2056,13 +2057,13 @@ int MAIN(int argc, char *argv[]) 94 BIO_printf(bio_s_out, "ACCEPT\n"); 95 (void)BIO_flush(bio_s_out); 96 if (rev) 97- do_server(port, socket_type, &accept_socket, rev_body, context, 98+ do_server(port_str, socket_type, &accept_socket, rev_body, context, 99 naccept); 100 else if (www) 101- do_server(port, socket_type, &accept_socket, www_body, context, 102+ do_server(port_str, socket_type, &accept_socket, www_body, context, 103 naccept); 104 else 105- do_server(port, socket_type, &accept_socket, sv_body, context, 106+ do_server(port_str, socket_type, &accept_socket, sv_body, context, 107 naccept); 108 print_stats(bio_s_out, ctx); 109 ret = 0; 110 111--- a/apps/s_socket.c 112+++ b/apps/s_socket.c 113@@ -106,9 +106,7 @@ static struct hostent *GetHostByName(char *name); 114 static void ssl_sock_cleanup(void); 115 # endif 116 static int ssl_sock_init(void); 117-static int init_client_ip(int *sock, unsigned char ip[4], int port, int type); 118-static int init_server(int *sock, int port, int type); 119-static int init_server_long(int *sock, int port, char *ip, int type); 120+static int init_server(int *sock, char *port, int type); 121 static int do_accept(int acc_sock, int *sock, char **host); 122 static int host_ip(char *str, unsigned char ip[4]); 123 124@@ -231,65 +229,66 @@ static int ssl_sock_init(void) 125 return (1); 126 } 127 128-int init_client(int *sock, char *host, int port, int type) 129+int init_client(int *sock, char *host, char *port, int type) 130 { 131- unsigned char ip[4]; 132- 133- memset(ip, '\0', sizeof ip); 134- if (!host_ip(host, &(ip[0]))) 135- return 0; 136- return init_client_ip(sock, ip, port, type); 137-} 138- 139-static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) 140-{ 141- unsigned long addr; 142- struct sockaddr_in them; 143- int s, i; 144+ struct addrinfo *res, *res0, hints; 145+ char *failed_call = NULL; 146+ int s; 147+ int e; 148 149 if (!ssl_sock_init()) 150 return (0); 151 152- memset((char *)&them, 0, sizeof(them)); 153- them.sin_family = AF_INET; 154- them.sin_port = htons((unsigned short)port); 155- addr = (unsigned long) 156- ((unsigned long)ip[0] << 24L) | 157- ((unsigned long)ip[1] << 16L) | 158- ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]); 159- them.sin_addr.s_addr = htonl(addr); 160- 161- if (type == SOCK_STREAM) 162- s = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); 163- else /* ( type == SOCK_DGRAM) */ 164- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 165+ memset(&hints, '\0', sizeof(hints)); 166+ hints.ai_socktype = type; 167+ hints.ai_flags = AI_ADDRCONFIG; 168 169- if (s == INVALID_SOCKET) { 170- perror("socket"); 171+ e = getaddrinfo(host, port, &hints, &res); 172+ if (e) { 173+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); 174+ if (e == EAI_SYSTEM) 175+ perror("getaddrinfo"); 176 return (0); 177 } 178+ 179+ res0 = res; 180+ while (res) { 181+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 182+ if (s == INVALID_SOCKET) { 183+ failed_call = "socket"; 184+ goto nextres; 185+ } 186 # if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) 187- if (type == SOCK_STREAM) { 188- i = 0; 189- i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i)); 190- if (i < 0) { 191- closesocket(s); 192- perror("keepalive"); 193- return (0); 194+ if (type == SOCK_STREAM) { 195+ int i = 0; 196+ i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 197+ (char *)&i, sizeof(i)); 198+ if (i < 0) { 199+ failed_call = "keepalive"; 200+ goto nextres; 201+ } 202 } 203- } 204 # endif 205+ if (connect(s, (struct sockaddr *)res->ai_addr, res->ai_addrlen) == 0) { 206+ freeaddrinfo(res0); 207+ *sock = s; 208+ return (1); 209+ } 210 211- if (connect(s, (struct sockaddr *)&them, sizeof(them)) == -1) { 212- closesocket(s); 213- perror("connect"); 214- return (0); 215+ failed_call = "socket"; 216+ nextres: 217+ if (s != INVALID_SOCKET) 218+ close(s); 219+ res = res->ai_next; 220 } 221- *sock = s; 222- return (1); 223+ freeaddrinfo(res0); 224+ closesocket(s); 225+ 226+ perror(failed_call); 227+ return (0); 228 } 229 230-int do_server(int port, int type, int *ret, 231+int do_server(char *port, int type, int *ret, 232 int (*cb) (char *hostname, int s, int stype, 233 unsigned char *context), unsigned char *context, 234 int naccept) 235@@ -328,69 +327,89 @@ int do_server(int port, int type, int *ret, 236 } 237 } 238 239-static int init_server_long(int *sock, int port, char *ip, int type) 240+static int init_server(int *sock, char *port, int type) 241 { 242- int ret = 0; 243- struct sockaddr_in server; 244- int s = -1; 245+ struct addrinfo *res, *res0 = NULL, hints; 246+ char *failed_call = NULL; 247+ int s = INVALID_SOCKET; 248+ int e; 249 250 if (!ssl_sock_init()) 251 return (0); 252 253- memset((char *)&server, 0, sizeof(server)); 254- server.sin_family = AF_INET; 255- server.sin_port = htons((unsigned short)port); 256- if (ip == NULL) 257- server.sin_addr.s_addr = INADDR_ANY; 258- else 259-/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */ 260-# ifndef BIT_FIELD_LIMITS 261- memcpy(&server.sin_addr.s_addr, ip, 4); 262-# else 263- memcpy(&server.sin_addr, ip, 4); 264-# endif 265- 266- if (type == SOCK_STREAM) 267- s = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); 268- else /* type == SOCK_DGRAM */ 269- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 270+ memset(&hints, '\0', sizeof(hints)); 271+ hints.ai_family = AF_INET6; 272+ tryipv4: 273+ hints.ai_socktype = type; 274+ hints.ai_flags = AI_PASSIVE; 275+ 276+ e = getaddrinfo(NULL, port, &hints, &res); 277+ if (e) { 278+ if (hints.ai_family == AF_INET) { 279+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); 280+ if (e == EAI_SYSTEM) 281+ perror("getaddrinfo"); 282+ return (0); 283+ } else 284+ res = NULL; 285+ } 286 287- if (s == INVALID_SOCKET) 288- goto err; 289+ res0 = res; 290+ while (res) { 291+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 292+ if (s == INVALID_SOCKET) { 293+ failed_call = "socket"; 294+ goto nextres; 295+ } 296+ if (hints.ai_family == AF_INET6) { 297+ int j = 0; 298+ setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&j, sizeof j); 299+ } 300 # if defined SOL_SOCKET && defined SO_REUSEADDR 301- { 302- int j = 1; 303- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j); 304- } 305-# endif 306- if (bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) { 307-# ifndef OPENSSL_SYS_WINDOWS 308- perror("bind"); 309+ { 310+ int j = 1; 311+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j); 312+ } 313 # endif 314- goto err; 315+ 316+ if (bind(s, (struct sockaddr *)res->ai_addr, res->ai_addrlen) == -1) { 317+ failed_call = "bind"; 318+ goto nextres; 319+ } 320+ if (type == SOCK_STREAM && listen(s, 128) == -1) { 321+ failed_call = "listen"; 322+ goto nextres; 323+ } 324+ 325+ *sock = s; 326+ return (1); 327+ 328+ nextres: 329+ if (s != INVALID_SOCKET) 330+ close(s); 331+ res = res->ai_next; 332 } 333- /* Make it 128 for linux */ 334- if (type == SOCK_STREAM && listen(s, 128) == -1) 335- goto err; 336- *sock = s; 337- ret = 1; 338- err: 339- if ((ret == 0) && (s != -1)) { 340- SHUTDOWN(s); 341+ if (res0) 342+ freeaddrinfo(res0); 343+ 344+ if (s == INVALID_SOCKET) { 345+ if (hints.ai_family == AF_INET6) { 346+ hints.ai_family = AF_INET; 347+ goto tryipv4; 348+ } 349+ perror("socket"); 350+ return (0); 351 } 352- return (ret); 353-} 354 355-static int init_server(int *sock, int port, int type) 356-{ 357- return (init_server_long(sock, port, NULL, type)); 358+ perror(failed_call); 359+ return (0); 360 } 361 362 static int do_accept(int acc_sock, int *sock, char **host) 363 { 364+ static struct sockaddr_storage from; 365+ char buffer[NI_MAXHOST]; 366 int ret; 367- struct hostent *h1, *h2; 368- static struct sockaddr_in from; 369 int len; 370 /* struct linger ling; */ 371 372@@ -432,134 +451,60 @@ static int do_accept(int acc_sock, int *sock, char **host) 373 ling.l_onoff=1; 374 ling.l_linger=0; 375 i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling)); 376- if (i < 0) { perror("linger"); return(0); } 377+ if (i < 0) { closesocket(ret); perror("linger"); return(0); } 378 i=0; 379 i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); 380- if (i < 0) { perror("keepalive"); return(0); } 381+ if (i < 0) { closesocket(ret); perror("keepalive"); return(0); } 382 */ 383 384 if (host == NULL) 385 goto end; 386-# ifndef BIT_FIELD_LIMITS 387- /* I should use WSAAsyncGetHostByName() under windows */ 388- h1 = gethostbyaddr((char *)&from.sin_addr.s_addr, 389- sizeof(from.sin_addr.s_addr), AF_INET); 390-# else 391- h1 = gethostbyaddr((char *)&from.sin_addr, 392- sizeof(struct in_addr), AF_INET); 393-# endif 394- if (h1 == NULL) { 395- BIO_printf(bio_err, "bad gethostbyaddr\n"); 396+ 397+ if (getnameinfo((struct sockaddr *)&from, sizeof(from), 398+ buffer, sizeof(buffer), NULL, 0, 0)) { 399+ BIO_printf(bio_err, "getnameinfo failed\n"); 400 *host = NULL; 401 /* return(0); */ 402 } else { 403- if ((*host = (char *)OPENSSL_malloc(strlen(h1->h_name) + 1)) == NULL) { 404+ if ((*host = (char *)OPENSSL_malloc(strlen(buffer) + 1)) == NULL) { 405 perror("OPENSSL_malloc"); 406 closesocket(ret); 407 return (0); 408 } 409- BUF_strlcpy(*host, h1->h_name, strlen(h1->h_name) + 1); 410- 411- h2 = GetHostByName(*host); 412- if (h2 == NULL) { 413- BIO_printf(bio_err, "gethostbyname failure\n"); 414- closesocket(ret); 415- return (0); 416- } 417- if (h2->h_addrtype != AF_INET) { 418- BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n"); 419- closesocket(ret); 420- return (0); 421- } 422+ strcpy(*host, buffer); 423 } 424 end: 425 *sock = ret; 426 return (1); 427 } 428 429-int extract_host_port(char *str, char **host_ptr, unsigned char *ip, 430- short *port_ptr) 431+int extract_host_port(char *str, char **host_ptr, char **port_ptr) 432 { 433- char *h, *p; 434- 435- h = str; 436- p = strchr(str, ':'); 437+ char *h, *p, *x; 438+ 439+ x = h = str; 440+ if (*h == '[') { 441+ h++; 442+ p = strchr(h, ']'); 443+ if (p == NULL) { 444+ BIO_printf(bio_err, "no ending bracket for IPv6 address\n"); 445+ return (0); 446+ } 447+ *(p++) = '\0'; 448+ x = p; 449+ } 450+ p = strchr(x, ':'); 451 if (p == NULL) { 452 BIO_printf(bio_err, "no port defined\n"); 453 return (0); 454 } 455 *(p++) = '\0'; 456 457- if ((ip != NULL) && !host_ip(str, ip)) 458- goto err; 459 if (host_ptr != NULL) 460 *host_ptr = h; 461+ if (port_ptr != NULL) 462+ *port_ptr = p; 463 464- if (!extract_port(p, port_ptr)) 465- goto err; 466- return (1); 467- err: 468- return (0); 469-} 470- 471-static int host_ip(char *str, unsigned char ip[4]) 472-{ 473- unsigned int in[4]; 474- int i; 475- 476- if (sscanf(str, "%u.%u.%u.%u", &(in[0]), &(in[1]), &(in[2]), &(in[3])) == 477- 4) { 478- for (i = 0; i < 4; i++) 479- if (in[i] > 255) { 480- BIO_printf(bio_err, "invalid IP address\n"); 481- goto err; 482- } 483- ip[0] = in[0]; 484- ip[1] = in[1]; 485- ip[2] = in[2]; 486- ip[3] = in[3]; 487- } else { /* do a gethostbyname */ 488- struct hostent *he; 489- 490- if (!ssl_sock_init()) 491- return (0); 492- 493- he = GetHostByName(str); 494- if (he == NULL) { 495- BIO_printf(bio_err, "gethostbyname failure\n"); 496- goto err; 497- } 498- /* cast to short because of win16 winsock definition */ 499- if ((short)he->h_addrtype != AF_INET) { 500- BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n"); 501- return (0); 502- } 503- ip[0] = he->h_addr_list[0][0]; 504- ip[1] = he->h_addr_list[0][1]; 505- ip[2] = he->h_addr_list[0][2]; 506- ip[3] = he->h_addr_list[0][3]; 507- } 508- return (1); 509- err: 510- return (0); 511-} 512- 513-int extract_port(char *str, short *port_ptr) 514-{ 515- int i; 516- struct servent *s; 517- 518- i = atoi(str); 519- if (i != 0) 520- *port_ptr = (unsigned short)i; 521- else { 522- s = getservbyname(str, "tcp"); 523- if (s == NULL) { 524- BIO_printf(bio_err, "getservbyname failure for %s\n", str); 525- return (0); 526- } 527- *port_ptr = ntohs((unsigned short)s->s_port); 528- } 529 return (1); 530 } 531 532