Deleted Added
full compact
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 ---