1 /* $FreeBSD: src/lib/libc/net/getaddrinfo.c,v 1.9.2.14 2002/11/08 17:49:31 ume Exp $ */ 2 /* $DragonFly: src/lib/libc/net/getaddrinfo.c,v 1.5 2005/02/02 15:10:55 hrs Exp $ */ 3 /* $KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $ */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 /* 35 * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. 36 * 37 * Issues to be discussed: 38 * - Thread safe-ness must be checked. 39 * - Return values. There are nonstandard return values defined and used 40 * in the source code. This is because RFC2553 is silent about which error 41 * code must be returned for which situation. 42 * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is 43 * invalid. current code - SEGV on freeaddrinfo(NULL) 44 * 45 * Note: 46 * - The code filters out AFs that are not supported by the kernel, 47 * when globbing NULL hostname (to loopback, or wildcard). Is it the right 48 * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG 49 * in ai_flags? 50 * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague. 51 * (1) what should we do against numeric hostname (2) what should we do 52 * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready? 53 * non-loopback address configured? global address configured? 54 * 55 * OS specific notes for netbsd/openbsd/freebsd4/bsdi4: 56 * - To avoid search order issue, we have a big amount of code duplicate 57 * from gethnamaddr.c and some other places. The issues that there's no 58 * lower layer function to lookup "IPv4 or IPv6" record. Calling 59 * gethostbyname2 from getaddrinfo will end up in wrong search order, as 60 * presented above. 61 * 62 * OS specific notes for freebsd4: 63 * - FreeBSD supported $GAI. The code does not. 64 * - FreeBSD allowed classful IPv4 numeric (127.1), the code does not. 65 */ 66 67 #include "namespace.h" 68 #include <sys/types.h> 69 #include <sys/param.h> 70 #include <sys/socket.h> 71 #include <net/if.h> 72 #include <netinet/in.h> 73 #include <arpa/inet.h> 74 #include <arpa/nameser.h> 75 #include <netdb.h> 76 #include <resolv.h> 77 #include <string.h> 78 #include <stdlib.h> 79 #include <stddef.h> 80 #include <ctype.h> 81 #include <unistd.h> 82 #include <stdio.h> 83 #include <errno.h> 84 #include "un-namespace.h" 85 86 #include "res_config.h" 87 88 #ifdef DEBUG 89 #include <syslog.h> 90 #endif 91 92 #if defined(__KAME__) && defined(INET6) 93 # define FAITH 94 #endif 95 96 #define SUCCESS 0 97 #define ANY 0 98 #define YES 1 99 #define NO 0 100 101 static const char in_addrany[] = { 0, 0, 0, 0 }; 102 static const char in_loopback[] = { 127, 0, 0, 1 }; 103 #ifdef INET6 104 static const char in6_addrany[] = { 105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 106 }; 107 static const char in6_loopback[] = { 108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 109 }; 110 #endif 111 112 static const struct afd { 113 int a_af; 114 int a_addrlen; 115 int a_socklen; 116 int a_off; 117 const char *a_addrany; 118 const char *a_loopback; 119 int a_scoped; 120 } afdl [] = { 121 #ifdef INET6 122 #define N_INET6 0 123 {PF_INET6, sizeof(struct in6_addr), 124 sizeof(struct sockaddr_in6), 125 offsetof(struct sockaddr_in6, sin6_addr), 126 in6_addrany, in6_loopback, 1}, 127 #define N_INET 1 128 #else 129 #define N_INET 0 130 #endif 131 {PF_INET, sizeof(struct in_addr), 132 sizeof(struct sockaddr_in), 133 offsetof(struct sockaddr_in, sin_addr), 134 in_addrany, in_loopback, 0}, 135 {0, 0, 0, 0, NULL, NULL, 0}, 136 }; 137 138 struct explore { 139 int e_af; 140 int e_socktype; 141 int e_protocol; 142 const char *e_protostr; 143 int e_wild; 144 #define WILD_AF(ex) ((ex)->e_wild & 0x01) 145 #define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) 146 #define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) 147 }; 148 149 static const struct explore explore[] = { 150 #if 0 151 { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, 152 #endif 153 #ifdef INET6 154 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 155 { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 156 { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, 157 #endif 158 { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 159 { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 160 { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, 161 { PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 162 { PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 163 { PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 }, 164 { -1, 0, 0, NULL, 0 }, 165 }; 166 167 #ifdef INET6 168 #define PTON_MAX 16 169 #else 170 #define PTON_MAX 4 171 #endif 172 173 #define MAXPACKET (64*1024) 174 175 typedef union { 176 HEADER hdr; 177 u_char buf[MAXPACKET]; 178 } querybuf; 179 180 struct res_target { 181 struct res_target *next; 182 const char *name; /* domain name */ 183 int qclass, qtype; /* class and type of query */ 184 u_char *answer; /* buffer to put answer */ 185 int anslen; /* size of answer buffer */ 186 int n; /* result length */ 187 }; 188 189 static int str_isnumber (const char *); 190 static int explore_fqdn (const struct addrinfo *, const char *, 191 const char *, struct addrinfo **); 192 static int explore_null (const struct addrinfo *, 193 const char *, struct addrinfo **); 194 static int explore_numeric (const struct addrinfo *, const char *, 195 const char *, struct addrinfo **); 196 static int explore_numeric_scope (const struct addrinfo *, const char *, 197 const char *, struct addrinfo **); 198 static int get_canonname (const struct addrinfo *, 199 struct addrinfo *, const char *); 200 static struct addrinfo *get_ai (const struct addrinfo *, 201 const struct afd *, const char *); 202 static int get_portmatch (const struct addrinfo *, const char *); 203 static int get_port (struct addrinfo *, const char *, int); 204 static const struct afd *find_afd (int); 205 static int addrconfig (struct addrinfo *); 206 #ifdef INET6 207 static int ip6_str2scopeid (char *, struct sockaddr_in6 *, u_int32_t *); 208 #endif 209 210 static struct addrinfo *getanswer (const querybuf *, int, const char *, 211 int, const struct addrinfo *); 212 static int _dns_getaddrinfo (const struct addrinfo *, const char *, 213 struct addrinfo **); 214 static struct addrinfo *_gethtent (FILE *fp, const char *, 215 const struct addrinfo *); 216 static int _files_getaddrinfo (const struct addrinfo *, const char *, 217 struct addrinfo **); 218 #ifdef YP 219 static int _nis_getaddrinfo (const struct addrinfo *, const char *, 220 struct addrinfo **); 221 #endif 222 223 static int res_queryN (const char *, struct res_target *); 224 static int res_searchN (const char *, struct res_target *); 225 static int res_querydomainN (const char *, const char *, 226 struct res_target *); 227 228 static char *ai_errlist[] = { 229 "Success", 230 "Address family for hostname not supported", /* EAI_ADDRFAMILY */ 231 "Temporary failure in name resolution", /* EAI_AGAIN */ 232 "Invalid value for ai_flags", /* EAI_BADFLAGS */ 233 "Non-recoverable failure in name resolution", /* EAI_FAIL */ 234 "ai_family not supported", /* EAI_FAMILY */ 235 "Memory allocation failure", /* EAI_MEMORY */ 236 "No address associated with hostname", /* EAI_NODATA */ 237 "hostname nor servname provided, or not known", /* EAI_NONAME */ 238 "servname not supported for ai_socktype", /* EAI_SERVICE */ 239 "ai_socktype not supported", /* EAI_SOCKTYPE */ 240 "System error returned in errno", /* EAI_SYSTEM */ 241 "Invalid value for hints", /* EAI_BADHINTS */ 242 "Resolved protocol is unknown", /* EAI_PROTOCOL */ 243 "Unknown error", /* EAI_MAX */ 244 }; 245 246 /* 247 * Select order host function. 248 */ 249 #define MAXHOSTCONF 4 250 251 #ifndef HOSTCONF 252 # define HOSTCONF "/etc/host.conf" 253 #endif /* !HOSTCONF */ 254 255 struct _hostconf { 256 int (*byname)(const struct addrinfo *, const char *, 257 struct addrinfo **); 258 }; 259 260 /* default order */ 261 static struct _hostconf _hostconf[MAXHOSTCONF] = { 262 _dns_getaddrinfo, 263 _files_getaddrinfo, 264 #ifdef ICMPNL 265 NULL, 266 #endif /* ICMPNL */ 267 }; 268 269 static int _hostconf_init_done; 270 static void _hostconf_init(void); 271 272 /* Make getaddrinfo() thread-safe in libc for use with kernel threads. */ 273 #include "libc_private.h" 274 #include "spinlock.h" 275 /* 276 * XXX: Our res_*() is not thread-safe. So, we share lock between 277 * getaddrinfo() and getipnodeby*(). Still, we cannot use 278 * getaddrinfo() and getipnodeby*() in conjunction with other 279 * functions which call res_*(). 280 */ 281 spinlock_t __getaddrinfo_thread_lock = _SPINLOCK_INITIALIZER; 282 #define THREAD_LOCK() \ 283 if (__isthreaded) _SPINLOCK(&__getaddrinfo_thread_lock); 284 #define THREAD_UNLOCK() \ 285 if (__isthreaded) _SPINUNLOCK(&__getaddrinfo_thread_lock); 286 287 /* XXX macros that make external reference is BAD. */ 288 289 #define GET_AI(ai, afd, addr) \ 290 do { \ 291 /* external reference: pai, error, and label free */ \ 292 (ai) = get_ai(pai, (afd), (addr)); \ 293 if ((ai) == NULL) { \ 294 error = EAI_MEMORY; \ 295 goto free; \ 296 } \ 297 } while (/*CONSTCOND*/0) 298 299 #define GET_PORT(ai, serv) \ 300 do { \ 301 /* external reference: error and label free */ \ 302 error = get_port((ai), (serv), 0); \ 303 if (error != 0) \ 304 goto free; \ 305 } while (/*CONSTCOND*/0) 306 307 #define GET_CANONNAME(ai, str) \ 308 do { \ 309 /* external reference: pai, error and label free */ \ 310 error = get_canonname(pai, (ai), (str)); \ 311 if (error != 0) \ 312 goto free; \ 313 } while (/*CONSTCOND*/0) 314 315 #define ERR(err) \ 316 do { \ 317 /* external reference: error, and label bad */ \ 318 error = (err); \ 319 goto bad; \ 320 /*NOTREACHED*/ \ 321 } while (/*CONSTCOND*/0) 322 323 #define MATCH_FAMILY(x, y, w) \ 324 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) 325 #define MATCH(x, y, w) \ 326 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY))) 327 328 char * 329 gai_strerror(ecode) 330 int ecode; 331 { 332 if (ecode < 0 || ecode > EAI_MAX) 333 ecode = EAI_MAX; 334 return ai_errlist[ecode]; 335 } 336 337 void 338 freeaddrinfo(ai) 339 struct addrinfo *ai; 340 { 341 struct addrinfo *next; 342 343 do { 344 next = ai->ai_next; 345 if (ai->ai_canonname) 346 free(ai->ai_canonname); 347 /* no need to free(ai->ai_addr) */ 348 free(ai); 349 ai = next; 350 } while (ai); 351 } 352 353 static int 354 str_isnumber(p) 355 const char *p; 356 { 357 char *ep; 358 359 if (*p == '\0') 360 return NO; 361 ep = NULL; 362 errno = 0; 363 (void)strtoul(p, &ep, 10); 364 if (errno == 0 && ep && *ep == '\0') 365 return YES; 366 else 367 return NO; 368 } 369 370 int 371 getaddrinfo(hostname, servname, hints, res) 372 const char *hostname, *servname; 373 const struct addrinfo *hints; 374 struct addrinfo **res; 375 { 376 struct addrinfo sentinel; 377 struct addrinfo *cur; 378 int error = 0; 379 struct addrinfo ai; 380 struct addrinfo ai0; 381 struct addrinfo *pai; 382 const struct explore *ex; 383 384 memset(&sentinel, 0, sizeof(sentinel)); 385 cur = &sentinel; 386 pai = &ai; 387 pai->ai_flags = 0; 388 pai->ai_family = PF_UNSPEC; 389 pai->ai_socktype = ANY; 390 pai->ai_protocol = ANY; 391 pai->ai_addrlen = 0; 392 pai->ai_canonname = NULL; 393 pai->ai_addr = NULL; 394 pai->ai_next = NULL; 395 396 if (hostname == NULL && servname == NULL) 397 return EAI_NONAME; 398 if (hints) { 399 /* error check for hints */ 400 if (hints->ai_addrlen || hints->ai_canonname || 401 hints->ai_addr || hints->ai_next) 402 ERR(EAI_BADHINTS); /* xxx */ 403 if (hints->ai_flags & ~AI_MASK) 404 ERR(EAI_BADFLAGS); 405 switch (hints->ai_family) { 406 case PF_UNSPEC: 407 case PF_INET: 408 #ifdef INET6 409 case PF_INET6: 410 #endif 411 break; 412 default: 413 ERR(EAI_FAMILY); 414 } 415 memcpy(pai, hints, sizeof(*pai)); 416 417 /* 418 * if both socktype/protocol are specified, check if they 419 * are meaningful combination. 420 */ 421 if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { 422 for (ex = explore; ex->e_af >= 0; ex++) { 423 if (pai->ai_family != ex->e_af) 424 continue; 425 if (ex->e_socktype == ANY) 426 continue; 427 if (ex->e_protocol == ANY) 428 continue; 429 if (pai->ai_socktype == ex->e_socktype && 430 pai->ai_protocol != ex->e_protocol) { 431 ERR(EAI_BADHINTS); 432 } 433 } 434 } 435 } 436 437 /* 438 * post-2553: AI_ALL and AI_V4MAPPED are effective only against 439 * AF_INET6 query. They need to be ignored if specified in other 440 * occassions. 441 */ 442 switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) { 443 case AI_V4MAPPED: 444 case AI_ALL | AI_V4MAPPED: 445 if (pai->ai_family != AF_INET6) 446 pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED); 447 break; 448 case AI_ALL: 449 #if 1 450 /* illegal */ 451 ERR(EAI_BADFLAGS); 452 #else 453 pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED); 454 #endif 455 break; 456 } 457 458 /* 459 * check for special cases. (1) numeric servname is disallowed if 460 * socktype/protocol are left unspecified. (2) servname is disallowed 461 * for raw and other inet{,6} sockets. 462 */ 463 if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) 464 #ifdef PF_INET6 465 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) 466 #endif 467 ) { 468 ai0 = *pai; /* backup *pai */ 469 470 if (pai->ai_family == PF_UNSPEC) { 471 #ifdef PF_INET6 472 pai->ai_family = PF_INET6; 473 #else 474 pai->ai_family = PF_INET; 475 #endif 476 } 477 error = get_portmatch(pai, servname); 478 if (error) 479 ERR(error); 480 481 *pai = ai0; 482 } 483 484 ai0 = *pai; 485 486 /* NULL hostname, or numeric hostname */ 487 for (ex = explore; ex->e_af >= 0; ex++) { 488 *pai = ai0; 489 490 /* PF_UNSPEC entries are prepared for DNS queries only */ 491 if (ex->e_af == PF_UNSPEC) 492 continue; 493 494 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 495 continue; 496 if (!MATCH(pai->ai_socktype, ex->e_socktype, 497 WILD_SOCKTYPE(ex))) 498 continue; 499 if (!MATCH(pai->ai_protocol, ex->e_protocol, 500 WILD_PROTOCOL(ex))) 501 continue; 502 503 if (pai->ai_family == PF_UNSPEC) 504 pai->ai_family = ex->e_af; 505 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 506 pai->ai_socktype = ex->e_socktype; 507 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 508 pai->ai_protocol = ex->e_protocol; 509 510 if (hostname == NULL) 511 error = explore_null(pai, servname, &cur->ai_next); 512 else 513 error = explore_numeric_scope(pai, hostname, servname, 514 &cur->ai_next); 515 516 if (error) 517 goto free; 518 519 while (cur && cur->ai_next) 520 cur = cur->ai_next; 521 } 522 523 /* 524 * XXX 525 * If numreic representation of AF1 can be interpreted as FQDN 526 * representation of AF2, we need to think again about the code below. 527 */ 528 if (sentinel.ai_next) 529 goto good; 530 531 if (pai->ai_flags & AI_NUMERICHOST) 532 ERR(EAI_NONAME); 533 if (hostname == NULL) 534 ERR(EAI_NODATA); 535 536 if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(&ai0)) 537 ERR(EAI_FAIL); 538 539 /* 540 * hostname as alphabetical name. 541 * we would like to prefer AF_INET6 than AF_INET, so we'll make a 542 * outer loop by AFs. 543 */ 544 for (ex = explore; ex->e_af >= 0; ex++) { 545 *pai = ai0; 546 547 /* require exact match for family field */ 548 if (pai->ai_family != ex->e_af) 549 continue; 550 551 if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) { 552 continue; 553 } 554 if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) { 555 continue; 556 } 557 558 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 559 pai->ai_socktype = ex->e_socktype; 560 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 561 pai->ai_protocol = ex->e_protocol; 562 563 error = explore_fqdn(pai, hostname, servname, &cur->ai_next); 564 565 while (cur && cur->ai_next) 566 cur = cur->ai_next; 567 } 568 569 /* XXX */ 570 if (sentinel.ai_next) 571 error = 0; 572 573 if (error) 574 goto free; 575 if (error == 0) { 576 if (sentinel.ai_next) { 577 good: 578 *res = sentinel.ai_next; 579 return SUCCESS; 580 } else 581 error = EAI_FAIL; 582 } 583 free: 584 bad: 585 if (sentinel.ai_next) 586 freeaddrinfo(sentinel.ai_next); 587 *res = NULL; 588 return error; 589 } 590 591 static char * 592 _hgetword(char **pp) 593 { 594 char c, *p, *ret; 595 const char *sp; 596 static const char sep[] = "# \t\n"; 597 598 ret = NULL; 599 for (p = *pp; (c = *p) != '\0'; p++) { 600 for (sp = sep; *sp != '\0'; sp++) { 601 if (c == *sp) 602 break; 603 } 604 if (c == '#') 605 p[1] = '\0'; /* ignore rest of line */ 606 if (ret == NULL) { 607 if (*sp == '\0') 608 ret = p; 609 } else { 610 if (*sp != '\0') { 611 *p++ = '\0'; 612 break; 613 } 614 } 615 } 616 *pp = p; 617 if (ret == NULL || *ret == '\0') 618 return NULL; 619 return ret; 620 } 621 622 /* 623 * Initialize hostconf structure. 624 */ 625 626 static void 627 _hostconf_init(void) 628 { 629 FILE *fp; 630 int n; 631 char *p, *line; 632 char buf[BUFSIZ]; 633 634 _hostconf_init_done = 1; 635 n = 0; 636 p = HOSTCONF; 637 if ((fp = fopen(p, "r")) == NULL) 638 return; 639 while (n < MAXHOSTCONF && fgets(buf, sizeof(buf), fp)) { 640 line = buf; 641 if ((p = _hgetword(&line)) == NULL) 642 continue; 643 do { 644 if (strcmp(p, "hosts") == 0 645 || strcmp(p, "local") == 0 646 || strcmp(p, "file") == 0 647 || strcmp(p, "files") == 0) 648 _hostconf[n++].byname = _files_getaddrinfo; 649 else if (strcmp(p, "dns") == 0 650 || strcmp(p, "bind") == 0) 651 _hostconf[n++].byname = _dns_getaddrinfo; 652 #ifdef YP 653 else if (strcmp(p, "nis") == 0) 654 _hostconf[n++].byname = _nis_getaddrinfo; 655 #endif 656 } while ((p = _hgetword(&line)) != NULL); 657 } 658 fclose(fp); 659 if (n < 0) { 660 /* no keyword found. do not change default configuration */ 661 return; 662 } 663 for (; n < MAXHOSTCONF; n++) 664 _hostconf[n].byname = NULL; 665 } 666 667 /* 668 * FQDN hostname, DNS lookup 669 */ 670 static int 671 explore_fqdn(pai, hostname, servname, res) 672 const struct addrinfo *pai; 673 const char *hostname; 674 const char *servname; 675 struct addrinfo **res; 676 { 677 struct addrinfo *result; 678 struct addrinfo *cur; 679 int error = 0, i; 680 681 result = NULL; 682 *res = NULL; 683 684 THREAD_LOCK(); 685 686 /* 687 * if the servname does not match socktype/protocol, ignore it. 688 */ 689 if (get_portmatch(pai, servname) != 0) { 690 THREAD_UNLOCK(); 691 return 0; 692 } 693 694 if (!_hostconf_init_done) 695 _hostconf_init(); 696 697 for (i = 0; i < MAXHOSTCONF; i++) { 698 if (!_hostconf[i].byname) 699 continue; 700 error = (*_hostconf[i].byname)(pai, hostname, &result); 701 if (error != 0) 702 continue; 703 for (cur = result; cur; cur = cur->ai_next) { 704 GET_PORT(cur, servname); 705 /* canonname should be filled already */ 706 } 707 THREAD_UNLOCK(); 708 *res = result; 709 return 0; 710 } 711 712 free: 713 THREAD_UNLOCK(); 714 if (result) 715 freeaddrinfo(result); 716 return error; 717 } 718 719 /* 720 * hostname == NULL. 721 * passive socket -> anyaddr (0.0.0.0 or ::) 722 * non-passive socket -> localhost (127.0.0.1 or ::1) 723 */ 724 static int 725 explore_null(pai, servname, res) 726 const struct addrinfo *pai; 727 const char *servname; 728 struct addrinfo **res; 729 { 730 int s; 731 const struct afd *afd; 732 struct addrinfo *cur; 733 struct addrinfo sentinel; 734 int error; 735 736 *res = NULL; 737 sentinel.ai_next = NULL; 738 cur = &sentinel; 739 740 /* 741 * filter out AFs that are not supported by the kernel 742 * XXX errno? 743 */ 744 s = _socket(pai->ai_family, SOCK_DGRAM, 0); 745 if (s < 0) { 746 if (errno != EMFILE) 747 return 0; 748 } else 749 _close(s); 750 751 /* 752 * if the servname does not match socktype/protocol, ignore it. 753 */ 754 if (get_portmatch(pai, servname) != 0) 755 return 0; 756 757 afd = find_afd(pai->ai_family); 758 if (afd == NULL) 759 return 0; 760 761 if (pai->ai_flags & AI_PASSIVE) { 762 GET_AI(cur->ai_next, afd, afd->a_addrany); 763 /* xxx meaningless? 764 * GET_CANONNAME(cur->ai_next, "anyaddr"); 765 */ 766 GET_PORT(cur->ai_next, servname); 767 } else { 768 GET_AI(cur->ai_next, afd, afd->a_loopback); 769 /* xxx meaningless? 770 * GET_CANONNAME(cur->ai_next, "localhost"); 771 */ 772 GET_PORT(cur->ai_next, servname); 773 } 774 cur = cur->ai_next; 775 776 *res = sentinel.ai_next; 777 return 0; 778 779 free: 780 if (sentinel.ai_next) 781 freeaddrinfo(sentinel.ai_next); 782 return error; 783 } 784 785 /* 786 * numeric hostname 787 */ 788 static int 789 explore_numeric(pai, hostname, servname, res) 790 const struct addrinfo *pai; 791 const char *hostname; 792 const char *servname; 793 struct addrinfo **res; 794 { 795 const struct afd *afd; 796 struct addrinfo *cur; 797 struct addrinfo sentinel; 798 int error; 799 char pton[PTON_MAX]; 800 801 *res = NULL; 802 sentinel.ai_next = NULL; 803 cur = &sentinel; 804 805 /* 806 * if the servname does not match socktype/protocol, ignore it. 807 */ 808 if (get_portmatch(pai, servname) != 0) 809 return 0; 810 811 afd = find_afd(pai->ai_family); 812 if (afd == NULL) 813 return 0; 814 815 switch (afd->a_af) { 816 #if 1 /*X/Open spec*/ 817 case AF_INET: 818 if (inet_aton(hostname, (struct in_addr *)pton) == 1) { 819 if (pai->ai_family == afd->a_af || 820 pai->ai_family == PF_UNSPEC /*?*/) { 821 GET_AI(cur->ai_next, afd, pton); 822 GET_PORT(cur->ai_next, servname); 823 while (cur && cur->ai_next) 824 cur = cur->ai_next; 825 } else 826 ERR(EAI_FAMILY); /*xxx*/ 827 } 828 break; 829 #endif 830 default: 831 if (inet_pton(afd->a_af, hostname, pton) == 1) { 832 if (pai->ai_family == afd->a_af || 833 pai->ai_family == PF_UNSPEC /*?*/) { 834 GET_AI(cur->ai_next, afd, pton); 835 GET_PORT(cur->ai_next, servname); 836 while (cur && cur->ai_next) 837 cur = cur->ai_next; 838 } else 839 ERR(EAI_FAMILY); /* XXX */ 840 } 841 break; 842 } 843 844 *res = sentinel.ai_next; 845 return 0; 846 847 free: 848 bad: 849 if (sentinel.ai_next) 850 freeaddrinfo(sentinel.ai_next); 851 return error; 852 } 853 854 /* 855 * numeric hostname with scope 856 */ 857 static int 858 explore_numeric_scope(pai, hostname, servname, res) 859 const struct addrinfo *pai; 860 const char *hostname; 861 const char *servname; 862 struct addrinfo **res; 863 { 864 #if !defined(SCOPE_DELIMITER) || !defined(INET6) 865 return explore_numeric(pai, hostname, servname, res); 866 #else 867 const struct afd *afd; 868 struct addrinfo *cur; 869 int error; 870 char *cp, *hostname2 = NULL, *scope, *addr; 871 struct sockaddr_in6 *sin6; 872 873 /* 874 * if the servname does not match socktype/protocol, ignore it. 875 */ 876 if (get_portmatch(pai, servname) != 0) 877 return 0; 878 879 afd = find_afd(pai->ai_family); 880 if (afd == NULL) 881 return 0; 882 if (!afd->a_scoped) 883 return explore_numeric(pai, hostname, servname, res); 884 885 cp = strchr(hostname, SCOPE_DELIMITER); 886 if (cp == NULL) 887 return explore_numeric(pai, hostname, servname, res); 888 889 /* 890 * Handle special case of <scoped_address><delimiter><scope id> 891 */ 892 hostname2 = strdup(hostname); 893 if (hostname2 == NULL) 894 return EAI_MEMORY; 895 /* terminate at the delimiter */ 896 hostname2[cp - hostname] = '\0'; 897 addr = hostname2; 898 scope = cp + 1; 899 900 error = explore_numeric(pai, addr, servname, res); 901 if (error == 0) { 902 u_int32_t scopeid; 903 904 for (cur = *res; cur; cur = cur->ai_next) { 905 if (cur->ai_family != AF_INET6) 906 continue; 907 sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr; 908 if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) { 909 free(hostname2); 910 return(EAI_NODATA); /* XXX: is return OK? */ 911 } 912 sin6->sin6_scope_id = scopeid; 913 } 914 } 915 916 free(hostname2); 917 918 return error; 919 #endif 920 } 921 922 static int 923 get_canonname(pai, ai, str) 924 const struct addrinfo *pai; 925 struct addrinfo *ai; 926 const char *str; 927 { 928 if ((pai->ai_flags & AI_CANONNAME) != 0) { 929 ai->ai_canonname = (char *)malloc(strlen(str) + 1); 930 if (ai->ai_canonname == NULL) 931 return EAI_MEMORY; 932 strlcpy(ai->ai_canonname, str, strlen(str) + 1); 933 } 934 return 0; 935 } 936 937 static struct addrinfo * 938 get_ai(pai, afd, addr) 939 const struct addrinfo *pai; 940 const struct afd *afd; 941 const char *addr; 942 { 943 char *p; 944 struct addrinfo *ai; 945 #ifdef FAITH 946 struct in6_addr faith_prefix; 947 char *fp_str; 948 int translate = 0; 949 #endif 950 951 #ifdef FAITH 952 /* 953 * Transfrom an IPv4 addr into a special IPv6 addr format for 954 * IPv6->IPv4 translation gateway. (only TCP is supported now) 955 * 956 * +-----------------------------------+------------+ 957 * | faith prefix part (12 bytes) | embedded | 958 * | | IPv4 addr part (4 bytes) 959 * +-----------------------------------+------------+ 960 * 961 * faith prefix part is specified as ascii IPv6 addr format 962 * in environmental variable GAI. 963 * For FAITH to work correctly, routing to faith prefix must be 964 * setup toward a machine where a FAITH daemon operates. 965 * Also, the machine must enable some mechanizm 966 * (e.g. faith interface hack) to divert those packet with 967 * faith prefixed destination addr to user-land FAITH daemon. 968 */ 969 fp_str = getenv("GAI"); 970 if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 && 971 afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) { 972 u_int32_t v4a; 973 u_int8_t v4a_top; 974 975 memcpy(&v4a, addr, sizeof v4a); 976 v4a_top = v4a >> IN_CLASSA_NSHIFT; 977 if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) && 978 v4a_top != 0 && v4a != IN_LOOPBACKNET) { 979 afd = &afdl[N_INET6]; 980 memcpy(&faith_prefix.s6_addr[12], addr, 981 sizeof(struct in_addr)); 982 translate = 1; 983 } 984 } 985 #endif 986 987 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) 988 + (afd->a_socklen)); 989 if (ai == NULL) 990 return NULL; 991 992 memcpy(ai, pai, sizeof(struct addrinfo)); 993 ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); 994 memset(ai->ai_addr, 0, (size_t)afd->a_socklen); 995 ai->ai_addr->sa_len = afd->a_socklen; 996 ai->ai_addrlen = afd->a_socklen; 997 ai->ai_addr->sa_family = ai->ai_family = afd->a_af; 998 p = (char *)(ai->ai_addr); 999 #ifdef FAITH 1000 if (translate == 1) 1001 memcpy(p + afd->a_off, &faith_prefix, afd->a_addrlen); 1002 else 1003 #endif 1004 memcpy(p + afd->a_off, addr, afd->a_addrlen); 1005 1006 return ai; 1007 } 1008 1009 static int 1010 get_portmatch(ai, servname) 1011 const struct addrinfo *ai; 1012 const char *servname; 1013 { 1014 1015 /* get_port does not touch first argument. when matchonly == 1. */ 1016 /* LINTED const cast */ 1017 return get_port((struct addrinfo *)ai, servname, 1); 1018 } 1019 1020 static int 1021 get_port(ai, servname, matchonly) 1022 struct addrinfo *ai; 1023 const char *servname; 1024 int matchonly; 1025 { 1026 const char *proto; 1027 struct servent *sp; 1028 int port; 1029 int allownumeric; 1030 1031 if (servname == NULL) 1032 return 0; 1033 switch (ai->ai_family) { 1034 case AF_INET: 1035 #ifdef AF_INET6 1036 case AF_INET6: 1037 #endif 1038 break; 1039 default: 1040 return 0; 1041 } 1042 1043 switch (ai->ai_socktype) { 1044 case SOCK_RAW: 1045 return EAI_SERVICE; 1046 case SOCK_DGRAM: 1047 case SOCK_STREAM: 1048 allownumeric = 1; 1049 break; 1050 case ANY: 1051 allownumeric = 0; 1052 break; 1053 default: 1054 return EAI_SOCKTYPE; 1055 } 1056 1057 if (str_isnumber(servname)) { 1058 if (!allownumeric) 1059 return EAI_SERVICE; 1060 port = atoi(servname); 1061 if (port < 0 || port > 65535) 1062 return EAI_SERVICE; 1063 port = htons(port); 1064 } else { 1065 switch (ai->ai_socktype) { 1066 case SOCK_DGRAM: 1067 proto = "udp"; 1068 break; 1069 case SOCK_STREAM: 1070 proto = "tcp"; 1071 break; 1072 default: 1073 proto = NULL; 1074 break; 1075 } 1076 1077 if ((sp = getservbyname(servname, proto)) == NULL) 1078 return EAI_SERVICE; 1079 port = sp->s_port; 1080 } 1081 1082 if (!matchonly) { 1083 switch (ai->ai_family) { 1084 case AF_INET: 1085 ((struct sockaddr_in *)(void *) 1086 ai->ai_addr)->sin_port = port; 1087 break; 1088 #ifdef INET6 1089 case AF_INET6: 1090 ((struct sockaddr_in6 *)(void *) 1091 ai->ai_addr)->sin6_port = port; 1092 break; 1093 #endif 1094 } 1095 } 1096 1097 return 0; 1098 } 1099 1100 static const struct afd * 1101 find_afd(af) 1102 int af; 1103 { 1104 const struct afd *afd; 1105 1106 if (af == PF_UNSPEC) 1107 return NULL; 1108 for (afd = afdl; afd->a_af; afd++) { 1109 if (afd->a_af == af) 1110 return afd; 1111 } 1112 return NULL; 1113 } 1114 1115 /* 1116 * post-2553: AI_ADDRCONFIG check. if we use getipnodeby* as backend, backend 1117 * will take care of it. 1118 * the semantics of AI_ADDRCONFIG is not defined well. we are not sure 1119 * if the code is right or not. 1120 * 1121 * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with 1122 * _dns_getaddrinfo. 1123 */ 1124 static int 1125 addrconfig(pai) 1126 struct addrinfo *pai; 1127 { 1128 int s, af; 1129 1130 /* 1131 * TODO: 1132 * Note that implementation dependent test for address 1133 * configuration should be done everytime called 1134 * (or apropriate interval), 1135 * because addresses will be dynamically assigned or deleted. 1136 */ 1137 af = pai->ai_family; 1138 if (af == AF_UNSPEC) { 1139 if ((s = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 1140 af = AF_INET; 1141 else { 1142 _close(s); 1143 if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0) 1144 af = AF_INET6; 1145 else 1146 _close(s); 1147 } 1148 1149 } 1150 if (af != AF_UNSPEC) { 1151 if ((s = _socket(af, SOCK_DGRAM, 0)) < 0) 1152 return 0; 1153 _close(s); 1154 } 1155 pai->ai_family = af; 1156 return 1; 1157 } 1158 1159 #ifdef INET6 1160 /* convert a string to a scope identifier. XXX: IPv6 specific */ 1161 static int 1162 ip6_str2scopeid(scope, sin6, scopeid) 1163 char *scope; 1164 struct sockaddr_in6 *sin6; 1165 u_int32_t *scopeid; 1166 { 1167 u_long lscopeid; 1168 struct in6_addr *a6; 1169 char *ep; 1170 1171 a6 = &sin6->sin6_addr; 1172 1173 /* empty scopeid portion is invalid */ 1174 if (*scope == '\0') 1175 return -1; 1176 1177 if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) { 1178 /* 1179 * We currently assume a one-to-one mapping between links 1180 * and interfaces, so we simply use interface indices for 1181 * like-local scopes. 1182 */ 1183 *scopeid = if_nametoindex(scope); 1184 if (*scopeid == 0) 1185 goto trynumeric; 1186 return 0; 1187 } 1188 1189 /* still unclear about literal, allow numeric only - placeholder */ 1190 if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) 1191 goto trynumeric; 1192 if (IN6_IS_ADDR_MC_ORGLOCAL(a6)) 1193 goto trynumeric; 1194 else 1195 goto trynumeric; /* global */ 1196 1197 /* try to convert to a numeric id as a last resort */ 1198 trynumeric: 1199 errno = 0; 1200 lscopeid = strtoul(scope, &ep, 10); 1201 *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL); 1202 if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid) 1203 return 0; 1204 else 1205 return -1; 1206 } 1207 #endif 1208 1209 #ifdef RESOLVSORT 1210 struct addr_ptr { 1211 struct addrinfo *ai; 1212 int aval; 1213 }; 1214 1215 static int 1216 addr4sort(struct addrinfo *sentinel) 1217 { 1218 struct addrinfo *ai; 1219 struct addr_ptr *addrs, addr; 1220 struct sockaddr_in *sin; 1221 int naddrs, i, j; 1222 int needsort = 0; 1223 1224 if (!sentinel) 1225 return -1; 1226 naddrs = 0; 1227 for (ai = sentinel->ai_next; ai; ai = ai->ai_next) 1228 naddrs++; 1229 if (naddrs < 2) 1230 return 0; /* We don't need sorting. */ 1231 if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL) 1232 return -1; 1233 i = 0; 1234 for (ai = sentinel->ai_next; ai; ai = ai->ai_next) { 1235 sin = (struct sockaddr_in *)ai->ai_addr; 1236 for (j = 0; (unsigned)j < _res.nsort; j++) { 1237 if (_res.sort_list[j].addr.s_addr == 1238 (sin->sin_addr.s_addr & _res.sort_list[j].mask)) 1239 break; 1240 } 1241 addrs[i].ai = ai; 1242 addrs[i].aval = j; 1243 if (needsort == 0 && i > 0 && j < addrs[i - 1].aval) 1244 needsort = i; 1245 i++; 1246 } 1247 if (!needsort) { 1248 free(addrs); 1249 return 0; 1250 } 1251 1252 while (needsort < naddrs) { 1253 for (j = needsort - 1; j >= 0; j--) { 1254 if (addrs[j].aval > addrs[j+1].aval) { 1255 addr = addrs[j]; 1256 addrs[j] = addrs[j + 1]; 1257 addrs[j + 1] = addr; 1258 } else 1259 break; 1260 } 1261 needsort++; 1262 } 1263 1264 ai = sentinel; 1265 for (i = 0; i < naddrs; ++i) { 1266 ai->ai_next = addrs[i].ai; 1267 ai = ai->ai_next; 1268 } 1269 ai->ai_next = NULL; 1270 free(addrs); 1271 return 0; 1272 } 1273 #endif /*RESOLVSORT*/ 1274 1275 #ifdef DEBUG 1276 static const char AskedForGot[] = 1277 "gethostby*.getanswer: asked for \"%s\", got \"%s\""; 1278 #endif 1279 1280 static struct addrinfo * 1281 getanswer(answer, anslen, qname, qtype, pai) 1282 const querybuf *answer; 1283 int anslen; 1284 const char *qname; 1285 int qtype; 1286 const struct addrinfo *pai; 1287 { 1288 struct addrinfo sentinel, *cur; 1289 struct addrinfo ai; 1290 const struct afd *afd; 1291 char *canonname; 1292 const HEADER *hp; 1293 const u_char *cp; 1294 int n; 1295 const u_char *eom; 1296 char *bp, *ep; 1297 int type, class, ancount, qdcount; 1298 int haveanswer, had_error; 1299 char tbuf[MAXDNAME]; 1300 int (*name_ok) (const char *); 1301 char hostbuf[8*1024]; 1302 1303 memset(&sentinel, 0, sizeof(sentinel)); 1304 cur = &sentinel; 1305 1306 canonname = NULL; 1307 eom = answer->buf + anslen; 1308 switch (qtype) { 1309 case T_A: 1310 case T_AAAA: 1311 case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/ 1312 name_ok = res_hnok; 1313 break; 1314 default: 1315 return (NULL); /* XXX should be abort(); */ 1316 } 1317 /* 1318 * find first satisfactory answer 1319 */ 1320 hp = &answer->hdr; 1321 ancount = ntohs(hp->ancount); 1322 qdcount = ntohs(hp->qdcount); 1323 bp = hostbuf; 1324 ep = hostbuf + sizeof hostbuf; 1325 cp = answer->buf + HFIXEDSZ; 1326 if (qdcount != 1) { 1327 h_errno = NO_RECOVERY; 1328 return (NULL); 1329 } 1330 n = dn_expand(answer->buf, eom, cp, bp, ep - bp); 1331 if ((n < 0) || !(*name_ok)(bp)) { 1332 h_errno = NO_RECOVERY; 1333 return (NULL); 1334 } 1335 cp += n + QFIXEDSZ; 1336 if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) { 1337 /* res_send() has already verified that the query name is the 1338 * same as the one we sent; this just gets the expanded name 1339 * (i.e., with the succeeding search-domain tacked on). 1340 */ 1341 n = strlen(bp) + 1; /* for the \0 */ 1342 if (n >= MAXHOSTNAMELEN) { 1343 h_errno = NO_RECOVERY; 1344 return (NULL); 1345 } 1346 canonname = bp; 1347 bp += n; 1348 /* The qname can be abbreviated, but h_name is now absolute. */ 1349 qname = canonname; 1350 } 1351 haveanswer = 0; 1352 had_error = 0; 1353 while (ancount-- > 0 && cp < eom && !had_error) { 1354 n = dn_expand(answer->buf, eom, cp, bp, ep - bp); 1355 if ((n < 0) || !(*name_ok)(bp)) { 1356 had_error++; 1357 continue; 1358 } 1359 cp += n; /* name */ 1360 type = _getshort(cp); 1361 cp += INT16SZ; /* type */ 1362 class = _getshort(cp); 1363 cp += INT16SZ + INT32SZ; /* class, TTL */ 1364 n = _getshort(cp); 1365 cp += INT16SZ; /* len */ 1366 if (class != C_IN) { 1367 /* XXX - debug? syslog? */ 1368 cp += n; 1369 continue; /* XXX - had_error++ ? */ 1370 } 1371 if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && 1372 type == T_CNAME) { 1373 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); 1374 if ((n < 0) || !(*name_ok)(tbuf)) { 1375 had_error++; 1376 continue; 1377 } 1378 cp += n; 1379 /* Get canonical name. */ 1380 n = strlen(tbuf) + 1; /* for the \0 */ 1381 if (n > ep - bp || n >= MAXHOSTNAMELEN) { 1382 had_error++; 1383 continue; 1384 } 1385 strlcpy(bp, tbuf, ep - bp); 1386 canonname = bp; 1387 bp += n; 1388 continue; 1389 } 1390 if (qtype == T_ANY) { 1391 if (!(type == T_A || type == T_AAAA)) { 1392 cp += n; 1393 continue; 1394 } 1395 } else if (type != qtype) { 1396 #ifdef DEBUG 1397 if (type != T_KEY && type != T_SIG) 1398 syslog(LOG_NOTICE|LOG_AUTH, 1399 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", 1400 qname, p_class(C_IN), p_type(qtype), 1401 p_type(type)); 1402 #endif 1403 cp += n; 1404 continue; /* XXX - had_error++ ? */ 1405 } 1406 switch (type) { 1407 case T_A: 1408 case T_AAAA: 1409 if (strcasecmp(canonname, bp) != 0) { 1410 #ifdef DEBUG 1411 syslog(LOG_NOTICE|LOG_AUTH, 1412 AskedForGot, canonname, bp); 1413 #endif 1414 cp += n; 1415 continue; /* XXX - had_error++ ? */ 1416 } 1417 if (type == T_A && n != INADDRSZ) { 1418 cp += n; 1419 continue; 1420 } 1421 if (type == T_AAAA && n != IN6ADDRSZ) { 1422 cp += n; 1423 continue; 1424 } 1425 #ifdef FILTER_V4MAPPED 1426 if (type == T_AAAA) { 1427 struct in6_addr in6; 1428 memcpy(&in6, cp, sizeof(in6)); 1429 if (IN6_IS_ADDR_V4MAPPED(&in6)) { 1430 cp += n; 1431 continue; 1432 } 1433 } 1434 #endif 1435 if (!haveanswer) { 1436 int nn; 1437 1438 canonname = bp; 1439 nn = strlen(bp) + 1; /* for the \0 */ 1440 bp += nn; 1441 } 1442 1443 /* don't overwrite pai */ 1444 ai = *pai; 1445 ai.ai_family = (type == T_A) ? AF_INET : AF_INET6; 1446 afd = find_afd(ai.ai_family); 1447 if (afd == NULL) { 1448 cp += n; 1449 continue; 1450 } 1451 cur->ai_next = get_ai(&ai, afd, (const char *)cp); 1452 if (cur->ai_next == NULL) 1453 had_error++; 1454 while (cur && cur->ai_next) 1455 cur = cur->ai_next; 1456 cp += n; 1457 break; 1458 default: 1459 abort(); 1460 } 1461 if (!had_error) 1462 haveanswer++; 1463 } 1464 if (haveanswer) { 1465 #if defined(RESOLVSORT) 1466 /* 1467 * We support only IPv4 address for backward 1468 * compatibility against gethostbyname(3). 1469 */ 1470 if (_res.nsort && qtype == T_A) { 1471 if (addr4sort(&sentinel) < 0) { 1472 freeaddrinfo(sentinel.ai_next); 1473 h_errno = NO_RECOVERY; 1474 return NULL; 1475 } 1476 } 1477 #endif /*RESOLVSORT*/ 1478 if (!canonname) 1479 (void)get_canonname(pai, sentinel.ai_next, qname); 1480 else 1481 (void)get_canonname(pai, sentinel.ai_next, canonname); 1482 h_errno = NETDB_SUCCESS; 1483 return sentinel.ai_next; 1484 } 1485 1486 h_errno = NO_RECOVERY; 1487 return NULL; 1488 } 1489 1490 /*ARGSUSED*/ 1491 static int 1492 _dns_getaddrinfo(pai, hostname, res) 1493 const struct addrinfo *pai; 1494 const char *hostname; 1495 struct addrinfo **res; 1496 { 1497 struct addrinfo *ai; 1498 querybuf *buf, *buf2; 1499 const char *name; 1500 struct addrinfo sentinel, *cur; 1501 struct res_target q, q2; 1502 1503 memset(&q, 0, sizeof(q2)); 1504 memset(&q2, 0, sizeof(q2)); 1505 memset(&sentinel, 0, sizeof(sentinel)); 1506 cur = &sentinel; 1507 1508 buf = malloc(sizeof(*buf)); 1509 if (!buf) { 1510 h_errno = NETDB_INTERNAL; 1511 return EAI_MEMORY; 1512 } 1513 buf2 = malloc(sizeof(*buf2)); 1514 if (!buf2) { 1515 free(buf); 1516 h_errno = NETDB_INTERNAL; 1517 return EAI_MEMORY; 1518 } 1519 1520 switch (pai->ai_family) { 1521 case AF_UNSPEC: 1522 q.name = name; 1523 q.qclass = C_IN; 1524 q.qtype = T_A; 1525 q.answer = buf->buf; 1526 q.anslen = sizeof(buf->buf); 1527 q.next = &q2; 1528 q2.name = name; 1529 q2.qclass = C_IN; 1530 q2.qtype = T_AAAA; 1531 q2.answer = buf2->buf; 1532 q2.anslen = sizeof(buf2->buf); 1533 break; 1534 case AF_INET: 1535 q.name = name; 1536 q.qclass = C_IN; 1537 q.qtype = T_A; 1538 q.answer = buf->buf; 1539 q.anslen = sizeof(buf->buf); 1540 break; 1541 case AF_INET6: 1542 q.name = name; 1543 q.qclass = C_IN; 1544 q.qtype = T_AAAA; 1545 q.answer = buf->buf; 1546 q.anslen = sizeof(buf->buf); 1547 break; 1548 default: 1549 free(buf); 1550 free(buf2); 1551 return EAI_FAIL; 1552 } 1553 if (res_searchN(hostname, &q) < 0) { 1554 free(buf); 1555 free(buf2); 1556 return EAI_NODATA; 1557 } 1558 /* prefer IPv6 */ 1559 if (q.next) { 1560 ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai); 1561 if (ai) { 1562 cur->ai_next = ai; 1563 while (cur && cur->ai_next) 1564 cur = cur->ai_next; 1565 } 1566 } 1567 1568 ai = getanswer(buf, q.n, q.name, q.qtype, pai); 1569 if (ai) 1570 cur->ai_next = ai; 1571 free(buf); 1572 free(buf2); 1573 if (sentinel.ai_next == NULL) 1574 switch (h_errno) { 1575 case HOST_NOT_FOUND: 1576 return EAI_NODATA; 1577 case TRY_AGAIN: 1578 return EAI_AGAIN; 1579 default: 1580 return EAI_FAIL; 1581 } 1582 *res = sentinel.ai_next; 1583 return 0; 1584 } 1585 1586 static struct addrinfo * 1587 _gethtent(hostf, name, pai) 1588 FILE *hostf; 1589 const char *name; 1590 const struct addrinfo *pai; 1591 { 1592 char *p; 1593 char *cp, *tname, *cname; 1594 struct addrinfo hints, *res0, *res; 1595 int error; 1596 const char *addr; 1597 char hostbuf[8*1024]; 1598 1599 again: 1600 if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) 1601 return (NULL); 1602 if (*p == '#') 1603 goto again; 1604 if (!(cp = strpbrk(p, "#\n"))) 1605 goto again; 1606 *cp = '\0'; 1607 if (!(cp = strpbrk(p, " \t"))) 1608 goto again; 1609 *cp++ = '\0'; 1610 addr = p; 1611 cname = NULL; 1612 /* if this is not something we're looking for, skip it. */ 1613 while (cp && *cp) { 1614 if (*cp == ' ' || *cp == '\t') { 1615 cp++; 1616 continue; 1617 } 1618 tname = cp; 1619 if (cname == NULL) 1620 cname = cp; 1621 if ((cp = strpbrk(cp, " \t")) != NULL) 1622 *cp++ = '\0'; 1623 if (strcasecmp(name, tname) == 0) 1624 goto found; 1625 } 1626 goto again; 1627 1628 found: 1629 /* we should not glob socktype/protocol here */ 1630 memset(&hints, 0, sizeof(hints)); 1631 hints.ai_family = pai->ai_family; 1632 hints.ai_socktype = SOCK_DGRAM; 1633 hints.ai_protocol = 0; 1634 hints.ai_flags = AI_NUMERICHOST; 1635 error = getaddrinfo(addr, "0", &hints, &res0); 1636 if (error) 1637 goto again; 1638 #ifdef FILTER_V4MAPPED 1639 /* XXX should check all items in the chain */ 1640 if (res0->ai_family == AF_INET6 && 1641 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr)) { 1642 freeaddrinfo(res0); 1643 goto again; 1644 } 1645 #endif 1646 for (res = res0; res; res = res->ai_next) { 1647 /* cover it up */ 1648 res->ai_flags = pai->ai_flags; 1649 res->ai_socktype = pai->ai_socktype; 1650 res->ai_protocol = pai->ai_protocol; 1651 1652 if (pai->ai_flags & AI_CANONNAME) { 1653 if (get_canonname(pai, res, cname) != 0) { 1654 freeaddrinfo(res0); 1655 goto again; 1656 } 1657 } 1658 } 1659 return res0; 1660 } 1661 1662 /*ARGSUSED*/ 1663 static int 1664 _files_getaddrinfo(pai, hostname, res) 1665 const struct addrinfo *pai; 1666 const char *hostname; 1667 struct addrinfo **res; 1668 { 1669 FILE *hostf; 1670 struct addrinfo sentinel, *cur; 1671 struct addrinfo *p; 1672 1673 sentinel.ai_next = NULL; 1674 cur = &sentinel; 1675 1676 if ((hostf = fopen(_PATH_HOSTS, "r")) == NULL) 1677 return EAI_FAIL; 1678 while ((p = _gethtent(hostf, hostname, pai)) != NULL) { 1679 cur->ai_next = p; 1680 while (cur && cur->ai_next) 1681 cur = cur->ai_next; 1682 } 1683 fclose(hostf); 1684 1685 if (!sentinel.ai_next) 1686 return EAI_NODATA; 1687 1688 *res = sentinel.ai_next; 1689 return 0; 1690 } 1691 1692 #ifdef YP 1693 /*ARGSUSED*/ 1694 static int 1695 _nis_getaddrinfo(pai, hostname, res) 1696 const struct addrinfo *pai; 1697 const char *hostname; 1698 struct addrinfo **res; 1699 { 1700 struct hostent *hp; 1701 int h_error; 1702 int af; 1703 struct addrinfo sentinel, *cur; 1704 int i; 1705 const struct afd *afd; 1706 int error; 1707 1708 sentinel.ai_next = NULL; 1709 cur = &sentinel; 1710 1711 af = (pai->ai_family == AF_UNSPEC) ? AF_INET : pai->ai_family; 1712 if (af != AF_INET) 1713 return (EAI_ADDRFAMILY); 1714 1715 if ((hp = _gethostbynisname(hostname, af)) == NULL) { 1716 switch (errno) { 1717 /* XXX: should be filled in */ 1718 default: 1719 error = EAI_FAIL; 1720 break; 1721 } 1722 } else if (hp->h_name == NULL || 1723 hp->h_name[0] == 0 || hp->h_addr_list[0] == NULL) { 1724 hp = NULL; 1725 error = EAI_FAIL; 1726 } 1727 1728 if (hp == NULL) 1729 return error; 1730 1731 for (i = 0; hp->h_addr_list[i] != NULL; i++) { 1732 if (hp->h_addrtype != af) 1733 continue; 1734 1735 afd = find_afd(hp->h_addrtype); 1736 if (afd == NULL) 1737 continue; 1738 1739 GET_AI(cur->ai_next, afd, hp->h_addr_list[i]); 1740 if ((pai->ai_flags & AI_CANONNAME) != 0) { 1741 /* 1742 * RFC2553 says that ai_canonname will be set only for 1743 * the first element. we do it for all the elements, 1744 * just for convenience. 1745 */ 1746 GET_CANONNAME(cur->ai_next, hp->h_name); 1747 } 1748 1749 while (cur && cur->ai_next) 1750 cur = cur->ai_next; 1751 } 1752 1753 *res = sentinel.ai_next; 1754 return 0; 1755 1756 free: 1757 if (sentinel.ai_next) 1758 freeaddrinfo(sentinel.ai_next); 1759 return error; 1760 } 1761 #endif 1762 1763 /* resolver logic */ 1764 1765 extern const char *__hostalias (const char *); 1766 extern int h_errno; 1767 1768 /* 1769 * Formulate a normal query, send, and await answer. 1770 * Returned answer is placed in supplied buffer "answer". 1771 * Perform preliminary check of answer, returning success only 1772 * if no error is indicated and the answer count is nonzero. 1773 * Return the size of the response on success, -1 on error. 1774 * Error number is left in h_errno. 1775 * 1776 * Caller must parse answer and determine whether it answers the question. 1777 */ 1778 static int 1779 res_queryN(name, target) 1780 const char *name; /* domain name */ 1781 struct res_target *target; 1782 { 1783 u_char *buf; 1784 HEADER *hp; 1785 int n; 1786 struct res_target *t; 1787 int rcode; 1788 int ancount; 1789 1790 rcode = NOERROR; 1791 ancount = 0; 1792 1793 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 1794 h_errno = NETDB_INTERNAL; 1795 return (-1); 1796 } 1797 1798 buf = malloc(MAXPACKET); 1799 if (!buf) { 1800 h_errno = NETDB_INTERNAL; 1801 return (-1); 1802 } 1803 1804 for (t = target; t; t = t->next) { 1805 int class, type; 1806 u_char *answer; 1807 int anslen; 1808 1809 hp = (HEADER *)(void *)t->answer; 1810 hp->rcode = NOERROR; /* default */ 1811 1812 /* make it easier... */ 1813 class = t->qclass; 1814 type = t->qtype; 1815 answer = t->answer; 1816 anslen = t->anslen; 1817 #ifdef DEBUG 1818 if (_res.options & RES_DEBUG) 1819 printf(";; res_query(%s, %d, %d)\n", name, class, type); 1820 #endif 1821 1822 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, 1823 buf, MAXPACKET); 1824 if (n > 0 && (_res.options & RES_USE_EDNS0) != 0) 1825 n = res_opt(n, buf, MAXPACKET, anslen); 1826 if (n <= 0) { 1827 #ifdef DEBUG 1828 if (_res.options & RES_DEBUG) 1829 printf(";; res_query: mkquery failed\n"); 1830 #endif 1831 free(buf); 1832 h_errno = NO_RECOVERY; 1833 return (n); 1834 } 1835 n = res_send(buf, n, answer, anslen); 1836 #if 0 1837 if (n < 0) { 1838 #ifdef DEBUG 1839 if (_res.options & RES_DEBUG) 1840 printf(";; res_query: send error\n"); 1841 #endif 1842 free(buf); 1843 h_errno = TRY_AGAIN; 1844 return (n); 1845 } 1846 #endif 1847 1848 if (n < 0 || n > anslen) 1849 hp->rcode = FORMERR; /* XXX not very informative */ 1850 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { 1851 rcode = hp->rcode; /* record most recent error */ 1852 #ifdef DEBUG 1853 if (_res.options & RES_DEBUG) 1854 printf(";; rcode = %u, ancount=%u\n", hp->rcode, 1855 ntohs(hp->ancount)); 1856 #endif 1857 continue; 1858 } 1859 1860 ancount += ntohs(hp->ancount); 1861 1862 t->n = n; 1863 } 1864 1865 free(buf); 1866 1867 if (ancount == 0) { 1868 switch (rcode) { 1869 case NXDOMAIN: 1870 h_errno = HOST_NOT_FOUND; 1871 break; 1872 case SERVFAIL: 1873 h_errno = TRY_AGAIN; 1874 break; 1875 case NOERROR: 1876 h_errno = NO_DATA; 1877 break; 1878 case FORMERR: 1879 case NOTIMP: 1880 case REFUSED: 1881 default: 1882 h_errno = NO_RECOVERY; 1883 break; 1884 } 1885 return (-1); 1886 } 1887 return (ancount); 1888 } 1889 1890 /* 1891 * Formulate a normal query, send, and retrieve answer in supplied buffer. 1892 * Return the size of the response on success, -1 on error. 1893 * If enabled, implement search rules until answer or unrecoverable failure 1894 * is detected. Error code, if any, is left in h_errno. 1895 */ 1896 static int 1897 res_searchN(name, target) 1898 const char *name; /* domain name */ 1899 struct res_target *target; 1900 { 1901 const char *cp, * const *domain; 1902 HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/ 1903 u_int dots; 1904 int trailing_dot, ret, saved_herrno; 1905 int got_nodata = 0, got_servfail = 0, tried_as_is = 0; 1906 1907 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 1908 h_errno = NETDB_INTERNAL; 1909 return (-1); 1910 } 1911 1912 errno = 0; 1913 h_errno = HOST_NOT_FOUND; /* default, if we never query */ 1914 dots = 0; 1915 for (cp = name; *cp; cp++) 1916 dots += (*cp == '.'); 1917 trailing_dot = 0; 1918 if (cp > name && *--cp == '.') 1919 trailing_dot++; 1920 1921 /* 1922 * if there aren't any dots, it could be a user-level alias 1923 */ 1924 if (!dots && (cp = __hostalias(name)) != NULL) 1925 return (res_queryN(cp, target)); 1926 1927 /* 1928 * If there are dots in the name already, let's just give it a try 1929 * 'as is'. The threshold can be set with the "ndots" option. 1930 */ 1931 saved_herrno = -1; 1932 if (dots >= _res.ndots) { 1933 ret = res_querydomainN(name, NULL, target); 1934 if (ret > 0) 1935 return (ret); 1936 saved_herrno = h_errno; 1937 tried_as_is++; 1938 } 1939 1940 /* 1941 * We do at least one level of search if 1942 * - there is no dot and RES_DEFNAME is set, or 1943 * - there is at least one dot, there is no trailing dot, 1944 * and RES_DNSRCH is set. 1945 */ 1946 if ((!dots && (_res.options & RES_DEFNAMES)) || 1947 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { 1948 int done = 0; 1949 1950 for (domain = (const char * const *)_res.dnsrch; 1951 *domain && !done; 1952 domain++) { 1953 1954 ret = res_querydomainN(name, *domain, target); 1955 if (ret > 0) 1956 return (ret); 1957 1958 /* 1959 * If no server present, give up. 1960 * If name isn't found in this domain, 1961 * keep trying higher domains in the search list 1962 * (if that's enabled). 1963 * On a NO_DATA error, keep trying, otherwise 1964 * a wildcard entry of another type could keep us 1965 * from finding this entry higher in the domain. 1966 * If we get some other error (negative answer or 1967 * server failure), then stop searching up, 1968 * but try the input name below in case it's 1969 * fully-qualified. 1970 */ 1971 if (errno == ECONNREFUSED) { 1972 h_errno = TRY_AGAIN; 1973 return (-1); 1974 } 1975 1976 switch (h_errno) { 1977 case NO_DATA: 1978 got_nodata++; 1979 /* FALLTHROUGH */ 1980 case HOST_NOT_FOUND: 1981 /* keep trying */ 1982 break; 1983 case TRY_AGAIN: 1984 if (hp->rcode == SERVFAIL) { 1985 /* try next search element, if any */ 1986 got_servfail++; 1987 break; 1988 } 1989 /* FALLTHROUGH */ 1990 default: 1991 /* anything else implies that we're done */ 1992 done++; 1993 } 1994 /* 1995 * if we got here for some reason other than DNSRCH, 1996 * we only wanted one iteration of the loop, so stop. 1997 */ 1998 if (!(_res.options & RES_DNSRCH)) 1999 done++; 2000 } 2001 } 2002 2003 /* 2004 * if we have not already tried the name "as is", do that now. 2005 * note that we do this regardless of how many dots were in the 2006 * name or whether it ends with a dot. 2007 */ 2008 if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) { 2009 ret = res_querydomainN(name, NULL, target); 2010 if (ret > 0) 2011 return (ret); 2012 } 2013 2014 /* 2015 * if we got here, we didn't satisfy the search. 2016 * if we did an initial full query, return that query's h_errno 2017 * (note that we wouldn't be here if that query had succeeded). 2018 * else if we ever got a nodata, send that back as the reason. 2019 * else send back meaningless h_errno, that being the one from 2020 * the last DNSRCH we did. 2021 */ 2022 if (saved_herrno != -1) 2023 h_errno = saved_herrno; 2024 else if (got_nodata) 2025 h_errno = NO_DATA; 2026 else if (got_servfail) 2027 h_errno = TRY_AGAIN; 2028 return (-1); 2029 } 2030 2031 /* 2032 * Perform a call on res_query on the concatenation of name and domain, 2033 * removing a trailing dot from name if domain is NULL. 2034 */ 2035 static int 2036 res_querydomainN(name, domain, target) 2037 const char *name, *domain; 2038 struct res_target *target; 2039 { 2040 char nbuf[MAXDNAME]; 2041 const char *longname = nbuf; 2042 size_t n, d; 2043 2044 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 2045 h_errno = NETDB_INTERNAL; 2046 return (-1); 2047 } 2048 #ifdef DEBUG 2049 if (_res.options & RES_DEBUG) 2050 printf(";; res_querydomain(%s, %s)\n", 2051 name, domain?domain:"<Nil>"); 2052 #endif 2053 if (domain == NULL) { 2054 /* 2055 * Check for trailing '.'; 2056 * copy without '.' if present. 2057 */ 2058 n = strlen(name); 2059 if (n >= MAXDNAME) { 2060 h_errno = NO_RECOVERY; 2061 return (-1); 2062 } 2063 if (n > 0 && name[--n] == '.') { 2064 strncpy(nbuf, name, n); 2065 nbuf[n] = '\0'; 2066 } else 2067 longname = name; 2068 } else { 2069 n = strlen(name); 2070 d = strlen(domain); 2071 if (n + d + 1 >= MAXDNAME) { 2072 h_errno = NO_RECOVERY; 2073 return (-1); 2074 } 2075 snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain); 2076 } 2077 return (res_queryN(longname, target)); 2078 } 2079