lookup_name.c 11 KB

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