1/* crypto/bio/b_sock.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include <stdio.h> 60#include <stdlib.h> 61#include <errno.h> 62#define USE_SOCKETS 63#include "cryptlib.h" 64#include <openssl/bio.h> 65#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK) 66# include <netdb.h> 67# if defined(NETWARE_CLIB) 68# include <sys/ioctl.h> 69NETDB_DEFINE_CONTEXT 70# endif 71#endif 72#ifndef OPENSSL_NO_SOCK 73# include <openssl/dso.h> 74# define SOCKET_PROTOCOL IPPROTO_TCP 75# ifdef SO_MAXCONN 76# define MAX_LISTEN SO_MAXCONN 77# elif defined(SOMAXCONN) 78# define MAX_LISTEN SOMAXCONN 79# else 80# define MAX_LISTEN 32 81# endif 82# if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) 83static int wsa_init_done = 0; 84# endif 85 86/* 87 * WSAAPI specifier is required to make indirect calls to run-time 88 * linked WinSock 2 functions used in this module, to be specific 89 * [get|free]addrinfo and getnameinfo. This is because WinSock uses 90 * uses non-C calling convention, __stdcall vs. __cdecl, on x86 91 * Windows. On non-WinSock platforms WSAAPI needs to be void. 92 */ 93# ifndef WSAAPI 94# define WSAAPI 95# endif 96 97# if 0 98static unsigned long BIO_ghbn_hits = 0L; 99static unsigned long BIO_ghbn_miss = 0L; 100 101# define GHBN_NUM 4 102static struct ghbn_cache_st { 103 char name[129]; 104 struct hostent *ent; 105 unsigned long order; 106} ghbn_cache[GHBN_NUM]; 107# endif 108 109static int get_ip(const char *str, unsigned char *ip); 110# if 0 111static void ghbn_free(struct hostent *a); 112static struct hostent *ghbn_dup(struct hostent *a); 113# endif 114int BIO_get_host_ip(const char *str, unsigned char *ip) 115{ 116 int i; 117 int err = 1; 118 int locked = 0; 119 struct hostent *he; 120 121 i = get_ip(str, ip); 122 if (i < 0) { 123 BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS); 124 goto err; 125 } 126 127 /* 128 * At this point, we have something that is most probably correct in some 129 * way, so let's init the socket. 130 */ 131 if (BIO_sock_init() != 1) 132 return 0; /* don't generate another error code here */ 133 134 /* 135 * If the string actually contained an IP address, we need not do 136 * anything more 137 */ 138 if (i > 0) 139 return (1); 140 141 /* do a gethostbyname */ 142 CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); 143 locked = 1; 144 he = BIO_gethostbyname(str); 145 if (he == NULL) { 146 BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP); 147 goto err; 148 } 149 150 /* cast to short because of win16 winsock definition */ 151 if ((short)he->h_addrtype != AF_INET) { 152 BIOerr(BIO_F_BIO_GET_HOST_IP, 153 BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); 154 goto err; 155 } 156 for (i = 0; i < 4; i++) 157 ip[i] = he->h_addr_list[0][i]; 158 err = 0; 159 160 err: 161 if (locked) 162 CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); 163 if (err) { 164 ERR_add_error_data(2, "host=", str); 165 return 0; 166 } else 167 return 1; 168} 169 170int BIO_get_port(const char *str, unsigned short *port_ptr) 171{ 172 int i; 173 struct servent *s; 174 175 if (str == NULL) { 176 BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); 177 return (0); 178 } 179 i = atoi(str); 180 if (i != 0) 181 *port_ptr = (unsigned short)i; 182 else { 183 CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); 184 /* 185 * Note: under VMS with SOCKETSHR, it seems like the first parameter 186 * is 'char *', instead of 'const char *' 187 */ 188# ifndef CONST_STRICT 189 s = getservbyname((char *)str, "tcp"); 190# else 191 s = getservbyname(str, "tcp"); 192# endif 193 if (s != NULL) 194 *port_ptr = ntohs((unsigned short)s->s_port); 195 CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); 196 if (s == NULL) { 197 if (strcmp(str, "http") == 0) 198 *port_ptr = 80; 199 else if (strcmp(str, "telnet") == 0) 200 *port_ptr = 23; 201 else if (strcmp(str, "socks") == 0) 202 *port_ptr = 1080; 203 else if (strcmp(str, "https") == 0) 204 *port_ptr = 443; 205 else if (strcmp(str, "ssl") == 0) 206 *port_ptr = 443; 207 else if (strcmp(str, "ftp") == 0) 208 *port_ptr = 21; 209 else if (strcmp(str, "gopher") == 0) 210 *port_ptr = 70; 211# if 0 212 else if (strcmp(str, "wais") == 0) 213 *port_ptr = 21; 214# endif 215 else { 216 SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error()); 217 ERR_add_error_data(3, "service='", str, "'"); 218 return (0); 219 } 220 } 221 } 222 return (1); 223} 224 225int BIO_sock_error(int sock) 226{ 227 int j, i; 228 union { 229 size_t s; 230 int i; 231 } size; 232 233# if defined(OPENSSL_SYS_BEOS_R5) 234 return 0; 235# endif 236 237 /* heuristic way to adapt for platforms that expect 64-bit optlen */ 238 size.s = 0, size.i = sizeof(j); 239 /* 240 * Note: under Windows the third parameter is of type (char *) whereas 241 * under other systems it is (void *) if you don't have a cast it will 242 * choke the compiler: if you do have a cast then you can either go for 243 * (char *) or (void *). 244 */ 245 i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size); 246 if (i < 0) 247 return (1); 248 else 249 return (j); 250} 251 252# if 0 253long BIO_ghbn_ctrl(int cmd, int iarg, char *parg) 254{ 255 int i; 256 char **p; 257 258 switch (cmd) { 259 case BIO_GHBN_CTRL_HITS: 260 return (BIO_ghbn_hits); 261 /* break; */ 262 case BIO_GHBN_CTRL_MISSES: 263 return (BIO_ghbn_miss); 264 /* break; */ 265 case BIO_GHBN_CTRL_CACHE_SIZE: 266 return (GHBN_NUM); 267 /* break; */ 268 case BIO_GHBN_CTRL_GET_ENTRY: 269 if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) { 270 p = (char **)parg; 271 if (p == NULL) 272 return (0); 273 *p = ghbn_cache[iarg].name; 274 ghbn_cache[iarg].name[128] = '\0'; 275 return (1); 276 } 277 return (0); 278 /* break; */ 279 case BIO_GHBN_CTRL_FLUSH: 280 for (i = 0; i < GHBN_NUM; i++) 281 ghbn_cache[i].order = 0; 282 break; 283 default: 284 return (0); 285 } 286 return (1); 287} 288# endif 289 290# if 0 291static struct hostent *ghbn_dup(struct hostent *a) 292{ 293 struct hostent *ret; 294 int i, j; 295 296 MemCheck_off(); 297 ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent)); 298 if (ret == NULL) 299 return (NULL); 300 memset(ret, 0, sizeof(struct hostent)); 301 302 for (i = 0; a->h_aliases[i] != NULL; i++) ; 303 i++; 304 ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *)); 305 if (ret->h_aliases == NULL) 306 goto err; 307 memset(ret->h_aliases, 0, i * sizeof(char *)); 308 309 for (i = 0; a->h_addr_list[i] != NULL; i++) ; 310 i++; 311 ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *)); 312 if (ret->h_addr_list == NULL) 313 goto err; 314 memset(ret->h_addr_list, 0, i * sizeof(char *)); 315 316 j = strlen(a->h_name) + 1; 317 if ((ret->h_name = OPENSSL_malloc(j)) == NULL) 318 goto err; 319 memcpy((char *)ret->h_name, a->h_name, j); 320 for (i = 0; a->h_aliases[i] != NULL; i++) { 321 j = strlen(a->h_aliases[i]) + 1; 322 if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL) 323 goto err; 324 memcpy(ret->h_aliases[i], a->h_aliases[i], j); 325 } 326 ret->h_length = a->h_length; 327 ret->h_addrtype = a->h_addrtype; 328 for (i = 0; a->h_addr_list[i] != NULL; i++) { 329 if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL) 330 goto err; 331 memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length); 332 } 333 if (0) { 334 err: 335 if (ret != NULL) 336 ghbn_free(ret); 337 ret = NULL; 338 } 339 MemCheck_on(); 340 return (ret); 341} 342 343static void ghbn_free(struct hostent *a) 344{ 345 int i; 346 347 if (a == NULL) 348 return; 349 350 if (a->h_aliases != NULL) { 351 for (i = 0; a->h_aliases[i] != NULL; i++) 352 OPENSSL_free(a->h_aliases[i]); 353 OPENSSL_free(a->h_aliases); 354 } 355 if (a->h_addr_list != NULL) { 356 for (i = 0; a->h_addr_list[i] != NULL; i++) 357 OPENSSL_free(a->h_addr_list[i]); 358 OPENSSL_free(a->h_addr_list); 359 } 360 if (a->h_name != NULL) 361 OPENSSL_free(a->h_name); 362 OPENSSL_free(a); 363} 364 365# endif 366 367struct hostent *BIO_gethostbyname(const char *name) 368{ 369# if 1 370 /* 371 * Caching gethostbyname() results forever is wrong, so we have to let 372 * the true gethostbyname() worry about this 373 */ 374# if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__)) 375 return gethostbyname((char *)name); 376# else 377 return gethostbyname(name); 378# endif 379# else 380 struct hostent *ret; 381 int i, lowi = 0, j; 382 unsigned long low = (unsigned long)-1; 383 384# if 0 385 /* 386 * It doesn't make sense to use locking here: The function interface is 387 * not thread-safe, because threads can never be sure when some other 388 * thread destroys the data they were given a pointer to. 389 */ 390 CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); 391# endif 392 j = strlen(name); 393 if (j < 128) { 394 for (i = 0; i < GHBN_NUM; i++) { 395 if (low > ghbn_cache[i].order) { 396 low = ghbn_cache[i].order; 397 lowi = i; 398 } 399 if (ghbn_cache[i].order > 0) { 400 if (strncmp(name, ghbn_cache[i].name, 128) == 0) 401 break; 402 } 403 } 404 } else 405 i = GHBN_NUM; 406 407 if (i == GHBN_NUM) { /* no hit */ 408 BIO_ghbn_miss++; 409 /* 410 * Note: under VMS with SOCKETSHR, it seems like the first parameter 411 * is 'char *', instead of 'const char *' 412 */ 413# ifndef CONST_STRICT 414 ret = gethostbyname((char *)name); 415# else 416 ret = gethostbyname(name); 417# endif 418 419 if (ret == NULL) 420 goto end; 421 if (j > 128) { /* too big to cache */ 422# if 0 423 /* 424 * If we were trying to make this function thread-safe (which is 425 * bound to fail), we'd have to give up in this case (or allocate 426 * more memory). 427 */ 428 ret = NULL; 429# endif 430 goto end; 431 } 432 433 /* else add to cache */ 434 if (ghbn_cache[lowi].ent != NULL) 435 ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */ 436 ghbn_cache[lowi].name[0] = '\0'; 437 438 if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) { 439 BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE); 440 goto end; 441 } 442 strncpy(ghbn_cache[lowi].name, name, 128); 443 ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits; 444 } else { 445 BIO_ghbn_hits++; 446 ret = ghbn_cache[i].ent; 447 ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits; 448 } 449 end: 450# if 0 451 CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); 452# endif 453 return (ret); 454# endif 455} 456 457int BIO_sock_init(void) 458{ 459# ifdef OPENSSL_SYS_WINDOWS 460 static struct WSAData wsa_state; 461 462 if (!wsa_init_done) { 463 int err; 464 465 wsa_init_done = 1; 466 memset(&wsa_state, 0, sizeof(wsa_state)); 467 /* 468 * Not making wsa_state available to the rest of the code is formally 469 * wrong. But the structures we use are [beleived to be] invariable 470 * among Winsock DLLs, while API availability is [expected to be] 471 * probed at run-time with DSO_global_lookup. 472 */ 473 if (WSAStartup(0x0202, &wsa_state) != 0) { 474 err = WSAGetLastError(); 475 SYSerr(SYS_F_WSASTARTUP, err); 476 BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); 477 return (-1); 478 } 479 } 480# endif /* OPENSSL_SYS_WINDOWS */ 481# ifdef WATT32 482 extern int _watt_do_exit; 483 _watt_do_exit = 0; /* don't make sock_init() call exit() */ 484 if (sock_init()) 485 return (-1); 486# endif 487 488# if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) 489 WORD wVerReq; 490 WSADATA wsaData; 491 int err; 492 493 if (!wsa_init_done) { 494 wsa_init_done = 1; 495 wVerReq = MAKEWORD(2, 0); 496 err = WSAStartup(wVerReq, &wsaData); 497 if (err != 0) { 498 SYSerr(SYS_F_WSASTARTUP, err); 499 BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); 500 return (-1); 501 } 502 } 503# endif 504 505 return (1); 506} 507 508void BIO_sock_cleanup(void) 509{ 510# ifdef OPENSSL_SYS_WINDOWS 511 if (wsa_init_done) { 512 wsa_init_done = 0; 513# if 0 /* this call is claimed to be non-present in 514 * Winsock2 */ 515 WSACancelBlockingCall(); 516# endif 517 WSACleanup(); 518 } 519# elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) 520 if (wsa_init_done) { 521 wsa_init_done = 0; 522 WSACleanup(); 523 } 524# endif 525} 526 527# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000 528 529int BIO_socket_ioctl(int fd, long type, void *arg) 530{ 531 int i; 532 533# ifdef __DJGPP__ 534 i = ioctlsocket(fd, type, (char *)arg); 535# else 536# if defined(OPENSSL_SYS_VMS) 537 /*- 538 * 2011-02-18 SMS. 539 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we 540 * observe that all the consumers pass in an "unsigned long *", 541 * so we arrange a local copy with a short pointer, and use 542 * that, instead. 543 */ 544# if __INITIAL_POINTER_SIZE == 64 545# define ARG arg_32p 546# pragma pointer_size save 547# pragma pointer_size 32 548 unsigned long arg_32; 549 unsigned long *arg_32p; 550# pragma pointer_size restore 551 arg_32p = &arg_32; 552 arg_32 = *((unsigned long *)arg); 553# else /* __INITIAL_POINTER_SIZE == 64 */ 554# define ARG arg 555# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ 556# else /* defined(OPENSSL_SYS_VMS) */ 557# define ARG arg 558# endif /* defined(OPENSSL_SYS_VMS) [else] */ 559 560 i = ioctlsocket(fd, type, ARG); 561# endif /* __DJGPP__ */ 562 if (i < 0) 563 SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error()); 564 return (i); 565} 566# endif /* __VMS_VER */ 567 568/* 569 * The reason I have implemented this instead of using sscanf is because 570 * Visual C 1.52c gives an unresolved external when linking a DLL :-( 571 */ 572static int get_ip(const char *str, unsigned char ip[4]) 573{ 574 unsigned int tmp[4]; 575 int num = 0, c, ok = 0; 576 577 tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; 578 579 for (;;) { 580 c = *(str++); 581 if ((c >= '0') && (c <= '9')) { 582 ok = 1; 583 tmp[num] = tmp[num] * 10 + c - '0'; 584 if (tmp[num] > 255) 585 return (0); 586 } else if (c == '.') { 587 if (!ok) 588 return (-1); 589 if (num == 3) 590 return (0); 591 num++; 592 ok = 0; 593 } else if (c == '\0' && (num == 3) && ok) 594 break; 595 else 596 return (0); 597 } 598 ip[0] = tmp[0]; 599 ip[1] = tmp[1]; 600 ip[2] = tmp[2]; 601 ip[3] = tmp[3]; 602 return (1); 603} 604 605int BIO_get_accept_socket(char *host, int bind_mode) 606{ 607 int ret = 0; 608 union { 609 struct sockaddr sa; 610 struct sockaddr_in sa_in; 611# if OPENSSL_USE_IPV6 612 struct sockaddr_in6 sa_in6; 613# endif 614 } server, client; 615 int s = INVALID_SOCKET, cs, addrlen; 616 unsigned char ip[4]; 617 unsigned short port; 618 char *str = NULL, *e; 619 char *h, *p; 620 unsigned long l; 621 int err_num; 622 623 if (BIO_sock_init() != 1) 624 return (INVALID_SOCKET); 625 626 if ((str = BUF_strdup(host)) == NULL) 627 return (INVALID_SOCKET); 628 629 h = p = NULL; 630 h = str; 631 for (e = str; *e; e++) { 632 if (*e == ':') { 633 p = e; 634 } else if (*e == '/') { 635 *e = '\0'; 636 break; 637 } 638 } 639 if (p) 640 *p++ = '\0'; /* points at last ':', '::port' is special 641 * [see below] */ 642 else 643 p = h, h = NULL; 644 645# ifdef EAI_FAMILY 646 do { 647 static union { 648 void *p; 649 int (WSAAPI *f) (const char *, const char *, 650 const struct addrinfo *, struct addrinfo **); 651 } p_getaddrinfo = { 652 NULL 653 }; 654 static union { 655 void *p; 656 void (WSAAPI *f) (struct addrinfo *); 657 } p_freeaddrinfo = { 658 NULL 659 }; 660 struct addrinfo *res, hint; 661 662 if (p_getaddrinfo.p == NULL) { 663 if ((p_getaddrinfo.p = DSO_global_lookup("getaddrinfo")) == NULL 664 || (p_freeaddrinfo.p = 665 DSO_global_lookup("freeaddrinfo")) == NULL) 666 p_getaddrinfo.p = (void *)-1; 667 } 668 if (p_getaddrinfo.p == (void *)-1) 669 break; 670 671 /* 672 * '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris, 673 * default to IPv6 without any hint. Also note that commonly IPv6 674 * wildchard socket can service IPv4 connections just as well... 675 */ 676 memset(&hint, 0, sizeof(hint)); 677 hint.ai_flags = AI_PASSIVE; 678 if (h) { 679 if (strchr(h, ':')) { 680 if (h[1] == '\0') 681 h = NULL; 682# if OPENSSL_USE_IPV6 683 hint.ai_family = AF_INET6; 684# else 685 h = NULL; 686# endif 687 } else if (h[0] == '*' && h[1] == '\0') { 688 hint.ai_family = AF_INET; 689 h = NULL; 690 } 691 } 692 693 if ((*p_getaddrinfo.f) (h, p, &hint, &res)) 694 break; 695 696 addrlen = res->ai_addrlen <= sizeof(server) ? 697 res->ai_addrlen : sizeof(server); 698 memcpy(&server, res->ai_addr, addrlen); 699 700 (*p_freeaddrinfo.f) (res); 701 goto again; 702 } while (0); 703# endif 704 705 if (!BIO_get_port(p, &port)) 706 goto err; 707 708 memset((char *)&server, 0, sizeof(server)); 709 server.sa_in.sin_family = AF_INET; 710 server.sa_in.sin_port = htons(port); 711 addrlen = sizeof(server.sa_in); 712 713 if (h == NULL || strcmp(h, "*") == 0) 714 server.sa_in.sin_addr.s_addr = INADDR_ANY; 715 else { 716 if (!BIO_get_host_ip(h, &(ip[0]))) 717 goto err; 718 l = (unsigned long) 719 ((unsigned long)ip[0] << 24L) | 720 ((unsigned long)ip[1] << 16L) | 721 ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]); 722 server.sa_in.sin_addr.s_addr = htonl(l); 723 } 724 725 again: 726 s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); 727 if (s == INVALID_SOCKET) { 728 SYSerr(SYS_F_SOCKET, get_last_socket_error()); 729 ERR_add_error_data(3, "port='", host, "'"); 730 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET); 731 goto err; 732 } 733# ifdef SO_REUSEADDR 734 if (bind_mode == BIO_BIND_REUSEADDR) { 735 int i = 1; 736 737 ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)); 738 bind_mode = BIO_BIND_NORMAL; 739 } 740# endif 741 if (bind(s, &server.sa, addrlen) == -1) { 742# ifdef SO_REUSEADDR 743 err_num = get_last_socket_error(); 744 if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && 745# ifdef OPENSSL_SYS_WINDOWS 746 /* 747 * Some versions of Windows define EADDRINUSE to a dummy value. 748 */ 749 (err_num == WSAEADDRINUSE)) 750# else 751 (err_num == EADDRINUSE)) 752# endif 753 { 754 client = server; 755 if (h == NULL || strcmp(h, "*") == 0) { 756# if OPENSSL_USE_IPV6 757 if (client.sa.sa_family == AF_INET6) { 758 memset(&client.sa_in6.sin6_addr, 0, 759 sizeof(client.sa_in6.sin6_addr)); 760 client.sa_in6.sin6_addr.s6_addr[15] = 1; 761 } else 762# endif 763 if (client.sa.sa_family == AF_INET) { 764 client.sa_in.sin_addr.s_addr = htonl(0x7F000001); 765 } else 766 goto err; 767 } 768 cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); 769 if (cs != INVALID_SOCKET) { 770 int ii; 771 ii = connect(cs, &client.sa, addrlen); 772 closesocket(cs); 773 if (ii == INVALID_SOCKET) { 774 bind_mode = BIO_BIND_REUSEADDR; 775 closesocket(s); 776 goto again; 777 } 778 /* else error */ 779 } 780 /* else error */ 781 } 782# endif 783 SYSerr(SYS_F_BIND, err_num); 784 ERR_add_error_data(3, "port='", host, "'"); 785 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET); 786 goto err; 787 } 788 if (listen(s, MAX_LISTEN) == -1) { 789 SYSerr(SYS_F_BIND, get_last_socket_error()); 790 ERR_add_error_data(3, "port='", host, "'"); 791 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET); 792 goto err; 793 } 794 ret = 1; 795 err: 796 if (str != NULL) 797 OPENSSL_free(str); 798 if ((ret == 0) && (s != INVALID_SOCKET)) { 799 closesocket(s); 800 s = INVALID_SOCKET; 801 } 802 return (s); 803} 804 805int BIO_accept(int sock, char **addr) 806{ 807 int ret = INVALID_SOCKET; 808 unsigned long l; 809 unsigned short port; 810 char *p; 811 812 struct { 813 /* 814 * As for following union. Trouble is that there are platforms 815 * that have socklen_t and there are platforms that don't, on 816 * some platforms socklen_t is int and on some size_t. So what 817 * one can do? One can cook #ifdef spaghetti, which is nothing 818 * but masochistic. Or one can do union between int and size_t. 819 * One naturally does it primarily for 64-bit platforms where 820 * sizeof(int) != sizeof(size_t). But would it work? Note that 821 * if size_t member is initialized to 0, then later int member 822 * assignment naturally does the job on little-endian platforms 823 * regardless accept's expectations! What about big-endians? 824 * If accept expects int*, then it works, and if size_t*, then 825 * length value would appear as unreasonably large. But this 826 * won't prevent it from filling in the address structure. The 827 * trouble of course would be if accept returns more data than 828 * actual buffer can accomodate and overwrite stack... That's 829 * where early OPENSSL_assert comes into picture. Besides, the 830 * only 64-bit big-endian platform found so far that expects 831 * size_t* is HP-UX, where stack grows towards higher address. 832 * <appro> 833 */ 834 union { 835 size_t s; 836 int i; 837 } len; 838 union { 839 struct sockaddr sa; 840 struct sockaddr_in sa_in; 841# if OPENSSL_USE_IPV6 842 struct sockaddr_in6 sa_in6; 843# endif 844 } from; 845 } sa; 846 847 sa.len.s = 0; 848 sa.len.i = sizeof(sa.from); 849 memset(&sa.from, 0, sizeof(sa.from)); 850 ret = accept(sock, &sa.from.sa, (void *)&sa.len); 851 if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { 852 OPENSSL_assert(sa.len.s <= sizeof(sa.from)); 853 sa.len.i = (int)sa.len.s; 854 /* use sa.len.i from this point */ 855 } 856 if (ret == INVALID_SOCKET) { 857 if (BIO_sock_should_retry(ret)) 858 return -2; 859 SYSerr(SYS_F_ACCEPT, get_last_socket_error()); 860 BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR); 861 goto end; 862 } 863 864 if (addr == NULL) 865 goto end; 866 867# ifdef EAI_FAMILY 868 do { 869 char h[NI_MAXHOST], s[NI_MAXSERV]; 870 size_t nl; 871 static union { 872 void *p; 873 int (WSAAPI *f) (const struct sockaddr *, size_t /* socklen_t */ , 874 char *, size_t, char *, size_t, int); 875 } p_getnameinfo = { 876 NULL 877 }; 878 /* 879 * 2nd argument to getnameinfo is specified to be socklen_t. 880 * Unfortunately there is a number of environments where socklen_t is 881 * not defined. As it's passed by value, it's safe to pass it as 882 * size_t... <appro> 883 */ 884 885 if (p_getnameinfo.p == NULL) { 886 if ((p_getnameinfo.p = DSO_global_lookup("getnameinfo")) == NULL) 887 p_getnameinfo.p = (void *)-1; 888 } 889 if (p_getnameinfo.p == (void *)-1) 890 break; 891 892 if ((*p_getnameinfo.f) (&sa.from.sa, sa.len.i, h, sizeof(h), s, 893 sizeof(s), NI_NUMERICHOST | NI_NUMERICSERV)) 894 break; 895 nl = strlen(h) + strlen(s) + 2; 896 p = *addr; 897 if (p) { 898 *p = '\0'; 899 p = OPENSSL_realloc(p, nl); 900 } else { 901 p = OPENSSL_malloc(nl); 902 } 903 if (p == NULL) { 904 BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); 905 goto end; 906 } 907 *addr = p; 908 BIO_snprintf(*addr, nl, "%s:%s", h, s); 909 goto end; 910 } while (0); 911# endif 912 if (sa.from.sa.sa_family != AF_INET) 913 goto end; 914 l = ntohl(sa.from.sa_in.sin_addr.s_addr); 915 port = ntohs(sa.from.sa_in.sin_port); 916 if (*addr == NULL) { 917 if ((p = OPENSSL_malloc(24)) == NULL) { 918 BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); 919 goto end; 920 } 921 *addr = p; 922 } 923 BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d", 924 (unsigned char)(l >> 24L) & 0xff, 925 (unsigned char)(l >> 16L) & 0xff, 926 (unsigned char)(l >> 8L) & 0xff, 927 (unsigned char)(l) & 0xff, port); 928 end: 929 return (ret); 930} 931 932int BIO_set_tcp_ndelay(int s, int on) 933{ 934 int ret = 0; 935# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) 936 int opt; 937 938# ifdef SOL_TCP 939 opt = SOL_TCP; 940# else 941# ifdef IPPROTO_TCP 942 opt = IPPROTO_TCP; 943# endif 944# endif 945 946 ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on)); 947# endif 948 return (ret == 0); 949} 950 951int BIO_socket_nbio(int s, int mode) 952{ 953 int ret = -1; 954 int l; 955 956 l = mode; 957# ifdef FIONBIO 958 ret = BIO_socket_ioctl(s, FIONBIO, &l); 959# endif 960 return (ret == 0); 961} 962#endif 963