1 /* $NetBSD: getaddrinfo.c,v 1.82 2006/03/25 12:09:40 rpaulo Exp $ */ 2 /* $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Issues to be discussed: 35 * - Thread safe-ness must be checked. 36 * - Return values. There are nonstandard return values defined and used 37 * in the source code. This is because RFC2553 is silent about which error 38 * code must be returned for which situation. 39 * - IPv4 classful (shortened) form. RFC2553 is silent about it. XNET 5.2 40 * says to use inet_aton() to convert IPv4 numeric to binary (alows 41 * classful form as a result). 42 * current code - disallow classful form for IPv4 (due to use of inet_pton). 43 * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is 44 * invalid. 45 * current code - SEGV on freeaddrinfo(NULL) 46 * Note: 47 * - We use getipnodebyname() just for thread-safeness. There's no intent 48 * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to 49 * getipnodebyname(). 50 * - The code filters out AFs that are not supported by the kernel, 51 * when globbing NULL hostname (to loopback, or wildcard). Is it the right 52 * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG 53 * in ai_flags? 54 * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague. 55 * (1) what should we do against numeric hostname (2) what should we do 56 * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready? 57 * non-loopback address configured? global address configured? 58 * - To avoid search order issue, we have a big amount of code duplicate 59 * from gethnamaddr.c and some other places. The issues that there's no 60 * lower layer function to lookup "IPv4 or IPv6" record. Calling 61 * gethostbyname2 from getaddrinfo will end up in wrong search order, as 62 * follows: 63 * - The code makes use of following calls when asked to resolver with 64 * ai_family = PF_UNSPEC: 65 * getipnodebyname(host, AF_INET6); 66 * getipnodebyname(host, AF_INET); 67 * This will result in the following queries if the node is configure to 68 * prefer /etc/hosts than DNS: 69 * lookup /etc/hosts for IPv6 address 70 * lookup DNS for IPv6 address 71 * lookup /etc/hosts for IPv4 address 72 * lookup DNS for IPv4 address 73 * which may not meet people's requirement. 74 * The right thing to happen is to have underlying layer which does 75 * PF_UNSPEC lookup (lookup both) and return chain of addrinfos. 76 * This would result in a bit of code duplicate with _dns_ghbyname() and 77 * friends. 78 */ 79 80 #include <fcntl.h> 81 #include <sys/cdefs.h> 82 #include <sys/types.h> 83 #include <sys/stat.h> 84 #include <sys/param.h> 85 #include <sys/socket.h> 86 #include <sys/un.h> 87 #include <net/if.h> 88 #include <netinet/in.h> 89 #include <arpa/inet.h> 90 #include "arpa_nameser.h" 91 #include <assert.h> 92 #include <ctype.h> 93 #include <errno.h> 94 #include <netdb.h> 95 #include "resolv_private.h" 96 #include <stddef.h> 97 #include <stdio.h> 98 #include <stdlib.h> 99 #include <string.h> 100 #include <strings.h> 101 #include <unistd.h> 102 103 #include <syslog.h> 104 #include <stdarg.h> 105 #include "nsswitch.h" 106 107 #ifdef ANDROID_CHANGES 108 #include <sys/system_properties.h> 109 #endif /* ANDROID_CHANGES */ 110 111 typedef union sockaddr_union { 112 struct sockaddr generic; 113 struct sockaddr_in in; 114 struct sockaddr_in6 in6; 115 } sockaddr_union; 116 117 #define SUCCESS 0 118 #define ANY 0 119 #define YES 1 120 #define NO 0 121 122 static const char in_addrany[] = { 0, 0, 0, 0 }; 123 static const char in_loopback[] = { 127, 0, 0, 1 }; 124 #ifdef INET6 125 static const char in6_addrany[] = { 126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 127 }; 128 static const char in6_loopback[] = { 129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 130 }; 131 #endif 132 133 static const struct afd { 134 int a_af; 135 int a_addrlen; 136 int a_socklen; 137 int a_off; 138 const char *a_addrany; 139 const char *a_loopback; 140 int a_scoped; 141 } afdl [] = { 142 #ifdef INET6 143 {PF_INET6, sizeof(struct in6_addr), 144 sizeof(struct sockaddr_in6), 145 offsetof(struct sockaddr_in6, sin6_addr), 146 in6_addrany, in6_loopback, 1}, 147 #endif 148 {PF_INET, sizeof(struct in_addr), 149 sizeof(struct sockaddr_in), 150 offsetof(struct sockaddr_in, sin_addr), 151 in_addrany, in_loopback, 0}, 152 {0, 0, 0, 0, NULL, NULL, 0}, 153 }; 154 155 struct explore { 156 int e_af; 157 int e_socktype; 158 int e_protocol; 159 const char *e_protostr; 160 int e_wild; 161 #define WILD_AF(ex) ((ex)->e_wild & 0x01) 162 #define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) 163 #define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) 164 }; 165 166 static const struct explore explore[] = { 167 #if 0 168 { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, 169 #endif 170 #ifdef INET6 171 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 172 { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 173 { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, 174 #endif 175 { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 176 { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 177 { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, 178 { PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 179 { PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 180 { PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 }, 181 { -1, 0, 0, NULL, 0 }, 182 }; 183 184 #ifdef INET6 185 #define PTON_MAX 16 186 #else 187 #define PTON_MAX 4 188 #endif 189 190 static const ns_src default_dns_files[] = { 191 { NSSRC_FILES, NS_SUCCESS }, 192 { NSSRC_DNS, NS_SUCCESS }, 193 { 0, 0 } 194 }; 195 196 #define MAXPACKET (64*1024) 197 198 typedef union { 199 HEADER hdr; 200 u_char buf[MAXPACKET]; 201 } querybuf; 202 203 struct res_target { 204 struct res_target *next; 205 const char *name; /* domain name */ 206 int qclass, qtype; /* class and type of query */ 207 u_char *answer; /* buffer to put answer */ 208 int anslen; /* size of answer buffer */ 209 int n; /* result length */ 210 }; 211 212 static int str2number(const char *); 213 static int explore_fqdn(const struct addrinfo *, const char *, 214 const char *, struct addrinfo **); 215 static int explore_null(const struct addrinfo *, 216 const char *, struct addrinfo **); 217 static int explore_numeric(const struct addrinfo *, const char *, 218 const char *, struct addrinfo **, const char *); 219 static int explore_numeric_scope(const struct addrinfo *, const char *, 220 const char *, struct addrinfo **); 221 static int get_canonname(const struct addrinfo *, 222 struct addrinfo *, const char *); 223 static struct addrinfo *get_ai(const struct addrinfo *, 224 const struct afd *, const char *); 225 static int get_portmatch(const struct addrinfo *, const char *); 226 static int get_port(const struct addrinfo *, const char *, int); 227 static const struct afd *find_afd(int); 228 #ifdef INET6 229 static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *); 230 #endif 231 232 static struct addrinfo *getanswer(const querybuf *, int, const char *, int, 233 const struct addrinfo *); 234 static int _dns_getaddrinfo(void *, void *, va_list); 235 static void _sethtent(FILE **); 236 static void _endhtent(FILE **); 237 static struct addrinfo *_gethtent(FILE **, const char *, 238 const struct addrinfo *); 239 static int _files_getaddrinfo(void *, void *, va_list); 240 241 static int res_queryN(const char *, struct res_target *, res_state); 242 static int res_searchN(const char *, struct res_target *, res_state); 243 static int res_querydomainN(const char *, const char *, 244 struct res_target *, res_state); 245 246 static const char * const ai_errlist[] = { 247 "Success", 248 "Address family for hostname not supported", /* EAI_ADDRFAMILY */ 249 "Temporary failure in name resolution", /* EAI_AGAIN */ 250 "Invalid value for ai_flags", /* EAI_BADFLAGS */ 251 "Non-recoverable failure in name resolution", /* EAI_FAIL */ 252 "ai_family not supported", /* EAI_FAMILY */ 253 "Memory allocation failure", /* EAI_MEMORY */ 254 "No address associated with hostname", /* EAI_NODATA */ 255 "hostname nor servname provided, or not known", /* EAI_NONAME */ 256 "servname not supported for ai_socktype", /* EAI_SERVICE */ 257 "ai_socktype not supported", /* EAI_SOCKTYPE */ 258 "System error returned in errno", /* EAI_SYSTEM */ 259 "Invalid value for hints", /* EAI_BADHINTS */ 260 "Resolved protocol is unknown", /* EAI_PROTOCOL */ 261 "Argument buffer overflow", /* EAI_OVERFLOW */ 262 "Unknown error", /* EAI_MAX */ 263 }; 264 265 /* XXX macros that make external reference is BAD. */ 266 267 #define GET_AI(ai, afd, addr) \ 268 do { \ 269 /* external reference: pai, error, and label free */ \ 270 (ai) = get_ai(pai, (afd), (addr)); \ 271 if ((ai) == NULL) { \ 272 error = EAI_MEMORY; \ 273 goto free; \ 274 } \ 275 } while (/*CONSTCOND*/0) 276 277 #define GET_PORT(ai, serv) \ 278 do { \ 279 /* external reference: error and label free */ \ 280 error = get_port((ai), (serv), 0); \ 281 if (error != 0) \ 282 goto free; \ 283 } while (/*CONSTCOND*/0) 284 285 #define GET_CANONNAME(ai, str) \ 286 do { \ 287 /* external reference: pai, error and label free */ \ 288 error = get_canonname(pai, (ai), (str)); \ 289 if (error != 0) \ 290 goto free; \ 291 } while (/*CONSTCOND*/0) 292 293 #define ERR(err) \ 294 do { \ 295 /* external reference: error, and label bad */ \ 296 error = (err); \ 297 goto bad; \ 298 /*NOTREACHED*/ \ 299 } while (/*CONSTCOND*/0) 300 301 #define MATCH_FAMILY(x, y, w) \ 302 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || \ 303 (y) == PF_UNSPEC))) 304 #define MATCH(x, y, w) \ 305 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY))) 306 307 const char * 308 gai_strerror(int ecode) 309 { 310 if (ecode < 0 || ecode > EAI_MAX) 311 ecode = EAI_MAX; 312 return ai_errlist[ecode]; 313 } 314 315 void 316 freeaddrinfo(struct addrinfo *ai) 317 { 318 struct addrinfo *next; 319 320 assert(ai != NULL); 321 322 do { 323 next = ai->ai_next; 324 if (ai->ai_canonname) 325 free(ai->ai_canonname); 326 /* no need to free(ai->ai_addr) */ 327 free(ai); 328 ai = next; 329 } while (ai); 330 } 331 332 static int 333 str2number(const char *p) 334 { 335 char *ep; 336 unsigned long v; 337 338 assert(p != NULL); 339 340 if (*p == '\0') 341 return -1; 342 ep = NULL; 343 errno = 0; 344 v = strtoul(p, &ep, 10); 345 if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX) 346 return v; 347 else 348 return -1; 349 } 350 351 /* 352 * Connect a UDP socket to a given unicast address. This will cause no network 353 * traffic, but will fail fast if the system has no or limited reachability to 354 * the destination (e.g., no IPv4 address, no IPv6 default route, ...). 355 */ 356 static int 357 _test_connect(int pf, struct sockaddr *addr, size_t addrlen) { 358 int s = socket(pf, SOCK_DGRAM, IPPROTO_UDP); 359 if (s < 0) 360 return 0; 361 int ret; 362 do { 363 ret = connect(s, addr, addrlen); 364 } while (ret < 0 && errno == EINTR); 365 int success = (ret == 0); 366 do { 367 ret = close(s); 368 } while (ret < 0 && errno == EINTR); 369 return success; 370 } 371 372 /* 373 * The following functions determine whether IPv4 or IPv6 connectivity is 374 * available in order to implement AI_ADDRCONFIG. 375 * 376 * Strictly speaking, AI_ADDRCONFIG should not look at whether connectivity is 377 * available, but whether addresses of the specified family are "configured 378 * on the local system". However, bionic doesn't currently support getifaddrs, 379 * so checking for connectivity is the next best thing. 380 */ 381 static int 382 _have_ipv6() { 383 static const struct sockaddr_in6 sin6_test = { 384 .sin6_family = AF_INET6, 385 .sin6_addr.s6_addr = { // 2000:: 386 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 387 }; 388 sockaddr_union addr = { .in6 = sin6_test }; 389 return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6)); 390 } 391 392 static int 393 _have_ipv4() { 394 static const struct sockaddr_in sin_test = { 395 .sin_family = AF_INET, 396 .sin_addr.s_addr = __constant_htonl(0x08080808L) // 8.8.8.8 397 }; 398 sockaddr_union addr = { .in = sin_test }; 399 return _test_connect(PF_INET, &addr.generic, sizeof(addr.in)); 400 } 401 402 // Returns 0 on success, else returns non-zero on error (in which case 403 // getaddrinfo should continue as normal) 404 static int 405 android_getaddrinfo_proxy( 406 const char *hostname, const char *servname, 407 const struct addrinfo *hints, struct addrinfo **res) 408 { 409 int sock; 410 const int one = 1; 411 struct sockaddr_un proxy_addr; 412 const char* cache_mode = getenv("ANDROID_DNS_MODE"); 413 FILE* proxy = NULL; 414 int success = 0; 415 416 // Clear this at start, as we use its non-NULLness later (in the 417 // error path) to decide if we have to free up any memory we 418 // allocated in the process (before failing). 419 *res = NULL; 420 421 if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) { 422 // Don't use the proxy in local mode. This is used by the 423 // proxy itself. 424 return -1; 425 } 426 427 // Temporary cautious hack to disable the DNS proxy for processes 428 // requesting special treatment. Ideally the DNS proxy should 429 // accomodate these apps, though. 430 char propname[PROP_NAME_MAX]; 431 char propvalue[PROP_VALUE_MAX]; 432 snprintf(propname, sizeof(propname), "net.dns1.%d", getpid()); 433 if (__system_property_get(propname, propvalue) > 0) { 434 return -1; 435 } 436 437 // Bogus things we can't serialize. Don't use the proxy. 438 if ((hostname != NULL && 439 strcspn(hostname, " \n\r\t^'\"") != strlen(hostname)) || 440 (servname != NULL && 441 strcspn(servname, " \n\r\t^'\"") != strlen(servname))) { 442 return -1; 443 } 444 445 sock = socket(AF_UNIX, SOCK_STREAM, 0); 446 if (sock < 0) { 447 return -1; 448 } 449 450 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); 451 memset(&proxy_addr, 0, sizeof(proxy_addr)); 452 proxy_addr.sun_family = AF_UNIX; 453 strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd", 454 sizeof(proxy_addr.sun_path)); 455 if (TEMP_FAILURE_RETRY(connect(sock, 456 (const struct sockaddr*) &proxy_addr, 457 sizeof(proxy_addr))) != 0) { 458 close(sock); 459 return -1; 460 } 461 462 // Send the request. 463 proxy = fdopen(sock, "r+"); 464 if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d", 465 hostname == NULL ? "^" : hostname, 466 servname == NULL ? "^" : servname, 467 hints == NULL ? -1 : hints->ai_flags, 468 hints == NULL ? -1 : hints->ai_family, 469 hints == NULL ? -1 : hints->ai_socktype, 470 hints == NULL ? -1 : hints->ai_protocol) < 0) { 471 goto exit; 472 } 473 // literal NULL byte at end, required by FrameworkListener 474 if (fputc(0, proxy) == EOF || 475 fflush(proxy) != 0) { 476 goto exit; 477 } 478 479 int remote_rv; 480 if (fread(&remote_rv, sizeof(int), 1, proxy) != 1) { 481 goto exit; 482 } 483 484 if (remote_rv != 0) { 485 goto exit; 486 } 487 488 struct addrinfo* ai = NULL; 489 struct addrinfo** nextres = res; 490 while (1) { 491 uint32_t addrinfo_len; 492 if (fread(&addrinfo_len, sizeof(addrinfo_len), 493 1, proxy) != 1) { 494 break; 495 } 496 addrinfo_len = ntohl(addrinfo_len); 497 if (addrinfo_len == 0) { 498 success = 1; 499 break; 500 } 501 502 if (addrinfo_len < sizeof(struct addrinfo)) { 503 break; 504 } 505 struct addrinfo* ai = calloc(1, addrinfo_len + 506 sizeof(struct sockaddr_storage)); 507 if (ai == NULL) { 508 break; 509 } 510 511 if (fread(ai, addrinfo_len, 1, proxy) != 1) { 512 // Error; fall through. 513 break; 514 } 515 516 // Zero out the pointer fields we copied which aren't 517 // valid in this address space. 518 ai->ai_addr = NULL; 519 ai->ai_canonname = NULL; 520 ai->ai_next = NULL; 521 522 // struct sockaddr 523 uint32_t addr_len; 524 if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) { 525 break; 526 } 527 addr_len = ntohl(addr_len); 528 if (addr_len != 0) { 529 if (addr_len > sizeof(struct sockaddr_storage)) { 530 // Bogus; too big. 531 break; 532 } 533 struct sockaddr* addr = (struct sockaddr*)(ai + 1); 534 if (fread(addr, addr_len, 1, proxy) != 1) { 535 break; 536 } 537 ai->ai_addr = addr; 538 } 539 540 // cannonname 541 uint32_t name_len; 542 if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) { 543 break; 544 } 545 name_len = ntohl(name_len); 546 if (name_len != 0) { 547 ai->ai_canonname = (char*) malloc(name_len); 548 if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) { 549 break; 550 } 551 if (ai->ai_canonname[name_len - 1] != '\0') { 552 // The proxy should be returning this 553 // NULL-terminated. 554 break; 555 } 556 } 557 558 *nextres = ai; 559 nextres = &ai->ai_next; 560 ai = NULL; 561 } 562 563 if (ai != NULL) { 564 // Clean up partially-built addrinfo that we never ended up 565 // attaching to the response. 566 freeaddrinfo(ai); 567 } 568 exit: 569 if (proxy != NULL) { 570 fclose(proxy); 571 } 572 573 if (success) { 574 return 0; 575 } 576 577 // Proxy failed; fall through to local 578 // resolver case. But first clean up any 579 // memory we might've allocated. 580 if (*res) { 581 freeaddrinfo(*res); 582 *res = NULL; 583 } 584 return -1; 585 } 586 587 int 588 getaddrinfo(const char *hostname, const char *servname, 589 const struct addrinfo *hints, struct addrinfo **res) 590 { 591 struct addrinfo sentinel; 592 struct addrinfo *cur; 593 int error = 0; 594 struct addrinfo ai; 595 struct addrinfo ai0; 596 struct addrinfo *pai; 597 const struct explore *ex; 598 599 /* hostname is allowed to be NULL */ 600 /* servname is allowed to be NULL */ 601 /* hints is allowed to be NULL */ 602 assert(res != NULL); 603 604 memset(&sentinel, 0, sizeof(sentinel)); 605 cur = &sentinel; 606 pai = &ai; 607 pai->ai_flags = 0; 608 pai->ai_family = PF_UNSPEC; 609 pai->ai_socktype = ANY; 610 pai->ai_protocol = ANY; 611 pai->ai_addrlen = 0; 612 pai->ai_canonname = NULL; 613 pai->ai_addr = NULL; 614 pai->ai_next = NULL; 615 616 if (hostname == NULL && servname == NULL) 617 return EAI_NONAME; 618 if (hints) { 619 /* error check for hints */ 620 if (hints->ai_addrlen || hints->ai_canonname || 621 hints->ai_addr || hints->ai_next) 622 ERR(EAI_BADHINTS); /* xxx */ 623 if (hints->ai_flags & ~AI_MASK) 624 ERR(EAI_BADFLAGS); 625 switch (hints->ai_family) { 626 case PF_UNSPEC: 627 case PF_INET: 628 #ifdef INET6 629 case PF_INET6: 630 #endif 631 break; 632 default: 633 ERR(EAI_FAMILY); 634 } 635 memcpy(pai, hints, sizeof(*pai)); 636 637 /* 638 * if both socktype/protocol are specified, check if they 639 * are meaningful combination. 640 */ 641 if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { 642 for (ex = explore; ex->e_af >= 0; ex++) { 643 if (pai->ai_family != ex->e_af) 644 continue; 645 if (ex->e_socktype == ANY) 646 continue; 647 if (ex->e_protocol == ANY) 648 continue; 649 if (pai->ai_socktype == ex->e_socktype 650 && pai->ai_protocol != ex->e_protocol) { 651 ERR(EAI_BADHINTS); 652 } 653 } 654 } 655 } 656 657 /* 658 * check for special cases. (1) numeric servname is disallowed if 659 * socktype/protocol are left unspecified. (2) servname is disallowed 660 * for raw and other inet{,6} sockets. 661 */ 662 if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) 663 #ifdef PF_INET6 664 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) 665 #endif 666 ) { 667 ai0 = *pai; /* backup *pai */ 668 669 if (pai->ai_family == PF_UNSPEC) { 670 #ifdef PF_INET6 671 pai->ai_family = PF_INET6; 672 #else 673 pai->ai_family = PF_INET; 674 #endif 675 } 676 error = get_portmatch(pai, servname); 677 if (error) 678 ERR(error); 679 680 *pai = ai0; 681 } 682 683 ai0 = *pai; 684 685 /* NULL hostname, or numeric hostname */ 686 for (ex = explore; ex->e_af >= 0; ex++) { 687 *pai = ai0; 688 689 /* PF_UNSPEC entries are prepared for DNS queries only */ 690 if (ex->e_af == PF_UNSPEC) 691 continue; 692 693 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 694 continue; 695 if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) 696 continue; 697 if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) 698 continue; 699 700 if (pai->ai_family == PF_UNSPEC) 701 pai->ai_family = ex->e_af; 702 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 703 pai->ai_socktype = ex->e_socktype; 704 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 705 pai->ai_protocol = ex->e_protocol; 706 707 if (hostname == NULL) 708 error = explore_null(pai, servname, &cur->ai_next); 709 else 710 error = explore_numeric_scope(pai, hostname, servname, 711 &cur->ai_next); 712 713 if (error) 714 goto free; 715 716 while (cur->ai_next) 717 cur = cur->ai_next; 718 } 719 720 /* 721 * XXX 722 * If numeric representation of AF1 can be interpreted as FQDN 723 * representation of AF2, we need to think again about the code below. 724 */ 725 if (sentinel.ai_next) 726 goto good; 727 728 if (hostname == NULL) 729 ERR(EAI_NODATA); 730 if (pai->ai_flags & AI_NUMERICHOST) 731 ERR(EAI_NONAME); 732 733 /* 734 * BEGIN ANDROID CHANGES; proxying to the cache 735 */ 736 if (android_getaddrinfo_proxy(hostname, servname, hints, res) == 0) { 737 return 0; 738 } 739 740 /* 741 * hostname as alphabetical name. 742 * we would like to prefer AF_INET6 than AF_INET, so we'll make a 743 * outer loop by AFs. 744 */ 745 for (ex = explore; ex->e_af >= 0; ex++) { 746 *pai = ai0; 747 748 /* require exact match for family field */ 749 if (pai->ai_family != ex->e_af) 750 continue; 751 752 if (!MATCH(pai->ai_socktype, ex->e_socktype, 753 WILD_SOCKTYPE(ex))) { 754 continue; 755 } 756 if (!MATCH(pai->ai_protocol, ex->e_protocol, 757 WILD_PROTOCOL(ex))) { 758 continue; 759 } 760 761 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 762 pai->ai_socktype = ex->e_socktype; 763 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 764 pai->ai_protocol = ex->e_protocol; 765 766 error = explore_fqdn(pai, hostname, servname, 767 &cur->ai_next); 768 769 while (cur && cur->ai_next) 770 cur = cur->ai_next; 771 } 772 773 /* XXX */ 774 if (sentinel.ai_next) 775 error = 0; 776 777 if (error) 778 goto free; 779 if (error == 0) { 780 if (sentinel.ai_next) { 781 good: 782 *res = sentinel.ai_next; 783 return SUCCESS; 784 } else 785 error = EAI_FAIL; 786 } 787 free: 788 bad: 789 if (sentinel.ai_next) 790 freeaddrinfo(sentinel.ai_next); 791 *res = NULL; 792 return error; 793 } 794 795 /* 796 * FQDN hostname, DNS lookup 797 */ 798 static int 799 explore_fqdn(const struct addrinfo *pai, const char *hostname, 800 const char *servname, struct addrinfo **res) 801 { 802 struct addrinfo *result; 803 struct addrinfo *cur; 804 int error = 0; 805 static const ns_dtab dtab[] = { 806 NS_FILES_CB(_files_getaddrinfo, NULL) 807 { NSSRC_DNS, _dns_getaddrinfo, NULL }, /* force -DHESIOD */ 808 NS_NIS_CB(_yp_getaddrinfo, NULL) 809 { 0, 0, 0 } 810 }; 811 812 assert(pai != NULL); 813 /* hostname may be NULL */ 814 /* servname may be NULL */ 815 assert(res != NULL); 816 817 result = NULL; 818 819 /* 820 * if the servname does not match socktype/protocol, ignore it. 821 */ 822 if (get_portmatch(pai, servname) != 0) 823 return 0; 824 825 switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo", 826 default_dns_files, hostname, pai)) { 827 case NS_TRYAGAIN: 828 error = EAI_AGAIN; 829 goto free; 830 case NS_UNAVAIL: 831 error = EAI_FAIL; 832 goto free; 833 case NS_NOTFOUND: 834 error = EAI_NODATA; 835 goto free; 836 case NS_SUCCESS: 837 error = 0; 838 for (cur = result; cur; cur = cur->ai_next) { 839 GET_PORT(cur, servname); 840 /* canonname should be filled already */ 841 } 842 break; 843 } 844 845 *res = result; 846 847 return 0; 848 849 free: 850 if (result) 851 freeaddrinfo(result); 852 return error; 853 } 854 855 /* 856 * hostname == NULL. 857 * passive socket -> anyaddr (0.0.0.0 or ::) 858 * non-passive socket -> localhost (127.0.0.1 or ::1) 859 */ 860 static int 861 explore_null(const struct addrinfo *pai, const char *servname, 862 struct addrinfo **res) 863 { 864 int s; 865 const struct afd *afd; 866 struct addrinfo *cur; 867 struct addrinfo sentinel; 868 int error; 869 870 assert(pai != NULL); 871 /* servname may be NULL */ 872 assert(res != NULL); 873 874 *res = NULL; 875 sentinel.ai_next = NULL; 876 cur = &sentinel; 877 878 /* 879 * filter out AFs that are not supported by the kernel 880 * XXX errno? 881 */ 882 s = socket(pai->ai_family, SOCK_DGRAM, 0); 883 if (s < 0) { 884 if (errno != EMFILE) 885 return 0; 886 } else 887 close(s); 888 889 /* 890 * if the servname does not match socktype/protocol, ignore it. 891 */ 892 if (get_portmatch(pai, servname) != 0) 893 return 0; 894 895 afd = find_afd(pai->ai_family); 896 if (afd == NULL) 897 return 0; 898 899 if (pai->ai_flags & AI_PASSIVE) { 900 GET_AI(cur->ai_next, afd, afd->a_addrany); 901 /* xxx meaningless? 902 * GET_CANONNAME(cur->ai_next, "anyaddr"); 903 */ 904 GET_PORT(cur->ai_next, servname); 905 } else { 906 GET_AI(cur->ai_next, afd, afd->a_loopback); 907 /* xxx meaningless? 908 * GET_CANONNAME(cur->ai_next, "localhost"); 909 */ 910 GET_PORT(cur->ai_next, servname); 911 } 912 cur = cur->ai_next; 913 914 *res = sentinel.ai_next; 915 return 0; 916 917 free: 918 if (sentinel.ai_next) 919 freeaddrinfo(sentinel.ai_next); 920 return error; 921 } 922 923 /* 924 * numeric hostname 925 */ 926 static int 927 explore_numeric(const struct addrinfo *pai, const char *hostname, 928 const char *servname, struct addrinfo **res, const char *canonname) 929 { 930 const struct afd *afd; 931 struct addrinfo *cur; 932 struct addrinfo sentinel; 933 int error; 934 char pton[PTON_MAX]; 935 936 assert(pai != NULL); 937 /* hostname may be NULL */ 938 /* servname may be NULL */ 939 assert(res != NULL); 940 941 *res = NULL; 942 sentinel.ai_next = NULL; 943 cur = &sentinel; 944 945 /* 946 * if the servname does not match socktype/protocol, ignore it. 947 */ 948 if (get_portmatch(pai, servname) != 0) 949 return 0; 950 951 afd = find_afd(pai->ai_family); 952 if (afd == NULL) 953 return 0; 954 955 switch (afd->a_af) { 956 #if 0 /*X/Open spec*/ 957 case AF_INET: 958 if (inet_aton(hostname, (struct in_addr *)pton) == 1) { 959 if (pai->ai_family == afd->a_af || 960 pai->ai_family == PF_UNSPEC /*?*/) { 961 GET_AI(cur->ai_next, afd, pton); 962 GET_PORT(cur->ai_next, servname); 963 if ((pai->ai_flags & AI_CANONNAME)) { 964 /* 965 * Set the numeric address itself as 966 * the canonical name, based on a 967 * clarification in rfc2553bis-03. 968 */ 969 GET_CANONNAME(cur->ai_next, canonname); 970 } 971 while (cur && cur->ai_next) 972 cur = cur->ai_next; 973 } else 974 ERR(EAI_FAMILY); /*xxx*/ 975 } 976 break; 977 #endif 978 default: 979 if (inet_pton(afd->a_af, hostname, pton) == 1) { 980 if (pai->ai_family == afd->a_af || 981 pai->ai_family == PF_UNSPEC /*?*/) { 982 GET_AI(cur->ai_next, afd, pton); 983 GET_PORT(cur->ai_next, servname); 984 if ((pai->ai_flags & AI_CANONNAME)) { 985 /* 986 * Set the numeric address itself as 987 * the canonical name, based on a 988 * clarification in rfc2553bis-03. 989 */ 990 GET_CANONNAME(cur->ai_next, canonname); 991 } 992 while (cur->ai_next) 993 cur = cur->ai_next; 994 } else 995 ERR(EAI_FAMILY); /*xxx*/ 996 } 997 break; 998 } 999 1000 *res = sentinel.ai_next; 1001 return 0; 1002 1003 free: 1004 bad: 1005 if (sentinel.ai_next) 1006 freeaddrinfo(sentinel.ai_next); 1007 return error; 1008 } 1009 1010 /* 1011 * numeric hostname with scope 1012 */ 1013 static int 1014 explore_numeric_scope(const struct addrinfo *pai, const char *hostname, 1015 const char *servname, struct addrinfo **res) 1016 { 1017 #if !defined(SCOPE_DELIMITER) || !defined(INET6) 1018 return explore_numeric(pai, hostname, servname, res, hostname); 1019 #else 1020 const struct afd *afd; 1021 struct addrinfo *cur; 1022 int error; 1023 char *cp, *hostname2 = NULL, *scope, *addr; 1024 struct sockaddr_in6 *sin6; 1025 1026 assert(pai != NULL); 1027 /* hostname may be NULL */ 1028 /* servname may be NULL */ 1029 assert(res != NULL); 1030 1031 /* 1032 * if the servname does not match socktype/protocol, ignore it. 1033 */ 1034 if (get_portmatch(pai, servname) != 0) 1035 return 0; 1036 1037 afd = find_afd(pai->ai_family); 1038 if (afd == NULL) 1039 return 0; 1040 1041 if (!afd->a_scoped) 1042 return explore_numeric(pai, hostname, servname, res, hostname); 1043 1044 cp = strchr(hostname, SCOPE_DELIMITER); 1045 if (cp == NULL) 1046 return explore_numeric(pai, hostname, servname, res, hostname); 1047 1048 /* 1049 * Handle special case of <scoped_address><delimiter><scope id> 1050 */ 1051 hostname2 = strdup(hostname); 1052 if (hostname2 == NULL) 1053 return EAI_MEMORY; 1054 /* terminate at the delimiter */ 1055 hostname2[cp - hostname] = '\0'; 1056 addr = hostname2; 1057 scope = cp + 1; 1058 1059 error = explore_numeric(pai, addr, servname, res, hostname); 1060 if (error == 0) { 1061 u_int32_t scopeid; 1062 1063 for (cur = *res; cur; cur = cur->ai_next) { 1064 if (cur->ai_family != AF_INET6) 1065 continue; 1066 sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr; 1067 if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) { 1068 free(hostname2); 1069 return(EAI_NODATA); /* XXX: is return OK? */ 1070 } 1071 sin6->sin6_scope_id = scopeid; 1072 } 1073 } 1074 1075 free(hostname2); 1076 1077 return error; 1078 #endif 1079 } 1080 1081 static int 1082 get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str) 1083 { 1084 1085 assert(pai != NULL); 1086 assert(ai != NULL); 1087 assert(str != NULL); 1088 1089 if ((pai->ai_flags & AI_CANONNAME) != 0) { 1090 ai->ai_canonname = strdup(str); 1091 if (ai->ai_canonname == NULL) 1092 return EAI_MEMORY; 1093 } 1094 return 0; 1095 } 1096 1097 static struct addrinfo * 1098 get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr) 1099 { 1100 char *p; 1101 struct addrinfo *ai; 1102 1103 assert(pai != NULL); 1104 assert(afd != NULL); 1105 assert(addr != NULL); 1106 1107 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) 1108 + (afd->a_socklen)); 1109 if (ai == NULL) 1110 return NULL; 1111 1112 memcpy(ai, pai, sizeof(struct addrinfo)); 1113 ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); 1114 memset(ai->ai_addr, 0, (size_t)afd->a_socklen); 1115 1116 #ifdef HAVE_SA_LEN 1117 ai->ai_addr->sa_len = afd->a_socklen; 1118 #endif 1119 1120 ai->ai_addrlen = afd->a_socklen; 1121 #if defined (__alpha__) || (defined(__i386__) && defined(_LP64)) || defined(__sparc64__) 1122 ai->__ai_pad0 = 0; 1123 #endif 1124 ai->ai_addr->sa_family = ai->ai_family = afd->a_af; 1125 p = (char *)(void *)(ai->ai_addr); 1126 memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen); 1127 return ai; 1128 } 1129 1130 static int 1131 get_portmatch(const struct addrinfo *ai, const char *servname) 1132 { 1133 1134 assert(ai != NULL); 1135 /* servname may be NULL */ 1136 1137 return get_port(ai, servname, 1); 1138 } 1139 1140 static int 1141 get_port(const struct addrinfo *ai, const char *servname, int matchonly) 1142 { 1143 const char *proto; 1144 struct servent *sp; 1145 int port; 1146 int allownumeric; 1147 1148 assert(ai != NULL); 1149 /* servname may be NULL */ 1150 1151 if (servname == NULL) 1152 return 0; 1153 switch (ai->ai_family) { 1154 case AF_INET: 1155 #ifdef AF_INET6 1156 case AF_INET6: 1157 #endif 1158 break; 1159 default: 1160 return 0; 1161 } 1162 1163 switch (ai->ai_socktype) { 1164 case SOCK_RAW: 1165 return EAI_SERVICE; 1166 case SOCK_DGRAM: 1167 case SOCK_STREAM: 1168 allownumeric = 1; 1169 break; 1170 case ANY: 1171 #if 1 /* ANDROID-SPECIFIC CHANGE TO MATCH GLIBC */ 1172 allownumeric = 1; 1173 #else 1174 allownumeric = 0; 1175 #endif 1176 break; 1177 default: 1178 return EAI_SOCKTYPE; 1179 } 1180 1181 port = str2number(servname); 1182 if (port >= 0) { 1183 if (!allownumeric) 1184 return EAI_SERVICE; 1185 if (port < 0 || port > 65535) 1186 return EAI_SERVICE; 1187 port = htons(port); 1188 } else { 1189 if (ai->ai_flags & AI_NUMERICSERV) 1190 return EAI_NONAME; 1191 1192 switch (ai->ai_socktype) { 1193 case SOCK_DGRAM: 1194 proto = "udp"; 1195 break; 1196 case SOCK_STREAM: 1197 proto = "tcp"; 1198 break; 1199 default: 1200 proto = NULL; 1201 break; 1202 } 1203 1204 if ((sp = getservbyname(servname, proto)) == NULL) 1205 return EAI_SERVICE; 1206 port = sp->s_port; 1207 } 1208 1209 if (!matchonly) { 1210 switch (ai->ai_family) { 1211 case AF_INET: 1212 ((struct sockaddr_in *)(void *) 1213 ai->ai_addr)->sin_port = port; 1214 break; 1215 #ifdef INET6 1216 case AF_INET6: 1217 ((struct sockaddr_in6 *)(void *) 1218 ai->ai_addr)->sin6_port = port; 1219 break; 1220 #endif 1221 } 1222 } 1223 1224 return 0; 1225 } 1226 1227 static const struct afd * 1228 find_afd(int af) 1229 { 1230 const struct afd *afd; 1231 1232 if (af == PF_UNSPEC) 1233 return NULL; 1234 for (afd = afdl; afd->a_af; afd++) { 1235 if (afd->a_af == af) 1236 return afd; 1237 } 1238 return NULL; 1239 } 1240 1241 #ifdef INET6 1242 /* convert a string to a scope identifier. XXX: IPv6 specific */ 1243 static int 1244 ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid) 1245 { 1246 u_long lscopeid; 1247 struct in6_addr *a6; 1248 char *ep; 1249 1250 assert(scope != NULL); 1251 assert(sin6 != NULL); 1252 assert(scopeid != NULL); 1253 1254 a6 = &sin6->sin6_addr; 1255 1256 /* empty scopeid portion is invalid */ 1257 if (*scope == '\0') 1258 return -1; 1259 1260 if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) { 1261 /* 1262 * We currently assume a one-to-one mapping between links 1263 * and interfaces, so we simply use interface indices for 1264 * like-local scopes. 1265 */ 1266 *scopeid = if_nametoindex(scope); 1267 if (*scopeid == 0) 1268 goto trynumeric; 1269 return 0; 1270 } 1271 1272 /* still unclear about literal, allow numeric only - placeholder */ 1273 if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) 1274 goto trynumeric; 1275 if (IN6_IS_ADDR_MC_ORGLOCAL(a6)) 1276 goto trynumeric; 1277 else 1278 goto trynumeric; /* global */ 1279 1280 /* try to convert to a numeric id as a last resort */ 1281 trynumeric: 1282 errno = 0; 1283 lscopeid = strtoul(scope, &ep, 10); 1284 *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL); 1285 if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid) 1286 return 0; 1287 else 1288 return -1; 1289 } 1290 #endif 1291 1292 /* code duplicate with gethnamaddr.c */ 1293 1294 static const char AskedForGot[] = 1295 "gethostby*.getanswer: asked for \"%s\", got \"%s\""; 1296 1297 static struct addrinfo * 1298 getanswer(const querybuf *answer, int anslen, const char *qname, int qtype, 1299 const struct addrinfo *pai) 1300 { 1301 struct addrinfo sentinel, *cur; 1302 struct addrinfo ai; 1303 const struct afd *afd; 1304 char *canonname; 1305 const HEADER *hp; 1306 const u_char *cp; 1307 int n; 1308 const u_char *eom; 1309 char *bp, *ep; 1310 int type, class, ancount, qdcount; 1311 int haveanswer, had_error; 1312 char tbuf[MAXDNAME]; 1313 int (*name_ok) (const char *); 1314 char hostbuf[8*1024]; 1315 1316 assert(answer != NULL); 1317 assert(qname != NULL); 1318 assert(pai != NULL); 1319 1320 memset(&sentinel, 0, sizeof(sentinel)); 1321 cur = &sentinel; 1322 1323 canonname = NULL; 1324 eom = answer->buf + anslen; 1325 switch (qtype) { 1326 case T_A: 1327 case T_AAAA: 1328 case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/ 1329 name_ok = res_hnok; 1330 break; 1331 default: 1332 return NULL; /* XXX should be abort(); */ 1333 } 1334 /* 1335 * find first satisfactory answer 1336 */ 1337 hp = &answer->hdr; 1338 ancount = ntohs(hp->ancount); 1339 qdcount = ntohs(hp->qdcount); 1340 bp = hostbuf; 1341 ep = hostbuf + sizeof hostbuf; 1342 cp = answer->buf + HFIXEDSZ; 1343 if (qdcount != 1) { 1344 h_errno = NO_RECOVERY; 1345 return (NULL); 1346 } 1347 n = dn_expand(answer->buf, eom, cp, bp, ep - bp); 1348 if ((n < 0) || !(*name_ok)(bp)) { 1349 h_errno = NO_RECOVERY; 1350 return (NULL); 1351 } 1352 cp += n + QFIXEDSZ; 1353 if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) { 1354 /* res_send() has already verified that the query name is the 1355 * same as the one we sent; this just gets the expanded name 1356 * (i.e., with the succeeding search-domain tacked on). 1357 */ 1358 n = strlen(bp) + 1; /* for the \0 */ 1359 if (n >= MAXHOSTNAMELEN) { 1360 h_errno = NO_RECOVERY; 1361 return (NULL); 1362 } 1363 canonname = bp; 1364 bp += n; 1365 /* The qname can be abbreviated, but h_name is now absolute. */ 1366 qname = canonname; 1367 } 1368 haveanswer = 0; 1369 had_error = 0; 1370 while (ancount-- > 0 && cp < eom && !had_error) { 1371 n = dn_expand(answer->buf, eom, cp, bp, ep - bp); 1372 if ((n < 0) || !(*name_ok)(bp)) { 1373 had_error++; 1374 continue; 1375 } 1376 cp += n; /* name */ 1377 type = _getshort(cp); 1378 cp += INT16SZ; /* type */ 1379 class = _getshort(cp); 1380 cp += INT16SZ + INT32SZ; /* class, TTL */ 1381 n = _getshort(cp); 1382 cp += INT16SZ; /* len */ 1383 if (class != C_IN) { 1384 /* XXX - debug? syslog? */ 1385 cp += n; 1386 continue; /* XXX - had_error++ ? */ 1387 } 1388 if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && 1389 type == T_CNAME) { 1390 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); 1391 if ((n < 0) || !(*name_ok)(tbuf)) { 1392 had_error++; 1393 continue; 1394 } 1395 cp += n; 1396 /* Get canonical name. */ 1397 n = strlen(tbuf) + 1; /* for the \0 */ 1398 if (n > ep - bp || n >= MAXHOSTNAMELEN) { 1399 had_error++; 1400 continue; 1401 } 1402 strlcpy(bp, tbuf, (size_t)(ep - bp)); 1403 canonname = bp; 1404 bp += n; 1405 continue; 1406 } 1407 if (qtype == T_ANY) { 1408 if (!(type == T_A || type == T_AAAA)) { 1409 cp += n; 1410 continue; 1411 } 1412 } else if (type != qtype) { 1413 if (type != T_KEY && type != T_SIG) 1414 syslog(LOG_NOTICE|LOG_AUTH, 1415 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", 1416 qname, p_class(C_IN), p_type(qtype), 1417 p_type(type)); 1418 cp += n; 1419 continue; /* XXX - had_error++ ? */ 1420 } 1421 switch (type) { 1422 case T_A: 1423 case T_AAAA: 1424 if (strcasecmp(canonname, bp) != 0) { 1425 syslog(LOG_NOTICE|LOG_AUTH, 1426 AskedForGot, canonname, bp); 1427 cp += n; 1428 continue; /* XXX - had_error++ ? */ 1429 } 1430 if (type == T_A && n != INADDRSZ) { 1431 cp += n; 1432 continue; 1433 } 1434 if (type == T_AAAA && n != IN6ADDRSZ) { 1435 cp += n; 1436 continue; 1437 } 1438 if (type == T_AAAA) { 1439 struct in6_addr in6; 1440 memcpy(&in6, cp, IN6ADDRSZ); 1441 if (IN6_IS_ADDR_V4MAPPED(&in6)) { 1442 cp += n; 1443 continue; 1444 } 1445 } 1446 if (!haveanswer) { 1447 int nn; 1448 1449 canonname = bp; 1450 nn = strlen(bp) + 1; /* for the \0 */ 1451 bp += nn; 1452 } 1453 1454 /* don't overwrite pai */ 1455 ai = *pai; 1456 ai.ai_family = (type == T_A) ? AF_INET : AF_INET6; 1457 afd = find_afd(ai.ai_family); 1458 if (afd == NULL) { 1459 cp += n; 1460 continue; 1461 } 1462 cur->ai_next = get_ai(&ai, afd, (const char *)cp); 1463 if (cur->ai_next == NULL) 1464 had_error++; 1465 while (cur && cur->ai_next) 1466 cur = cur->ai_next; 1467 cp += n; 1468 break; 1469 default: 1470 abort(); 1471 } 1472 if (!had_error) 1473 haveanswer++; 1474 } 1475 if (haveanswer) { 1476 if (!canonname) 1477 (void)get_canonname(pai, sentinel.ai_next, qname); 1478 else 1479 (void)get_canonname(pai, sentinel.ai_next, canonname); 1480 h_errno = NETDB_SUCCESS; 1481 return sentinel.ai_next; 1482 } 1483 1484 h_errno = NO_RECOVERY; 1485 return NULL; 1486 } 1487 1488 struct addrinfo_sort_elem { 1489 struct addrinfo *ai; 1490 int has_src_addr; 1491 sockaddr_union src_addr; 1492 int original_order; 1493 }; 1494 1495 /*ARGSUSED*/ 1496 static int 1497 _get_scope(const struct sockaddr *addr) 1498 { 1499 if (addr->sa_family == AF_INET6) { 1500 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; 1501 if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)) { 1502 return IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr); 1503 } else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) || 1504 IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) { 1505 /* 1506 * RFC 4291 section 2.5.3 says loopback is to be treated as having 1507 * link-local scope. 1508 */ 1509 return IPV6_ADDR_SCOPE_LINKLOCAL; 1510 } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) { 1511 return IPV6_ADDR_SCOPE_SITELOCAL; 1512 } else { 1513 return IPV6_ADDR_SCOPE_GLOBAL; 1514 } 1515 } else if (addr->sa_family == AF_INET) { 1516 const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; 1517 unsigned long int na = ntohl(addr4->sin_addr.s_addr); 1518 1519 if (IN_LOOPBACK(na) || /* 127.0.0.0/8 */ 1520 (na & 0xffff0000) == 0xa9fe0000) { /* 169.254.0.0/16 */ 1521 return IPV6_ADDR_SCOPE_LINKLOCAL; 1522 } else { 1523 /* 1524 * According to draft-ietf-6man-rfc3484-revise-01 section 2.3, 1525 * it is best not to treat the private IPv4 ranges 1526 * (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) as being 1527 * in a special scope, so we don't. 1528 */ 1529 return IPV6_ADDR_SCOPE_GLOBAL; 1530 } 1531 } else { 1532 /* 1533 * This should never happen. 1534 * Return a scope with low priority as a last resort. 1535 */ 1536 return IPV6_ADDR_SCOPE_NODELOCAL; 1537 } 1538 } 1539 1540 /* These macros are modelled after the ones in <netinet/in6.h>. */ 1541 1542 /* RFC 4380, section 2.6 */ 1543 #define IN6_IS_ADDR_TEREDO(a) \ 1544 ((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000))) 1545 1546 /* RFC 3056, section 2. */ 1547 #define IN6_IS_ADDR_6TO4(a) \ 1548 (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02)) 1549 1550 /* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */ 1551 #define IN6_IS_ADDR_6BONE(a) \ 1552 (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe)) 1553 1554 /* 1555 * Get the label for a given IPv4/IPv6 address. 1556 * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01. 1557 */ 1558 1559 /*ARGSUSED*/ 1560 static int 1561 _get_label(const struct sockaddr *addr) 1562 { 1563 if (addr->sa_family == AF_INET) { 1564 return 3; 1565 } else if (addr->sa_family == AF_INET6) { 1566 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; 1567 if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) { 1568 return 0; 1569 } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) { 1570 return 1; 1571 } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { 1572 return 3; 1573 } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { 1574 return 4; 1575 } else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) { 1576 return 5; 1577 } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) { 1578 return 10; 1579 } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) { 1580 return 11; 1581 } else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) { 1582 return 12; 1583 } else { 1584 return 2; 1585 } 1586 } else { 1587 /* 1588 * This should never happen. 1589 * Return a semi-random label as a last resort. 1590 */ 1591 return 1; 1592 } 1593 } 1594 1595 /* 1596 * Get the precedence for a given IPv4/IPv6 address. 1597 * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01. 1598 */ 1599 1600 /*ARGSUSED*/ 1601 static int 1602 _get_precedence(const struct sockaddr *addr) 1603 { 1604 if (addr->sa_family == AF_INET) { 1605 return 30; 1606 } else if (addr->sa_family == AF_INET6) { 1607 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; 1608 if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) { 1609 return 60; 1610 } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) { 1611 return 50; 1612 } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { 1613 return 30; 1614 } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { 1615 return 20; 1616 } else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) { 1617 return 10; 1618 } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) || 1619 IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) || 1620 IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) { 1621 return 1; 1622 } else { 1623 return 40; 1624 } 1625 } else { 1626 return 1; 1627 } 1628 } 1629 1630 /* 1631 * Find number of matching initial bits between the two addresses a1 and a2. 1632 */ 1633 1634 /*ARGSUSED*/ 1635 static int 1636 _common_prefix_len(const struct in6_addr *a1, const struct in6_addr *a2) 1637 { 1638 const char *p1 = (const char *)a1; 1639 const char *p2 = (const char *)a2; 1640 unsigned i; 1641 1642 for (i = 0; i < sizeof(*a1); ++i) { 1643 int x, j; 1644 1645 if (p1[i] == p2[i]) { 1646 continue; 1647 } 1648 x = p1[i] ^ p2[i]; 1649 for (j = 0; j < CHAR_BIT; ++j) { 1650 if (x & (1 << (CHAR_BIT - 1))) { 1651 return i * CHAR_BIT + j; 1652 } 1653 x <<= 1; 1654 } 1655 } 1656 return sizeof(*a1) * CHAR_BIT; 1657 } 1658 1659 /* 1660 * Compare two source/destination address pairs. 1661 * RFC 3484, section 6. 1662 */ 1663 1664 /*ARGSUSED*/ 1665 static int 1666 _rfc3484_compare(const void *ptr1, const void* ptr2) 1667 { 1668 const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1; 1669 const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2; 1670 int scope_src1, scope_dst1, scope_match1; 1671 int scope_src2, scope_dst2, scope_match2; 1672 int label_src1, label_dst1, label_match1; 1673 int label_src2, label_dst2, label_match2; 1674 int precedence1, precedence2; 1675 int prefixlen1, prefixlen2; 1676 1677 /* Rule 1: Avoid unusable destinations. */ 1678 if (a1->has_src_addr != a2->has_src_addr) { 1679 return a2->has_src_addr - a1->has_src_addr; 1680 } 1681 1682 /* Rule 2: Prefer matching scope. */ 1683 scope_src1 = _get_scope(&a1->src_addr.generic); 1684 scope_dst1 = _get_scope(a1->ai->ai_addr); 1685 scope_match1 = (scope_src1 == scope_dst1); 1686 1687 scope_src2 = _get_scope(&a2->src_addr.generic); 1688 scope_dst2 = _get_scope(a2->ai->ai_addr); 1689 scope_match2 = (scope_src2 == scope_dst2); 1690 1691 if (scope_match1 != scope_match2) { 1692 return scope_match2 - scope_match1; 1693 } 1694 1695 /* 1696 * Rule 3: Avoid deprecated addresses. 1697 * TODO(sesse): We don't currently have a good way of finding this. 1698 */ 1699 1700 /* 1701 * Rule 4: Prefer home addresses. 1702 * TODO(sesse): We don't currently have a good way of finding this. 1703 */ 1704 1705 /* Rule 5: Prefer matching label. */ 1706 label_src1 = _get_label(&a1->src_addr.generic); 1707 label_dst1 = _get_label(a1->ai->ai_addr); 1708 label_match1 = (label_src1 == label_dst1); 1709 1710 label_src2 = _get_label(&a2->src_addr.generic); 1711 label_dst2 = _get_label(a2->ai->ai_addr); 1712 label_match2 = (label_src2 == label_dst2); 1713 1714 if (label_match1 != label_match2) { 1715 return label_match2 - label_match1; 1716 } 1717 1718 /* Rule 6: Prefer higher precedence. */ 1719 precedence1 = _get_precedence(a1->ai->ai_addr); 1720 precedence2 = _get_precedence(a2->ai->ai_addr); 1721 if (precedence1 != precedence2) { 1722 return precedence2 - precedence1; 1723 } 1724 1725 /* 1726 * Rule 7: Prefer native transport. 1727 * TODO(sesse): We don't currently have a good way of finding this. 1728 */ 1729 1730 /* Rule 8: Prefer smaller scope. */ 1731 if (scope_dst1 != scope_dst2) { 1732 return scope_dst1 - scope_dst2; 1733 } 1734 1735 /* 1736 * Rule 9: Use longest matching prefix. 1737 * We implement this for IPv6 only, as the rules in RFC 3484 don't seem 1738 * to work very well directly applied to IPv4. (glibc uses information from 1739 * the routing table for a custom IPv4 implementation here.) 1740 */ 1741 if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 && 1742 a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6) { 1743 const struct sockaddr_in6 *a1_src = &a1->src_addr.in6; 1744 const struct sockaddr_in6 *a1_dst = (const struct sockaddr_in6 *)a1->ai->ai_addr; 1745 const struct sockaddr_in6 *a2_src = &a2->src_addr.in6; 1746 const struct sockaddr_in6 *a2_dst = (const struct sockaddr_in6 *)a2->ai->ai_addr; 1747 prefixlen1 = _common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr); 1748 prefixlen2 = _common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr); 1749 if (prefixlen1 != prefixlen2) { 1750 return prefixlen2 - prefixlen1; 1751 } 1752 } 1753 1754 /* 1755 * Rule 10: Leave the order unchanged. 1756 * We need this since qsort() is not necessarily stable. 1757 */ 1758 return a1->original_order - a2->original_order; 1759 } 1760 1761 /* 1762 * Find the source address that will be used if trying to connect to the given 1763 * address. src_addr must be large enough to hold a struct sockaddr_in6. 1764 * 1765 * Returns 1 if a source address was found, 0 if the address is unreachable, 1766 * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are 1767 * undefined. 1768 */ 1769 1770 /*ARGSUSED*/ 1771 static int 1772 _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr) 1773 { 1774 int sock; 1775 int ret; 1776 socklen_t len; 1777 1778 switch (addr->sa_family) { 1779 case AF_INET: 1780 len = sizeof(struct sockaddr_in); 1781 break; 1782 case AF_INET6: 1783 len = sizeof(struct sockaddr_in6); 1784 break; 1785 default: 1786 /* No known usable source address for non-INET families. */ 1787 return 0; 1788 } 1789 1790 sock = socket(addr->sa_family, SOCK_DGRAM, IPPROTO_UDP); 1791 if (sock == -1) { 1792 if (errno == EAFNOSUPPORT) { 1793 return 0; 1794 } else { 1795 return -1; 1796 } 1797 } 1798 1799 do { 1800 ret = connect(sock, addr, len); 1801 } while (ret == -1 && errno == EINTR); 1802 1803 if (ret == -1) { 1804 close(sock); 1805 return 0; 1806 } 1807 1808 if (getsockname(sock, src_addr, &len) == -1) { 1809 close(sock); 1810 return -1; 1811 } 1812 close(sock); 1813 return 1; 1814 } 1815 1816 /* 1817 * Sort the linked list starting at sentinel->ai_next in RFC3484 order. 1818 * Will leave the list unchanged if an error occurs. 1819 */ 1820 1821 /*ARGSUSED*/ 1822 static void 1823 _rfc3484_sort(struct addrinfo *list_sentinel) 1824 { 1825 struct addrinfo *cur; 1826 int nelem = 0, i; 1827 struct addrinfo_sort_elem *elems; 1828 1829 cur = list_sentinel->ai_next; 1830 while (cur) { 1831 ++nelem; 1832 cur = cur->ai_next; 1833 } 1834 1835 elems = (struct addrinfo_sort_elem *)malloc(nelem * sizeof(struct addrinfo_sort_elem)); 1836 if (elems == NULL) { 1837 goto error; 1838 } 1839 1840 /* 1841 * Convert the linked list to an array that also contains the candidate 1842 * source address for each destination address. 1843 */ 1844 for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next) { 1845 int has_src_addr; 1846 assert(cur != NULL); 1847 elems[i].ai = cur; 1848 elems[i].original_order = i; 1849 1850 has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic); 1851 if (has_src_addr == -1) { 1852 goto error; 1853 } 1854 elems[i].has_src_addr = has_src_addr; 1855 } 1856 1857 /* Sort the addresses, and rearrange the linked list so it matches the sorted order. */ 1858 qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), _rfc3484_compare); 1859 1860 list_sentinel->ai_next = elems[0].ai; 1861 for (i = 0; i < nelem - 1; ++i) { 1862 elems[i].ai->ai_next = elems[i + 1].ai; 1863 } 1864 elems[nelem - 1].ai->ai_next = NULL; 1865 1866 error: 1867 free(elems); 1868 } 1869 1870 /*ARGSUSED*/ 1871 static int 1872 _dns_getaddrinfo(void *rv, void *cb_data, va_list ap) 1873 { 1874 struct addrinfo *ai; 1875 querybuf *buf, *buf2; 1876 const char *name; 1877 const struct addrinfo *pai; 1878 struct addrinfo sentinel, *cur; 1879 struct res_target q, q2; 1880 res_state res; 1881 1882 name = va_arg(ap, char *); 1883 pai = va_arg(ap, const struct addrinfo *); 1884 //fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name); 1885 1886 memset(&q, 0, sizeof(q)); 1887 memset(&q2, 0, sizeof(q2)); 1888 memset(&sentinel, 0, sizeof(sentinel)); 1889 cur = &sentinel; 1890 1891 buf = malloc(sizeof(*buf)); 1892 if (buf == NULL) { 1893 h_errno = NETDB_INTERNAL; 1894 return NS_NOTFOUND; 1895 } 1896 buf2 = malloc(sizeof(*buf2)); 1897 if (buf2 == NULL) { 1898 free(buf); 1899 h_errno = NETDB_INTERNAL; 1900 return NS_NOTFOUND; 1901 } 1902 1903 switch (pai->ai_family) { 1904 case AF_UNSPEC: 1905 /* prefer IPv6 */ 1906 q.name = name; 1907 q.qclass = C_IN; 1908 q.answer = buf->buf; 1909 q.anslen = sizeof(buf->buf); 1910 int query_ipv6 = 1, query_ipv4 = 1; 1911 if (pai->ai_flags & AI_ADDRCONFIG) { 1912 query_ipv6 = _have_ipv6(); 1913 query_ipv4 = _have_ipv4(); 1914 if (query_ipv6 == 0 && query_ipv4 == 0) { 1915 // Both our IPv4 and IPv6 connectivity probes failed, which indicates 1916 // that we have neither an IPv4 or an IPv6 default route (and thus no 1917 // global IPv4 or IPv6 connectivity). We might be in a walled garden. 1918 // Throw up our arms and ask for both A and AAAA. 1919 query_ipv6 = query_ipv4 = 1; 1920 } 1921 } 1922 if (query_ipv6) { 1923 q.qtype = T_AAAA; 1924 if (query_ipv4) { 1925 q.next = &q2; 1926 q2.name = name; 1927 q2.qclass = C_IN; 1928 q2.qtype = T_A; 1929 q2.answer = buf2->buf; 1930 q2.anslen = sizeof(buf2->buf); 1931 } 1932 } else if (query_ipv4) { 1933 q.qtype = T_A; 1934 } else { 1935 free(buf); 1936 free(buf2); 1937 return NS_NOTFOUND; 1938 } 1939 break; 1940 case AF_INET: 1941 q.name = name; 1942 q.qclass = C_IN; 1943 q.qtype = T_A; 1944 q.answer = buf->buf; 1945 q.anslen = sizeof(buf->buf); 1946 break; 1947 case AF_INET6: 1948 q.name = name; 1949 q.qclass = C_IN; 1950 q.qtype = T_AAAA; 1951 q.answer = buf->buf; 1952 q.anslen = sizeof(buf->buf); 1953 break; 1954 default: 1955 free(buf); 1956 free(buf2); 1957 return NS_UNAVAIL; 1958 } 1959 1960 res = __res_get_state(); 1961 if (res == NULL) { 1962 free(buf); 1963 free(buf2); 1964 return NS_NOTFOUND; 1965 } 1966 1967 if (res_searchN(name, &q, res) < 0) { 1968 __res_put_state(res); 1969 free(buf); 1970 free(buf2); 1971 return NS_NOTFOUND; 1972 } 1973 ai = getanswer(buf, q.n, q.name, q.qtype, pai); 1974 if (ai) { 1975 cur->ai_next = ai; 1976 while (cur && cur->ai_next) 1977 cur = cur->ai_next; 1978 } 1979 if (q.next) { 1980 ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai); 1981 if (ai) 1982 cur->ai_next = ai; 1983 } 1984 free(buf); 1985 free(buf2); 1986 if (sentinel.ai_next == NULL) { 1987 __res_put_state(res); 1988 switch (h_errno) { 1989 case HOST_NOT_FOUND: 1990 return NS_NOTFOUND; 1991 case TRY_AGAIN: 1992 return NS_TRYAGAIN; 1993 default: 1994 return NS_UNAVAIL; 1995 } 1996 } 1997 1998 _rfc3484_sort(&sentinel); 1999 2000 __res_put_state(res); 2001 2002 *((struct addrinfo **)rv) = sentinel.ai_next; 2003 return NS_SUCCESS; 2004 } 2005 2006 static void 2007 _sethtent(FILE **hostf) 2008 { 2009 2010 if (!*hostf) 2011 *hostf = fopen(_PATH_HOSTS, "r" ); 2012 else 2013 rewind(*hostf); 2014 } 2015 2016 static void 2017 _endhtent(FILE **hostf) 2018 { 2019 2020 if (*hostf) { 2021 (void) fclose(*hostf); 2022 *hostf = NULL; 2023 } 2024 } 2025 2026 static struct addrinfo * 2027 _gethtent(FILE **hostf, const char *name, const struct addrinfo *pai) 2028 { 2029 char *p; 2030 char *cp, *tname, *cname; 2031 struct addrinfo hints, *res0, *res; 2032 int error; 2033 const char *addr; 2034 char hostbuf[8*1024]; 2035 2036 // fprintf(stderr, "_gethtent() name = '%s'\n", name); 2037 assert(name != NULL); 2038 assert(pai != NULL); 2039 2040 if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r" ))) 2041 return (NULL); 2042 again: 2043 if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf))) 2044 return (NULL); 2045 if (*p == '#') 2046 goto again; 2047 if (!(cp = strpbrk(p, "#\n"))) 2048 goto again; 2049 *cp = '\0'; 2050 if (!(cp = strpbrk(p, " \t"))) 2051 goto again; 2052 *cp++ = '\0'; 2053 addr = p; 2054 /* if this is not something we're looking for, skip it. */ 2055 cname = NULL; 2056 while (cp && *cp) { 2057 if (*cp == ' ' || *cp == '\t') { 2058 cp++; 2059 continue; 2060 } 2061 if (!cname) 2062 cname = cp; 2063 tname = cp; 2064 if ((cp = strpbrk(cp, " \t")) != NULL) 2065 *cp++ = '\0'; 2066 // fprintf(stderr, "\ttname = '%s'", tname); 2067 if (strcasecmp(name, tname) == 0) 2068 goto found; 2069 } 2070 goto again; 2071 2072 found: 2073 hints = *pai; 2074 hints.ai_flags = AI_NUMERICHOST; 2075 error = getaddrinfo(addr, NULL, &hints, &res0); 2076 if (error) 2077 goto again; 2078 for (res = res0; res; res = res->ai_next) { 2079 /* cover it up */ 2080 res->ai_flags = pai->ai_flags; 2081 2082 if (pai->ai_flags & AI_CANONNAME) { 2083 if (get_canonname(pai, res, cname) != 0) { 2084 freeaddrinfo(res0); 2085 goto again; 2086 } 2087 } 2088 } 2089 return res0; 2090 } 2091 2092 /*ARGSUSED*/ 2093 static int 2094 _files_getaddrinfo(void *rv, void *cb_data, va_list ap) 2095 { 2096 const char *name; 2097 const struct addrinfo *pai; 2098 struct addrinfo sentinel, *cur; 2099 struct addrinfo *p; 2100 FILE *hostf = NULL; 2101 2102 name = va_arg(ap, char *); 2103 pai = va_arg(ap, struct addrinfo *); 2104 2105 // fprintf(stderr, "_files_getaddrinfo() name = '%s'\n", name); 2106 memset(&sentinel, 0, sizeof(sentinel)); 2107 cur = &sentinel; 2108 2109 _sethtent(&hostf); 2110 while ((p = _gethtent(&hostf, name, pai)) != NULL) { 2111 cur->ai_next = p; 2112 while (cur && cur->ai_next) 2113 cur = cur->ai_next; 2114 } 2115 _endhtent(&hostf); 2116 2117 *((struct addrinfo **)rv) = sentinel.ai_next; 2118 if (sentinel.ai_next == NULL) 2119 return NS_NOTFOUND; 2120 return NS_SUCCESS; 2121 } 2122 2123 /* resolver logic */ 2124 2125 /* 2126 * Formulate a normal query, send, and await answer. 2127 * Returned answer is placed in supplied buffer "answer". 2128 * Perform preliminary check of answer, returning success only 2129 * if no error is indicated and the answer count is nonzero. 2130 * Return the size of the response on success, -1 on error. 2131 * Error number is left in h_errno. 2132 * 2133 * Caller must parse answer and determine whether it answers the question. 2134 */ 2135 static int 2136 res_queryN(const char *name, /* domain name */ struct res_target *target, 2137 res_state res) 2138 { 2139 u_char buf[MAXPACKET]; 2140 HEADER *hp; 2141 int n; 2142 struct res_target *t; 2143 int rcode; 2144 int ancount; 2145 2146 assert(name != NULL); 2147 /* XXX: target may be NULL??? */ 2148 2149 rcode = NOERROR; 2150 ancount = 0; 2151 2152 for (t = target; t; t = t->next) { 2153 int class, type; 2154 u_char *answer; 2155 int anslen; 2156 2157 hp = (HEADER *)(void *)t->answer; 2158 hp->rcode = NOERROR; /* default */ 2159 2160 /* make it easier... */ 2161 class = t->qclass; 2162 type = t->qtype; 2163 answer = t->answer; 2164 anslen = t->anslen; 2165 #ifdef DEBUG 2166 if (res->options & RES_DEBUG) 2167 printf(";; res_nquery(%s, %d, %d)\n", name, class, type); 2168 #endif 2169 2170 n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL, 2171 buf, sizeof(buf)); 2172 #ifdef RES_USE_EDNS0 2173 if (n > 0 && (res->options & RES_USE_EDNS0) != 0) 2174 n = res_nopt(res, n, buf, sizeof(buf), anslen); 2175 #endif 2176 if (n <= 0) { 2177 #ifdef DEBUG 2178 if (res->options & RES_DEBUG) 2179 printf(";; res_nquery: mkquery failed\n"); 2180 #endif 2181 h_errno = NO_RECOVERY; 2182 return n; 2183 } 2184 n = res_nsend(res, buf, n, answer, anslen); 2185 #if 0 2186 if (n < 0) { 2187 #ifdef DEBUG 2188 if (res->options & RES_DEBUG) 2189 printf(";; res_query: send error\n"); 2190 #endif 2191 h_errno = TRY_AGAIN; 2192 return n; 2193 } 2194 #endif 2195 2196 if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { 2197 rcode = hp->rcode; /* record most recent error */ 2198 #ifdef DEBUG 2199 if (res->options & RES_DEBUG) 2200 printf(";; rcode = %u, ancount=%u\n", hp->rcode, 2201 ntohs(hp->ancount)); 2202 #endif 2203 continue; 2204 } 2205 2206 ancount += ntohs(hp->ancount); 2207 2208 t->n = n; 2209 } 2210 2211 if (ancount == 0) { 2212 switch (rcode) { 2213 case NXDOMAIN: 2214 h_errno = HOST_NOT_FOUND; 2215 break; 2216 case SERVFAIL: 2217 h_errno = TRY_AGAIN; 2218 break; 2219 case NOERROR: 2220 h_errno = NO_DATA; 2221 break; 2222 case FORMERR: 2223 case NOTIMP: 2224 case REFUSED: 2225 default: 2226 h_errno = NO_RECOVERY; 2227 break; 2228 } 2229 return -1; 2230 } 2231 return ancount; 2232 } 2233 2234 /* 2235 * Formulate a normal query, send, and retrieve answer in supplied buffer. 2236 * Return the size of the response on success, -1 on error. 2237 * If enabled, implement search rules until answer or unrecoverable failure 2238 * is detected. Error code, if any, is left in h_errno. 2239 */ 2240 static int 2241 res_searchN(const char *name, struct res_target *target, res_state res) 2242 { 2243 const char *cp, * const *domain; 2244 HEADER *hp; 2245 u_int dots; 2246 int trailing_dot, ret, saved_herrno; 2247 int got_nodata = 0, got_servfail = 0, tried_as_is = 0; 2248 2249 assert(name != NULL); 2250 assert(target != NULL); 2251 2252 hp = (HEADER *)(void *)target->answer; /*XXX*/ 2253 2254 errno = 0; 2255 h_errno = HOST_NOT_FOUND; /* default, if we never query */ 2256 dots = 0; 2257 for (cp = name; *cp; cp++) 2258 dots += (*cp == '.'); 2259 trailing_dot = 0; 2260 if (cp > name && *--cp == '.') 2261 trailing_dot++; 2262 2263 2264 //fprintf(stderr, "res_searchN() name = '%s'\n", name); 2265 2266 /* 2267 * if there aren't any dots, it could be a user-level alias 2268 */ 2269 if (!dots && (cp = __hostalias(name)) != NULL) { 2270 ret = res_queryN(cp, target, res); 2271 return ret; 2272 } 2273 2274 /* 2275 * If there are dots in the name already, let's just give it a try 2276 * 'as is'. The threshold can be set with the "ndots" option. 2277 */ 2278 saved_herrno = -1; 2279 if (dots >= res->ndots) { 2280 ret = res_querydomainN(name, NULL, target, res); 2281 if (ret > 0) 2282 return (ret); 2283 saved_herrno = h_errno; 2284 tried_as_is++; 2285 } 2286 2287 /* 2288 * We do at least one level of search if 2289 * - there is no dot and RES_DEFNAME is set, or 2290 * - there is at least one dot, there is no trailing dot, 2291 * and RES_DNSRCH is set. 2292 */ 2293 if ((!dots && (res->options & RES_DEFNAMES)) || 2294 (dots && !trailing_dot && (res->options & RES_DNSRCH))) { 2295 int done = 0; 2296 2297 for (domain = (const char * const *)res->dnsrch; 2298 *domain && !done; 2299 domain++) { 2300 2301 ret = res_querydomainN(name, *domain, target, res); 2302 if (ret > 0) 2303 return ret; 2304 2305 /* 2306 * If no server present, give up. 2307 * If name isn't found in this domain, 2308 * keep trying higher domains in the search list 2309 * (if that's enabled). 2310 * On a NO_DATA error, keep trying, otherwise 2311 * a wildcard entry of another type could keep us 2312 * from finding this entry higher in the domain. 2313 * If we get some other error (negative answer or 2314 * server failure), then stop searching up, 2315 * but try the input name below in case it's 2316 * fully-qualified. 2317 */ 2318 if (errno == ECONNREFUSED) { 2319 h_errno = TRY_AGAIN; 2320 return -1; 2321 } 2322 2323 switch (h_errno) { 2324 case NO_DATA: 2325 got_nodata++; 2326 /* FALLTHROUGH */ 2327 case HOST_NOT_FOUND: 2328 /* keep trying */ 2329 break; 2330 case TRY_AGAIN: 2331 if (hp->rcode == SERVFAIL) { 2332 /* try next search element, if any */ 2333 got_servfail++; 2334 break; 2335 } 2336 /* FALLTHROUGH */ 2337 default: 2338 /* anything else implies that we're done */ 2339 done++; 2340 } 2341 /* 2342 * if we got here for some reason other than DNSRCH, 2343 * we only wanted one iteration of the loop, so stop. 2344 */ 2345 if (!(res->options & RES_DNSRCH)) 2346 done++; 2347 } 2348 } 2349 2350 /* 2351 * if we have not already tried the name "as is", do that now. 2352 * note that we do this regardless of how many dots were in the 2353 * name or whether it ends with a dot. 2354 */ 2355 if (!tried_as_is) { 2356 ret = res_querydomainN(name, NULL, target, res); 2357 if (ret > 0) 2358 return ret; 2359 } 2360 2361 /* 2362 * if we got here, we didn't satisfy the search. 2363 * if we did an initial full query, return that query's h_errno 2364 * (note that we wouldn't be here if that query had succeeded). 2365 * else if we ever got a nodata, send that back as the reason. 2366 * else send back meaningless h_errno, that being the one from 2367 * the last DNSRCH we did. 2368 */ 2369 if (saved_herrno != -1) 2370 h_errno = saved_herrno; 2371 else if (got_nodata) 2372 h_errno = NO_DATA; 2373 else if (got_servfail) 2374 h_errno = TRY_AGAIN; 2375 return -1; 2376 } 2377 2378 /* 2379 * Perform a call on res_query on the concatenation of name and domain, 2380 * removing a trailing dot from name if domain is NULL. 2381 */ 2382 static int 2383 res_querydomainN(const char *name, const char *domain, 2384 struct res_target *target, res_state res) 2385 { 2386 char nbuf[MAXDNAME]; 2387 const char *longname = nbuf; 2388 size_t n, d; 2389 2390 assert(name != NULL); 2391 /* XXX: target may be NULL??? */ 2392 2393 #ifdef DEBUG 2394 if (res->options & RES_DEBUG) 2395 printf(";; res_querydomain(%s, %s)\n", 2396 name, domain?domain:"<Nil>"); 2397 #endif 2398 if (domain == NULL) { 2399 /* 2400 * Check for trailing '.'; 2401 * copy without '.' if present. 2402 */ 2403 n = strlen(name); 2404 if (n + 1 > sizeof(nbuf)) { 2405 h_errno = NO_RECOVERY; 2406 return -1; 2407 } 2408 if (n > 0 && name[--n] == '.') { 2409 strncpy(nbuf, name, n); 2410 nbuf[n] = '\0'; 2411 } else 2412 longname = name; 2413 } else { 2414 n = strlen(name); 2415 d = strlen(domain); 2416 if (n + 1 + d + 1 > sizeof(nbuf)) { 2417 h_errno = NO_RECOVERY; 2418 return -1; 2419 } 2420 snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain); 2421 } 2422 return res_queryN(longname, target, res); 2423 } 2424