getaddrinfo.c (121425) | getaddrinfo.c (121426) |
---|---|
1/* $KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 49 unchanged lines hidden (view full) --- 58 * presented above. 59 * 60 * OS specific notes for freebsd4: 61 * - FreeBSD supported $GAI. The code does not. 62 * - FreeBSD allowed classful IPv4 numeric (127.1), the code does not. 63 */ 64 65#include <sys/cdefs.h> | 1/* $KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 49 unchanged lines hidden (view full) --- 58 * presented above. 59 * 60 * OS specific notes for freebsd4: 61 * - FreeBSD supported $GAI. The code does not. 62 * - FreeBSD allowed classful IPv4 numeric (127.1), the code does not. 63 */ 64 65#include <sys/cdefs.h> |
66__FBSDID("$FreeBSD: head/lib/libc/net/getaddrinfo.c 121425 2003-10-23 13:55:36Z ume $"); | 66__FBSDID("$FreeBSD: head/lib/libc/net/getaddrinfo.c 121426 2003-10-23 14:32:03Z ume $"); |
67 68#include "namespace.h" 69#include <sys/types.h> 70#include <sys/param.h> 71#include <sys/socket.h> 72#include <net/if.h> 73#include <netinet/in.h> 74#include <arpa/inet.h> --- 105 unchanged lines hidden (view full) --- 180#endif 181 182static const ns_src default_dns_files[] = { 183 { NSSRC_FILES, NS_SUCCESS }, 184 { NSSRC_DNS, NS_SUCCESS }, 185 { 0 } 186}; 187 | 67 68#include "namespace.h" 69#include <sys/types.h> 70#include <sys/param.h> 71#include <sys/socket.h> 72#include <net/if.h> 73#include <netinet/in.h> 74#include <arpa/inet.h> --- 105 unchanged lines hidden (view full) --- 180#endif 181 182static const ns_src default_dns_files[] = { 183 { NSSRC_FILES, NS_SUCCESS }, 184 { NSSRC_DNS, NS_SUCCESS }, 185 { 0 } 186}; 187 |
188#define MAXPACKET (64*1024) 189 190typedef union { 191 HEADER hdr; 192 u_char buf[MAXPACKET]; 193} querybuf; 194 | |
195struct res_target { 196 struct res_target *next; 197 const char *name; /* domain name */ 198 int qclass, qtype; /* class and type of query */ 199 u_char *answer; /* buffer to put answer */ 200 int anslen; /* size of answer buffer */ 201 int n; /* result length */ 202}; 203 | 188struct res_target { 189 struct res_target *next; 190 const char *name; /* domain name */ 191 int qclass, qtype; /* class and type of query */ 192 u_char *answer; /* buffer to put answer */ 193 int anslen; /* size of answer buffer */ 194 int n; /* result length */ 195}; 196 |
197#define MAXPACKET (64*1024) 198 199typedef union { 200 HEADER hdr; 201 u_char buf[MAXPACKET]; 202} querybuf; 203 |
|
204static int str_isnumber(const char *); | 204static int str_isnumber(const char *); |
205static int explore_fqdn(const struct addrinfo *, const char *, 206 const char *, struct addrinfo **); | |
207static int explore_null(const struct addrinfo *, 208 const char *, struct addrinfo **); 209static int explore_numeric(const struct addrinfo *, const char *, 210 const char *, struct addrinfo **); 211static int explore_numeric_scope(const struct addrinfo *, const char *, 212 const char *, struct addrinfo **); 213static int get_canonname(const struct addrinfo *, 214 struct addrinfo *, const char *); 215static struct addrinfo *get_ai(const struct addrinfo *, 216 const struct afd *, const char *); 217static int get_portmatch(const struct addrinfo *, const char *); 218static int get_port(struct addrinfo *, const char *, int); 219static const struct afd *find_afd(int); 220static int addrconfig(struct addrinfo *); 221#ifdef INET6 222static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *); 223#endif 224 | 205static int explore_null(const struct addrinfo *, 206 const char *, struct addrinfo **); 207static int explore_numeric(const struct addrinfo *, const char *, 208 const char *, struct addrinfo **); 209static int explore_numeric_scope(const struct addrinfo *, const char *, 210 const char *, struct addrinfo **); 211static int get_canonname(const struct addrinfo *, 212 struct addrinfo *, const char *); 213static struct addrinfo *get_ai(const struct addrinfo *, 214 const struct afd *, const char *); 215static int get_portmatch(const struct addrinfo *, const char *); 216static int get_port(struct addrinfo *, const char *, int); 217static const struct afd *find_afd(int); 218static int addrconfig(struct addrinfo *); 219#ifdef INET6 220static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *); 221#endif 222 |
223static int explore_fqdn(const struct addrinfo *, const char *, 224 const char *, struct addrinfo **); 225 |
|
225static struct addrinfo *getanswer(const querybuf *, int, const char *, int, 226 const struct addrinfo *); | 226static struct addrinfo *getanswer(const querybuf *, int, const char *, int, 227 const struct addrinfo *); |
228#if defined(RESOLVSORT) 229static int addr4sort(struct addrinfo *); 230#endif |
|
227static int _dns_getaddrinfo(void *, void *, va_list); 228static void _sethtent(void); 229static void _endhtent(void); 230static struct addrinfo *_gethtent(const char *, const struct addrinfo *); 231static int _files_getaddrinfo(void *, void *, va_list); 232#ifdef YP 233static struct addrinfo *_yphostent(char *, const struct addrinfo *); 234static int _yp_getaddrinfo(void *, void *, va_list); --- 342 unchanged lines hidden (view full) --- 577 bad: 578 if (sentinel.ai_next) 579 freeaddrinfo(sentinel.ai_next); 580 *res = NULL; 581 return error; 582} 583 584/* | 231static int _dns_getaddrinfo(void *, void *, va_list); 232static void _sethtent(void); 233static void _endhtent(void); 234static struct addrinfo *_gethtent(const char *, const struct addrinfo *); 235static int _files_getaddrinfo(void *, void *, va_list); 236#ifdef YP 237static struct addrinfo *_yphostent(char *, const struct addrinfo *); 238static int _yp_getaddrinfo(void *, void *, va_list); --- 342 unchanged lines hidden (view full) --- 581 bad: 582 if (sentinel.ai_next) 583 freeaddrinfo(sentinel.ai_next); 584 *res = NULL; 585 return error; 586} 587 588/* |
585 * FQDN hostname, DNS lookup 586 */ 587static int 588explore_fqdn(pai, hostname, servname, res) 589 const struct addrinfo *pai; 590 const char *hostname; 591 const char *servname; 592 struct addrinfo **res; 593{ 594 struct addrinfo *result; 595 struct addrinfo *cur; 596 int error = 0; 597 static const ns_dtab dtab[] = { 598 NS_FILES_CB(_files_getaddrinfo, NULL) 599 { NSSRC_DNS, _dns_getaddrinfo, NULL }, /* force -DHESIOD */ 600 NS_NIS_CB(_yp_getaddrinfo, NULL) 601 { 0 } 602 }; 603 604 result = NULL; 605 606 THREAD_LOCK(); 607 608 /* 609 * if the servname does not match socktype/protocol, ignore it. 610 */ 611 if (get_portmatch(pai, servname) != 0) { 612 THREAD_UNLOCK(); 613 return 0; 614 } 615 616 switch (_nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo", 617 default_dns_files, hostname, pai)) { 618 case NS_TRYAGAIN: 619 error = EAI_AGAIN; 620 goto free; 621 case NS_UNAVAIL: 622 error = EAI_FAIL; 623 goto free; 624 case NS_NOTFOUND: 625 error = EAI_NONAME; 626 goto free; 627 case NS_SUCCESS: 628 error = 0; 629 for (cur = result; cur; cur = cur->ai_next) { 630 GET_PORT(cur, servname); 631 /* canonname should be filled already */ 632 } 633 break; 634 } 635 THREAD_UNLOCK(); 636 637 *res = result; 638 639 return 0; 640 641free: 642 THREAD_UNLOCK(); 643 if (result) 644 freeaddrinfo(result); 645 return error; 646} 647 648/* | |
649 * hostname == NULL. 650 * passive socket -> anyaddr (0.0.0.0 or ::) 651 * non-passive socket -> localhost (127.0.0.1 or ::1) 652 */ 653static int 654explore_null(pai, servname, res) 655 const struct addrinfo *pai; 656 const char *servname; --- 472 unchanged lines hidden (view full) --- 1129 *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL); 1130 if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid) 1131 return 0; 1132 else 1133 return -1; 1134} 1135#endif 1136 | 589 * hostname == NULL. 590 * passive socket -> anyaddr (0.0.0.0 or ::) 591 * non-passive socket -> localhost (127.0.0.1 or ::1) 592 */ 593static int 594explore_null(pai, servname, res) 595 const struct addrinfo *pai; 596 const char *servname; --- 472 unchanged lines hidden (view full) --- 1069 *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL); 1070 if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid) 1071 return 0; 1072 else 1073 return -1; 1074} 1075#endif 1076 |
1137#ifdef RESOLVSORT 1138struct addr_ptr { 1139 struct addrinfo *ai; 1140 int aval; 1141}; 1142 | 1077/* 1078 * FQDN hostname, DNS lookup 1079 */ |
1143static int | 1080static int |
1144addr4sort(struct addrinfo *sentinel) | 1081explore_fqdn(pai, hostname, servname, res) 1082 const struct addrinfo *pai; 1083 const char *hostname; 1084 const char *servname; 1085 struct addrinfo **res; |
1145{ | 1086{ |
1146 struct addrinfo *ai; 1147 struct addr_ptr *addrs, addr; 1148 struct sockaddr_in *sin; 1149 int naddrs, i, j; 1150 int needsort = 0; | 1087 struct addrinfo *result; 1088 struct addrinfo *cur; 1089 int error = 0; 1090 static const ns_dtab dtab[] = { 1091 NS_FILES_CB(_files_getaddrinfo, NULL) 1092 { NSSRC_DNS, _dns_getaddrinfo, NULL }, /* force -DHESIOD */ 1093 NS_NIS_CB(_yp_getaddrinfo, NULL) 1094 { 0 } 1095 }; |
1151 | 1096 |
1152 if (!sentinel) 1153 return -1; 1154 naddrs = 0; 1155 for (ai = sentinel->ai_next; ai; ai = ai->ai_next) 1156 naddrs++; 1157 if (naddrs < 2) 1158 return 0; /* We don't need sorting. */ 1159 if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL) 1160 return -1; 1161 i = 0; 1162 for (ai = sentinel->ai_next; ai; ai = ai->ai_next) { 1163 sin = (struct sockaddr_in *)ai->ai_addr; 1164 for (j = 0; (unsigned)j < _res.nsort; j++) { 1165 if (_res.sort_list[j].addr.s_addr == 1166 (sin->sin_addr.s_addr & _res.sort_list[j].mask)) 1167 break; 1168 } 1169 addrs[i].ai = ai; 1170 addrs[i].aval = j; 1171 if (needsort == 0 && i > 0 && j < addrs[i - 1].aval) 1172 needsort = i; 1173 i++; 1174 } 1175 if (!needsort) { 1176 free(addrs); | 1097 result = NULL; 1098 1099 THREAD_LOCK(); 1100 1101 /* 1102 * if the servname does not match socktype/protocol, ignore it. 1103 */ 1104 if (get_portmatch(pai, servname) != 0) { 1105 THREAD_UNLOCK(); |
1177 return 0; 1178 } 1179 | 1106 return 0; 1107 } 1108 |
1180 while (needsort < naddrs) { 1181 for (j = needsort - 1; j >= 0; j--) { 1182 if (addrs[j].aval > addrs[j+1].aval) { 1183 addr = addrs[j]; 1184 addrs[j] = addrs[j + 1]; 1185 addrs[j + 1] = addr; 1186 } else 1187 break; 1188 } 1189 needsort++; | 1109 switch (_nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo", 1110 default_dns_files, hostname, pai)) { 1111 case NS_TRYAGAIN: 1112 error = EAI_AGAIN; 1113 goto free; 1114 case NS_UNAVAIL: 1115 error = EAI_FAIL; 1116 goto free; 1117 case NS_NOTFOUND: 1118 error = EAI_NONAME; 1119 goto free; 1120 case NS_SUCCESS: 1121 error = 0; 1122 for (cur = result; cur; cur = cur->ai_next) { 1123 GET_PORT(cur, servname); 1124 /* canonname should be filled already */ 1125 } 1126 break; |
1190 } | 1127 } |
1128 THREAD_UNLOCK(); |
|
1191 | 1129 |
1192 ai = sentinel; 1193 for (i = 0; i < naddrs; ++i) { 1194 ai->ai_next = addrs[i].ai; 1195 ai = ai->ai_next; 1196 } 1197 ai->ai_next = NULL; 1198 free(addrs); | 1130 *res = result; 1131 |
1199 return 0; | 1132 return 0; |
1133 1134free: 1135 THREAD_UNLOCK(); 1136 if (result) 1137 freeaddrinfo(result); 1138 return error; |
|
1200} | 1139} |
1201#endif /*RESOLVSORT*/ | |
1202 1203#ifdef DEBUG 1204static const char AskedForGot[] = 1205 "gethostby*.getanswer: asked for \"%s\", got \"%s\""; 1206#endif 1207static FILE *hostf = NULL; 1208 1209static struct addrinfo * --- 201 unchanged lines hidden (view full) --- 1411 h_errno = NETDB_SUCCESS; 1412 return sentinel.ai_next; 1413 } 1414 1415 h_errno = NO_RECOVERY; 1416 return NULL; 1417} 1418 | 1140 1141#ifdef DEBUG 1142static const char AskedForGot[] = 1143 "gethostby*.getanswer: asked for \"%s\", got \"%s\""; 1144#endif 1145static FILE *hostf = NULL; 1146 1147static struct addrinfo * --- 201 unchanged lines hidden (view full) --- 1349 h_errno = NETDB_SUCCESS; 1350 return sentinel.ai_next; 1351 } 1352 1353 h_errno = NO_RECOVERY; 1354 return NULL; 1355} 1356 |
1357#ifdef RESOLVSORT 1358struct addr_ptr { 1359 struct addrinfo *ai; 1360 int aval; 1361}; 1362 1363static int 1364addr4sort(struct addrinfo *sentinel) 1365{ 1366 struct addrinfo *ai; 1367 struct addr_ptr *addrs, addr; 1368 struct sockaddr_in *sin; 1369 int naddrs, i, j; 1370 int needsort = 0; 1371 1372 if (!sentinel) 1373 return -1; 1374 naddrs = 0; 1375 for (ai = sentinel->ai_next; ai; ai = ai->ai_next) 1376 naddrs++; 1377 if (naddrs < 2) 1378 return 0; /* We don't need sorting. */ 1379 if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL) 1380 return -1; 1381 i = 0; 1382 for (ai = sentinel->ai_next; ai; ai = ai->ai_next) { 1383 sin = (struct sockaddr_in *)ai->ai_addr; 1384 for (j = 0; (unsigned)j < _res.nsort; j++) { 1385 if (_res.sort_list[j].addr.s_addr == 1386 (sin->sin_addr.s_addr & _res.sort_list[j].mask)) 1387 break; 1388 } 1389 addrs[i].ai = ai; 1390 addrs[i].aval = j; 1391 if (needsort == 0 && i > 0 && j < addrs[i - 1].aval) 1392 needsort = i; 1393 i++; 1394 } 1395 if (!needsort) { 1396 free(addrs); 1397 return 0; 1398 } 1399 1400 while (needsort < naddrs) { 1401 for (j = needsort - 1; j >= 0; j--) { 1402 if (addrs[j].aval > addrs[j+1].aval) { 1403 addr = addrs[j]; 1404 addrs[j] = addrs[j + 1]; 1405 addrs[j + 1] = addr; 1406 } else 1407 break; 1408 } 1409 needsort++; 1410 } 1411 1412 ai = sentinel; 1413 for (i = 0; i < naddrs; ++i) { 1414 ai->ai_next = addrs[i].ai; 1415 ai = ai->ai_next; 1416 } 1417 ai->ai_next = NULL; 1418 free(addrs); 1419 return 0; 1420} 1421#endif /*RESOLVSORT*/ 1422 |
|
1419/*ARGSUSED*/ 1420static int 1421_dns_getaddrinfo(rv, cb_data, ap) 1422 void *rv; 1423 void *cb_data; 1424 va_list ap; 1425{ 1426 struct addrinfo *ai; --- 682 unchanged lines hidden --- | 1423/*ARGSUSED*/ 1424static int 1425_dns_getaddrinfo(rv, cb_data, ap) 1426 void *rv; 1427 void *cb_data; 1428 va_list ap; 1429{ 1430 struct addrinfo *ai; --- 682 unchanged lines hidden --- |