lookup_name.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. #include <sys/socket.h>
  2. #include <netinet/in.h>
  3. #include <netdb.h>
  4. #include <net/if.h>
  5. #include <arpa/inet.h>
  6. #include <ctype.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <fcntl.h>
  10. #include <unistd.h>
  11. #include <pthread.h>
  12. #include <errno.h>
  13. #include <resolv.h>
  14. #include "lookup.h"
  15. #include "stdio_impl.h"
  16. #include "syscall.h"
  17. static int is_valid_hostname(const char *host)
  18. {
  19. const unsigned char *s;
  20. if (strnlen(host, 255)-1 >= 254 || mbstowcs(0, host, 0) == -1) return 0;
  21. for (s=(void *)host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++);
  22. return !*s;
  23. }
  24. static int name_from_null(struct address buf[static 2], const char *name, int family, int flags)
  25. {
  26. int cnt = 0;
  27. if (name) return 0;
  28. if (flags & AI_PASSIVE) {
  29. if (family != AF_INET6)
  30. buf[cnt++] = (struct address){ .family = AF_INET };
  31. if (family != AF_INET)
  32. buf[cnt++] = (struct address){ .family = AF_INET6 };
  33. } else {
  34. if (family != AF_INET6)
  35. buf[cnt++] = (struct address){ .family = AF_INET, .addr = { 127,0,0,1 } };
  36. if (family != AF_INET)
  37. buf[cnt++] = (struct address){ .family = AF_INET6, .addr = { [15] = 1 } };
  38. }
  39. return cnt;
  40. }
  41. static int name_from_numeric(struct address buf[static 1], const char *name, int family)
  42. {
  43. return __lookup_ipliteral(buf, name, family);
  44. }
  45. static int name_from_hosts(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
  46. {
  47. char line[512];
  48. size_t l = strlen(name);
  49. int cnt = 0, badfam = 0;
  50. unsigned char _buf[1032];
  51. FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
  52. if (!f) switch (errno) {
  53. case ENOENT:
  54. case ENOTDIR:
  55. case EACCES:
  56. return 0;
  57. default:
  58. return EAI_SYSTEM;
  59. }
  60. while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
  61. char *p, *z;
  62. if ((p=strchr(line, '#'))) *p++='\n', *p=0;
  63. for(p=line+1; (p=strstr(p, name)) &&
  64. (!isspace(p[-1]) || !isspace(p[l])); p++);
  65. if (!p) continue;
  66. /* Isolate IP address to parse */
  67. for (p=line; *p && !isspace(*p); p++);
  68. *p++ = 0;
  69. switch (name_from_numeric(buf+cnt, line, family)) {
  70. case 1:
  71. cnt++;
  72. break;
  73. case 0:
  74. continue;
  75. default:
  76. badfam = EAI_NONAME;
  77. continue;
  78. }
  79. /* Extract first name as canonical name */
  80. for (; *p && isspace(*p); p++);
  81. for (z=p; *z && !isspace(*z); z++);
  82. *z = 0;
  83. if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
  84. }
  85. __fclose_ca(f);
  86. return cnt ? cnt : badfam;
  87. }
  88. struct dpc_ctx {
  89. struct address *addrs;
  90. char *canon;
  91. int cnt;
  92. };
  93. #define RR_A 1
  94. #define RR_CNAME 5
  95. #define RR_AAAA 28
  96. static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
  97. {
  98. char tmp[256];
  99. struct dpc_ctx *ctx = c;
  100. if (ctx->cnt >= MAXADDRS) return -1;
  101. switch (rr) {
  102. case RR_A:
  103. if (len != 4) return -1;
  104. ctx->addrs[ctx->cnt].family = AF_INET;
  105. ctx->addrs[ctx->cnt].scopeid = 0;
  106. memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
  107. break;
  108. case RR_AAAA:
  109. if (len != 16) return -1;
  110. ctx->addrs[ctx->cnt].family = AF_INET6;
  111. ctx->addrs[ctx->cnt].scopeid = 0;
  112. memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
  113. break;
  114. case RR_CNAME:
  115. if (__dn_expand(packet, (const unsigned char *)packet + 512,
  116. data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
  117. strcpy(ctx->canon, tmp);
  118. break;
  119. }
  120. return 0;
  121. }
  122. static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
  123. {
  124. unsigned char qbuf[2][280], abuf[2][512];
  125. const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
  126. unsigned char *ap[2] = { abuf[0], abuf[1] };
  127. int qlens[2], alens[2];
  128. int i, nq = 0;
  129. struct dpc_ctx ctx = { .addrs = buf, .canon = canon };
  130. static const struct { int af; int rr; } afrr[2] = {
  131. { .af = AF_INET6, .rr = RR_A },
  132. { .af = AF_INET, .rr = RR_AAAA },
  133. };
  134. for (i=0; i<2; i++) {
  135. if (family != afrr[i].af) {
  136. qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr,
  137. 0, 0, 0, qbuf[nq], sizeof *qbuf);
  138. if (qlens[nq] == -1)
  139. return EAI_NONAME;
  140. nq++;
  141. }
  142. }
  143. if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
  144. return EAI_SYSTEM;
  145. for (i=0; i<nq; i++)
  146. __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
  147. if (ctx.cnt) return ctx.cnt;
  148. if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
  149. if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
  150. if ((abuf[0][3] & 15) == 3) return 0;
  151. return EAI_FAIL;
  152. }
  153. static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
  154. {
  155. char search[256];
  156. struct resolvconf conf;
  157. size_t l, dots;
  158. char *p, *z;
  159. if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1;
  160. /* Count dots, suppress search when >=ndots or name ends in
  161. * a dot, which is an explicit request for global scope. */
  162. for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++;
  163. if (dots >= conf.ndots || name[l-1]=='.') *search = 0;
  164. /* Strip final dot for canon, fail if multiple trailing dots. */
  165. if (name[l-1]=='.') l--;
  166. if (!l || name[l-1]=='.') return EAI_NONAME;
  167. /* This can never happen; the caller already checked length. */
  168. if (l >= 256) return EAI_NONAME;
  169. /* Name with search domain appended is setup in canon[]. This both
  170. * provides the desired default canonical name (if the requested
  171. * name is not a CNAME record) and serves as a buffer for passing
  172. * the full requested name to name_from_dns. */
  173. memcpy(canon, name, l);
  174. canon[l] = '.';
  175. for (p=search; *p; p=z) {
  176. for (; isspace(*p); p++);
  177. for (z=p; *z && !isspace(*z); z++);
  178. if (z==p) break;
  179. if (z-p < 256 - l - 1) {
  180. memcpy(canon+l+1, p, z-p);
  181. canon[z-p+1+l] = 0;
  182. int cnt = name_from_dns(buf, canon, canon, family, &conf);
  183. if (cnt) return cnt;
  184. }
  185. }
  186. canon[l] = 0;
  187. return name_from_dns(buf, canon, name, family, &conf);
  188. }
  189. static const struct policy {
  190. unsigned char addr[16];
  191. unsigned char len, mask;
  192. unsigned char prec, label;
  193. } defpolicy[] = {
  194. { "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 15, 0xff, 50, 0 },
  195. { "\0\0\0\0\0\0\0\0\0\0\xff\xff", 11, 0xff, 35, 4 },
  196. { "\x20\2", 1, 0xff, 30, 2 },
  197. { "\x20\1", 3, 0xff, 5, 5 },
  198. { "\xfc", 0, 0xfe, 3, 13 },
  199. #if 0
  200. /* These are deprecated and/or returned to the address
  201. * pool, so despite the RFC, treating them as special
  202. * is probably wrong. */
  203. { "", 11, 0xff, 1, 3 },
  204. { "\xfe\xc0", 1, 0xc0, 1, 11 },
  205. { "\x3f\xfe", 1, 0xff, 1, 12 },
  206. #endif
  207. /* Last rule must match all addresses to stop loop. */
  208. { "", 0, 0, 40, 1 },
  209. };
  210. static const struct policy *policyof(const struct in6_addr *a)
  211. {
  212. int i;
  213. for (i=0; ; i++) {
  214. if (memcmp(a->s6_addr, defpolicy[i].addr, defpolicy[i].len))
  215. continue;
  216. if ((a->s6_addr[defpolicy[i].len] & defpolicy[i].mask)
  217. != defpolicy[i].addr[defpolicy[i].len])
  218. continue;
  219. return defpolicy+i;
  220. }
  221. }
  222. static int labelof(const struct in6_addr *a)
  223. {
  224. return policyof(a)->label;
  225. }
  226. static int scopeof(const struct in6_addr *a)
  227. {
  228. if (IN6_IS_ADDR_MULTICAST(a)) return a->s6_addr[1] & 15;
  229. if (IN6_IS_ADDR_LINKLOCAL(a)) return 2;
  230. if (IN6_IS_ADDR_LOOPBACK(a)) return 2;
  231. if (IN6_IS_ADDR_SITELOCAL(a)) return 5;
  232. return 14;
  233. }
  234. static int prefixmatch(const struct in6_addr *s, const struct in6_addr *d)
  235. {
  236. /* FIXME: The common prefix length should be limited to no greater
  237. * than the nominal length of the prefix portion of the source
  238. * address. However the definition of the source prefix length is
  239. * not clear and thus this limiting is not yet implemented. */
  240. unsigned i;
  241. for (i=0; i<128 && !((s->s6_addr[i/8]^d->s6_addr[i/8])&(128>>(i%8))); i++);
  242. return i;
  243. }
  244. #define DAS_USABLE 0x40000000
  245. #define DAS_MATCHINGSCOPE 0x20000000
  246. #define DAS_MATCHINGLABEL 0x10000000
  247. #define DAS_PREC_SHIFT 20
  248. #define DAS_SCOPE_SHIFT 16
  249. #define DAS_PREFIX_SHIFT 8
  250. #define DAS_ORDER_SHIFT 0
  251. static int addrcmp(const void *_a, const void *_b)
  252. {
  253. const struct address *a = _a, *b = _b;
  254. return b->sortkey - a->sortkey;
  255. }
  256. int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)
  257. {
  258. int cnt = 0, i, j;
  259. *canon = 0;
  260. if (name) {
  261. /* reject empty name and check len so it fits into temp bufs */
  262. size_t l = strnlen(name, 255);
  263. if (l-1 >= 254)
  264. return EAI_NONAME;
  265. memcpy(canon, name, l+1);
  266. }
  267. /* Procedurally, a request for v6 addresses with the v4-mapped
  268. * flag set is like a request for unspecified family, followed
  269. * by filtering of the results. */
  270. if (flags & AI_V4MAPPED) {
  271. if (family == AF_INET6) family = AF_UNSPEC;
  272. else flags -= AI_V4MAPPED;
  273. }
  274. /* Try each backend until there's at least one result. */
  275. cnt = name_from_null(buf, name, family, flags);
  276. if (!cnt) cnt = name_from_numeric(buf, name, family);
  277. if (!cnt && !(flags & AI_NUMERICHOST)) {
  278. cnt = name_from_hosts(buf, canon, name, family);
  279. if (!cnt) cnt = name_from_dns_search(buf, canon, name, family);
  280. }
  281. if (cnt<=0) return cnt ? cnt : EAI_NONAME;
  282. /* Filter/transform results for v4-mapped lookup, if requested. */
  283. if (flags & AI_V4MAPPED) {
  284. if (!(flags & AI_ALL)) {
  285. /* If any v6 results exist, remove v4 results. */
  286. for (i=0; i<cnt && buf[i].family != AF_INET6; i++);
  287. if (i<cnt) {
  288. for (j=0; i<cnt; i++) {
  289. if (buf[i].family == AF_INET6)
  290. buf[j++] = buf[i];
  291. }
  292. cnt = i = j;
  293. }
  294. }
  295. /* Translate any remaining v4 results to v6 */
  296. for (i=0; i<cnt; i++) {
  297. if (buf[i].family != AF_INET) continue;
  298. memcpy(buf[i].addr+12, buf[i].addr, 4);
  299. memcpy(buf[i].addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
  300. buf[i].family = AF_INET6;
  301. }
  302. }
  303. /* No further processing is needed if there are fewer than 2
  304. * results or if there are only IPv4 results. */
  305. if (cnt<2 || family==AF_INET) return cnt;
  306. for (i=0; i<cnt; i++) if (buf[i].family != AF_INET) break;
  307. if (i==cnt) return cnt;
  308. int cs;
  309. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  310. /* The following implements a subset of RFC 3484/6724 destination
  311. * address selection by generating a single 31-bit sort key for
  312. * each address. Rules 3, 4, and 7 are omitted for having
  313. * excessive runtime and code size cost and dubious benefit.
  314. * So far the label/precedence table cannot be customized. */
  315. for (i=0; i<cnt; i++) {
  316. int family = buf[i].family;
  317. int key = 0;
  318. struct sockaddr_in6 sa6 = { 0 }, da6 = {
  319. .sin6_family = AF_INET6,
  320. .sin6_scope_id = buf[i].scopeid,
  321. .sin6_port = 65535
  322. };
  323. struct sockaddr_in sa4 = { 0 }, da4 = {
  324. .sin_family = AF_INET,
  325. .sin_port = 65535
  326. };
  327. void *sa, *da;
  328. socklen_t salen, dalen;
  329. if (family == AF_INET6) {
  330. memcpy(da6.sin6_addr.s6_addr, buf[i].addr, 16);
  331. da = &da6; dalen = sizeof da6;
  332. sa = &sa6; salen = sizeof sa6;
  333. } else {
  334. memcpy(sa6.sin6_addr.s6_addr,
  335. "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
  336. memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
  337. memcpy(da6.sin6_addr.s6_addr,
  338. "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
  339. memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
  340. memcpy(&da4.sin_addr, buf[i].addr, 4);
  341. da = &da4; dalen = sizeof da4;
  342. sa = &sa4; salen = sizeof sa4;
  343. }
  344. const struct policy *dpolicy = policyof(&da6.sin6_addr);
  345. int dscope = scopeof(&da6.sin6_addr);
  346. int dlabel = dpolicy->label;
  347. int dprec = dpolicy->prec;
  348. int prefixlen = 0;
  349. int fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP);
  350. if (fd >= 0) {
  351. if (!connect(fd, da, dalen)) {
  352. key |= DAS_USABLE;
  353. if (!getsockname(fd, sa, &salen)) {
  354. if (family == AF_INET) memcpy(
  355. sa6.sin6_addr.s6_addr+12,
  356. &sa4.sin_addr, 4);
  357. if (dscope == scopeof(&sa6.sin6_addr))
  358. key |= DAS_MATCHINGSCOPE;
  359. if (dlabel == labelof(&sa6.sin6_addr))
  360. key |= DAS_MATCHINGLABEL;
  361. prefixlen = prefixmatch(&sa6.sin6_addr,
  362. &da6.sin6_addr);
  363. }
  364. }
  365. close(fd);
  366. }
  367. key |= dprec << DAS_PREC_SHIFT;
  368. key |= (15-dscope) << DAS_SCOPE_SHIFT;
  369. key |= prefixlen << DAS_PREFIX_SHIFT;
  370. key |= (MAXADDRS-i) << DAS_ORDER_SHIFT;
  371. buf[i].sortkey = key;
  372. }
  373. qsort(buf, cnt, sizeof *buf, addrcmp);
  374. pthread_setcancelstate(cs, 0);
  375. return cnt;
  376. }