gethnamaddr.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
  1. /* $NetBSD: gethnamaddr.c,v 1.91 2014/06/19 15:08:18 christos Exp $ */
  2. /*
  3. * ++Copyright++ 1985, 1988, 1993
  4. * -
  5. * Copyright (c) 1985, 1988, 1993
  6. * The Regents of the University of California. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the University nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. * -
  32. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  33. *
  34. * Permission to use, copy, modify, and distribute this software for any
  35. * purpose with or without fee is hereby granted, provided that the above
  36. * copyright notice and this permission notice appear in all copies, and that
  37. * the name of Digital Equipment Corporation not be used in advertising or
  38. * publicity pertaining to distribution of the document or software without
  39. * specific, written prior permission.
  40. *
  41. * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  42. * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  43. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  44. * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  45. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  46. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  47. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  48. * SOFTWARE.
  49. * -
  50. * --Copyright--
  51. */
  52. #include "gethnamaddr.h"
  53. #include <android-base/logging.h>
  54. #include <arpa/inet.h>
  55. #include <arpa/nameser.h>
  56. #include <assert.h>
  57. #include <ctype.h>
  58. #include <errno.h>
  59. #include <netdb.h>
  60. #include <netinet/in.h>
  61. #include <stdarg.h>
  62. #include <stdbool.h>
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #include <sys/param.h>
  67. #include <sys/socket.h>
  68. #include <sys/types.h>
  69. #include <sys/un.h>
  70. #include <unistd.h>
  71. #include <functional>
  72. #include <vector>
  73. #include "hostent.h"
  74. #include "netd_resolv/resolv.h"
  75. #include "resolv_cache.h"
  76. #include "resolv_private.h"
  77. #include "stats.pb.h"
  78. using android::net::NetworkDnsEventReported;
  79. // NetBSD uses _DIAGASSERT to null-check arguments and the like,
  80. // but it's clear from the number of mistakes in their assertions
  81. // that they don't actually test or ship with this.
  82. #define _DIAGASSERT(e) /* nothing */
  83. // TODO: unify macro ALIGNBYTES and ALIGN for all possible data type alignment of hostent
  84. // buffer.
  85. #define ALIGNBYTES (sizeof(uintptr_t) - 1)
  86. #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)
  87. #define maybe_ok(res, nm, ok) (((res)->options & RES_NOCHECKNAME) != 0U || (ok)(nm) != 0)
  88. #define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
  89. #define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
  90. #define MAXPACKET (8 * 1024)
  91. typedef union {
  92. HEADER hdr;
  93. u_char buf[MAXPACKET];
  94. } querybuf;
  95. typedef union {
  96. int32_t al;
  97. char ac;
  98. } align;
  99. static struct hostent* getanswer(const querybuf*, int, const char*, int, res_state, struct hostent*,
  100. char*, size_t, int*);
  101. static void convert_v4v6_hostent(struct hostent* hp, char** bpp, char* ep,
  102. std::function<void(struct hostent* hp)> mapping_param,
  103. std::function<void(char* src, char* dst)> mapping_addr);
  104. static void map_v4v6_address(const char*, char*);
  105. static void map_v4v6_hostent(struct hostent*, char**, char*);
  106. static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep);
  107. static void addrsort(char**, int, res_state);
  108. static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
  109. const android_net_context* netcontext, getnamaddr* info,
  110. NetworkDnsEventReported* event);
  111. static int dns_gethtbyname(const char* name, int af, getnamaddr* info);
  112. static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
  113. size_t hbuflen, const android_net_context* netcontext,
  114. NetworkDnsEventReported* event);
  115. static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
  116. char* buf, size_t buflen);
  117. static int android_gethostbyaddrfornetcontext_proxy_internal(const void*, socklen_t, int,
  118. struct hostent*, char*, size_t,
  119. const struct android_net_context*,
  120. NetworkDnsEventReported* event);
  121. static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
  122. const struct android_net_context* netcontext,
  123. hostent** hp, NetworkDnsEventReported* event);
  124. #define BOUNDED_INCR(x) \
  125. do { \
  126. BOUNDS_CHECK(cp, x); \
  127. cp += (x); \
  128. } while (0)
  129. #define BOUNDS_CHECK(ptr, count) \
  130. do { \
  131. if (eom - (ptr) < (count)) goto no_recovery; \
  132. } while (0)
  133. static struct hostent* getanswer(const querybuf* answer, int anslen, const char* qname, int qtype,
  134. res_state res, struct hostent* hent, char* buf, size_t buflen,
  135. int* he) {
  136. const HEADER* hp;
  137. const u_char* cp;
  138. int n;
  139. size_t qlen;
  140. const u_char *eom, *erdata;
  141. char *bp, **hap, *ep;
  142. int ancount, qdcount;
  143. int haveanswer, had_error;
  144. int toobig = 0;
  145. char tbuf[MAXDNAME];
  146. char* addr_ptrs[MAXADDRS];
  147. const char* tname;
  148. int (*name_ok)(const char*);
  149. std::vector<char*> aliases;
  150. _DIAGASSERT(answer != NULL);
  151. _DIAGASSERT(qname != NULL);
  152. tname = qname;
  153. hent->h_name = NULL;
  154. eom = answer->buf + anslen;
  155. switch (qtype) {
  156. case T_A:
  157. case T_AAAA:
  158. name_ok = res_hnok;
  159. break;
  160. case T_PTR:
  161. name_ok = res_dnok;
  162. break;
  163. default:
  164. *he = NO_RECOVERY;
  165. return NULL; /* XXX should be abort(); */
  166. }
  167. /*
  168. * find first satisfactory answer
  169. */
  170. hp = &answer->hdr;
  171. ancount = ntohs(hp->ancount);
  172. qdcount = ntohs(hp->qdcount);
  173. bp = buf;
  174. ep = buf + buflen;
  175. cp = answer->buf;
  176. BOUNDED_INCR(HFIXEDSZ);
  177. if (qdcount != 1) goto no_recovery;
  178. n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
  179. if ((n < 0) || !maybe_ok(res, bp, name_ok)) goto no_recovery;
  180. BOUNDED_INCR(n + QFIXEDSZ);
  181. if (qtype == T_A || qtype == T_AAAA) {
  182. /* res_send() has already verified that the query name is the
  183. * same as the one we sent; this just gets the expanded name
  184. * (i.e., with the succeeding search-domain tacked on).
  185. */
  186. n = (int) strlen(bp) + 1; /* for the \0 */
  187. if (n >= MAXHOSTNAMELEN) goto no_recovery;
  188. hent->h_name = bp;
  189. bp += n;
  190. /* The qname can be abbreviated, but h_name is now absolute. */
  191. qname = hent->h_name;
  192. }
  193. hent->h_addr_list = hap = addr_ptrs;
  194. *hap = NULL;
  195. haveanswer = 0;
  196. had_error = 0;
  197. while (ancount-- > 0 && cp < eom && !had_error) {
  198. n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
  199. if ((n < 0) || !maybe_ok(res, bp, name_ok)) {
  200. had_error++;
  201. continue;
  202. }
  203. cp += n; /* name */
  204. BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
  205. int type = ntohs(*reinterpret_cast<const uint16_t*>(cp));
  206. cp += INT16SZ; /* type */
  207. int cl = ntohs(*reinterpret_cast<const uint16_t*>(cp));
  208. cp += INT16SZ + INT32SZ; /* class, TTL */
  209. n = ntohs(*reinterpret_cast<const uint16_t*>(cp));
  210. cp += INT16SZ; /* len */
  211. BOUNDS_CHECK(cp, n);
  212. erdata = cp + n;
  213. if (cl != C_IN) {
  214. /* XXX - debug? syslog? */
  215. cp += n;
  216. continue; /* XXX - had_error++ ? */
  217. }
  218. if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
  219. n = dn_expand(answer->buf, eom, cp, tbuf, (int) sizeof tbuf);
  220. if ((n < 0) || !maybe_ok(res, tbuf, name_ok)) {
  221. had_error++;
  222. continue;
  223. }
  224. cp += n;
  225. if (cp != erdata) goto no_recovery;
  226. /* Store alias. */
  227. aliases.push_back(bp);
  228. n = (int) strlen(bp) + 1; /* for the \0 */
  229. if (n >= MAXHOSTNAMELEN) {
  230. had_error++;
  231. continue;
  232. }
  233. bp += n;
  234. /* Get canonical name. */
  235. n = (int) strlen(tbuf) + 1; /* for the \0 */
  236. if (n > ep - bp || n >= MAXHOSTNAMELEN) {
  237. had_error++;
  238. continue;
  239. }
  240. strlcpy(bp, tbuf, (size_t)(ep - bp));
  241. hent->h_name = bp;
  242. bp += n;
  243. continue;
  244. }
  245. if (qtype == T_PTR && type == T_CNAME) {
  246. n = dn_expand(answer->buf, eom, cp, tbuf, (int) sizeof tbuf);
  247. if (n < 0 || !maybe_dnok(res, tbuf)) {
  248. had_error++;
  249. continue;
  250. }
  251. cp += n;
  252. if (cp != erdata) goto no_recovery;
  253. /* Get canonical name. */
  254. n = (int) strlen(tbuf) + 1; /* for the \0 */
  255. if (n > ep - bp || n >= MAXHOSTNAMELEN) {
  256. had_error++;
  257. continue;
  258. }
  259. strlcpy(bp, tbuf, (size_t)(ep - bp));
  260. tname = bp;
  261. bp += n;
  262. continue;
  263. }
  264. if (type != qtype) {
  265. if (type != T_KEY && type != T_SIG)
  266. LOG(DEBUG) << __func__ << ": asked for \"" << qname << " " << p_class(C_IN) << " "
  267. << p_type(qtype) << "\", got type \"" << p_type(type) << "\"";
  268. cp += n;
  269. continue; /* XXX - had_error++ ? */
  270. }
  271. switch (type) {
  272. case T_PTR:
  273. if (strcasecmp(tname, bp) != 0) {
  274. LOG(DEBUG) << __func__ << ": asked for \"" << qname << "\", got \"" << bp
  275. << "\"";
  276. cp += n;
  277. continue; /* XXX - had_error++ ? */
  278. }
  279. n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
  280. if ((n < 0) || !maybe_hnok(res, bp)) {
  281. had_error++;
  282. break;
  283. }
  284. cp += n;
  285. if (cp != erdata) goto no_recovery;
  286. if (!haveanswer)
  287. hent->h_name = bp;
  288. else
  289. aliases.push_back(bp);
  290. if (n != -1) {
  291. n = (int) strlen(bp) + 1; /* for the \0 */
  292. if (n >= MAXHOSTNAMELEN) {
  293. had_error++;
  294. break;
  295. }
  296. bp += n;
  297. }
  298. break;
  299. case T_A:
  300. case T_AAAA:
  301. if (strcasecmp(hent->h_name, bp) != 0) {
  302. LOG(DEBUG) << __func__ << ": asked for \"" << hent->h_name << "\", got \"" << bp
  303. << "\"";
  304. cp += n;
  305. continue; /* XXX - had_error++ ? */
  306. }
  307. if (n != hent->h_length) {
  308. cp += n;
  309. continue;
  310. }
  311. if (type == T_AAAA) {
  312. struct in6_addr in6;
  313. memcpy(&in6, cp, NS_IN6ADDRSZ);
  314. if (IN6_IS_ADDR_V4MAPPED(&in6)) {
  315. cp += n;
  316. continue;
  317. }
  318. }
  319. if (!haveanswer) {
  320. int nn;
  321. hent->h_name = bp;
  322. nn = (int) strlen(bp) + 1; /* for the \0 */
  323. bp += nn;
  324. }
  325. bp += sizeof(align) - (size_t)((u_long) bp % sizeof(align));
  326. if (bp + n >= ep) {
  327. LOG(DEBUG) << __func__ << ": size (" << n << ") too big";
  328. had_error++;
  329. continue;
  330. }
  331. if (hap >= &addr_ptrs[MAXADDRS - 1]) {
  332. if (!toobig++) {
  333. LOG(DEBUG) << __func__ << ": Too many addresses (" << MAXADDRS << ")";
  334. }
  335. cp += n;
  336. continue;
  337. }
  338. (void) memcpy(*hap++ = bp, cp, (size_t) n);
  339. bp += n;
  340. cp += n;
  341. if (cp != erdata) goto no_recovery;
  342. break;
  343. default:
  344. abort();
  345. }
  346. if (!had_error) haveanswer++;
  347. }
  348. if (haveanswer) {
  349. *hap = NULL;
  350. /*
  351. * Note: we sort even if host can take only one address
  352. * in its return structures - should give it the "best"
  353. * address in that case, not some random one
  354. */
  355. if (res->nsort && haveanswer > 1 && qtype == T_A) addrsort(addr_ptrs, haveanswer, res);
  356. if (!hent->h_name) {
  357. n = (int) strlen(qname) + 1; /* for the \0 */
  358. if (n > ep - bp || n >= MAXHOSTNAMELEN) goto no_recovery;
  359. strlcpy(bp, qname, (size_t)(ep - bp));
  360. hent->h_name = bp;
  361. bp += n;
  362. }
  363. if (res->options & RES_USE_INET6) map_v4v6_hostent(hent, &bp, ep);
  364. if (hent->h_addrtype == AF_INET) pad_v4v6_hostent(hent, &bp, ep);
  365. goto success;
  366. }
  367. no_recovery:
  368. *he = NO_RECOVERY;
  369. return NULL;
  370. success:
  371. bp = (char*) ALIGN(bp);
  372. aliases.push_back(nullptr);
  373. qlen = aliases.size() * sizeof(*hent->h_aliases);
  374. if ((size_t)(ep - bp) < qlen) goto nospc;
  375. hent->h_aliases = (char**) bp;
  376. memcpy(bp, aliases.data(), qlen);
  377. bp += qlen;
  378. n = (int) (hap - addr_ptrs);
  379. qlen = (n + 1) * sizeof(*hent->h_addr_list);
  380. if ((size_t)(ep - bp) < qlen) goto nospc;
  381. hent->h_addr_list = (char**) bp;
  382. memcpy(bp, addr_ptrs, qlen);
  383. *he = NETDB_SUCCESS;
  384. return hent;
  385. nospc:
  386. errno = ENOSPC;
  387. *he = NETDB_INTERNAL;
  388. return NULL;
  389. }
  390. static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
  391. char* buf, size_t buflen) {
  392. getnamaddr info;
  393. size_t size;
  394. _DIAGASSERT(name != NULL);
  395. switch (af) {
  396. case AF_INET:
  397. size = NS_INADDRSZ;
  398. break;
  399. case AF_INET6:
  400. size = NS_IN6ADDRSZ;
  401. break;
  402. default:
  403. return EAI_FAMILY;
  404. }
  405. if (buflen < size) goto nospc;
  406. hp->h_addrtype = af;
  407. hp->h_length = (int) size;
  408. /*
  409. * disallow names consisting only of digits/dots, unless
  410. * they end in a dot.
  411. */
  412. if (isdigit((u_char) name[0])) {
  413. for (const char* cp = name;; ++cp) {
  414. if (!*cp) {
  415. if (*--cp == '.') break;
  416. /*
  417. * All-numeric, no dot at the end.
  418. * Fake up a hostent as if we'd actually
  419. * done a lookup.
  420. */
  421. goto fake;
  422. }
  423. if (!isdigit((u_char) *cp) && *cp != '.') break;
  424. }
  425. }
  426. if ((isxdigit((u_char) name[0]) && strchr(name, ':') != NULL) || name[0] == ':') {
  427. for (const char* cp = name;; ++cp) {
  428. if (!*cp) {
  429. if (*--cp == '.') break;
  430. /*
  431. * All-IPv6-legal, no dot at the end.
  432. * Fake up a hostent as if we'd actually
  433. * done a lookup.
  434. */
  435. goto fake;
  436. }
  437. if (!isxdigit((u_char) *cp) && *cp != ':' && *cp != '.') break;
  438. }
  439. }
  440. info.hp = hp;
  441. info.buf = buf;
  442. info.buflen = buflen;
  443. if (_hf_gethtbyname2(name, af, &info)) {
  444. int error = dns_gethtbyname(name, af, &info);
  445. if (error != 0) return error;
  446. }
  447. return 0;
  448. nospc:
  449. return EAI_MEMORY;
  450. fake:
  451. HENT_ARRAY(hp->h_addr_list, 1, buf, buflen);
  452. HENT_ARRAY(hp->h_aliases, 0, buf, buflen);
  453. hp->h_aliases[0] = NULL;
  454. if (size > buflen) goto nospc;
  455. if (inet_pton(af, name, buf) <= 0) {
  456. return EAI_NODATA;
  457. }
  458. hp->h_addr_list[0] = buf;
  459. hp->h_addr_list[1] = NULL;
  460. buf += size;
  461. buflen -= size;
  462. HENT_SCOPY(hp->h_name, name, buf, buflen);
  463. if (res->options & RES_USE_INET6) map_v4v6_hostent(hp, &buf, buf + buflen);
  464. return 0;
  465. }
  466. // very similar in proxy-ness to android_getaddrinfo_proxy
  467. static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
  468. size_t hbuflen, const android_net_context* netcontext,
  469. NetworkDnsEventReported* event) {
  470. res_setnetcontext(res, netcontext, event);
  471. return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen);
  472. }
  473. static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t len, int af,
  474. struct hostent* hp, char* buf, size_t buflen,
  475. const struct android_net_context* netcontext,
  476. NetworkDnsEventReported* event) {
  477. const u_char* uaddr = (const u_char*) addr;
  478. socklen_t size;
  479. struct getnamaddr info;
  480. _DIAGASSERT(addr != NULL);
  481. if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
  482. (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr*) addr) ||
  483. IN6_IS_ADDR_SITELOCAL((const struct in6_addr*) addr))) {
  484. return EAI_NODATA;
  485. }
  486. if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
  487. (IN6_IS_ADDR_V4MAPPED((const struct in6_addr*) addr) ||
  488. IN6_IS_ADDR_V4COMPAT((const struct in6_addr*) addr))) {
  489. /* Unmap. */
  490. uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
  491. addr = uaddr;
  492. af = AF_INET;
  493. len = NS_INADDRSZ;
  494. }
  495. switch (af) {
  496. case AF_INET:
  497. size = NS_INADDRSZ;
  498. break;
  499. case AF_INET6:
  500. size = NS_IN6ADDRSZ;
  501. break;
  502. default:
  503. return EAI_FAMILY;
  504. }
  505. if (size != len) {
  506. // TODO: Consider converting to a private extended EAI_* error code.
  507. // Currently, the EAI_* value has no corresponding error code for invalid argument socket
  508. // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM
  509. // and EINVAL, to EAI_FAIL.
  510. return EAI_FAIL;
  511. }
  512. info.hp = hp;
  513. info.buf = buf;
  514. info.buflen = buflen;
  515. if (_hf_gethtbyaddr(uaddr, len, af, &info)) {
  516. int error = dns_gethtbyaddr(uaddr, len, af, netcontext, &info, event);
  517. if (error != 0) return error;
  518. }
  519. return 0;
  520. }
  521. static int android_gethostbyaddrfornetcontext_proxy_internal(
  522. const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
  523. const struct android_net_context* netcontext, NetworkDnsEventReported* event) {
  524. return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext,
  525. event);
  526. }
  527. // TODO: Consider leaving function without returning error code as _gethtent() does because
  528. // the error code of the caller does not currently return to netd.
  529. struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, size_t buflen,
  530. int* he) {
  531. const size_t line_buf_size = sizeof(res_get_static()->hostbuf);
  532. char *name;
  533. char* cp;
  534. int af, len;
  535. size_t anum;
  536. struct in6_addr host_addr;
  537. std::vector<char*> aliases;
  538. if (hf == NULL) {
  539. *he = NETDB_INTERNAL;
  540. errno = EINVAL;
  541. return NULL;
  542. }
  543. char* p = NULL;
  544. /* Allocate a new space to read file lines like upstream does.
  545. * To keep reentrancy we cannot use res_get_static()->hostbuf here,
  546. * as the buffer may be used to store content for a previous hostent
  547. * returned by non-reentrant functions like gethostbyname().
  548. */
  549. if ((p = (char*) malloc(line_buf_size)) == NULL) {
  550. goto nospc;
  551. }
  552. for (;;) {
  553. if (!fgets(p, line_buf_size, hf)) {
  554. free(p);
  555. *he = HOST_NOT_FOUND;
  556. return NULL;
  557. }
  558. if (*p == '#') {
  559. continue;
  560. }
  561. if (!(cp = strpbrk(p, "#\n"))) {
  562. continue;
  563. }
  564. *cp = '\0';
  565. if (!(cp = strpbrk(p, " \t"))) continue;
  566. *cp++ = '\0';
  567. if (inet_pton(AF_INET6, p, &host_addr) > 0) {
  568. af = AF_INET6;
  569. len = NS_IN6ADDRSZ;
  570. } else {
  571. if (inet_pton(AF_INET, p, &host_addr) <= 0) continue;
  572. res_state res = res_get_state();
  573. if (res == NULL) goto nospc;
  574. if (res->options & RES_USE_INET6) {
  575. map_v4v6_address(buf, buf);
  576. af = AF_INET6;
  577. len = NS_IN6ADDRSZ;
  578. } else {
  579. af = AF_INET;
  580. len = NS_INADDRSZ;
  581. }
  582. }
  583. /* if this is not something we're looking for, skip it. */
  584. if (hent->h_addrtype != 0 && hent->h_addrtype != af) continue;
  585. if (hent->h_length != 0 && hent->h_length != len) continue;
  586. while (*cp == ' ' || *cp == '\t') cp++;
  587. if ((cp = strpbrk(name = cp, " \t")) != NULL) *cp++ = '\0';
  588. while (cp && *cp) {
  589. if (*cp == ' ' || *cp == '\t') {
  590. cp++;
  591. continue;
  592. }
  593. aliases.push_back(cp);
  594. if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0';
  595. }
  596. break;
  597. }
  598. hent->h_length = len;
  599. hent->h_addrtype = af;
  600. HENT_ARRAY(hent->h_addr_list, 1, buf, buflen);
  601. anum = aliases.size();
  602. HENT_ARRAY(hent->h_aliases, anum, buf, buflen);
  603. HENT_COPY(hent->h_addr_list[0], &host_addr, hent->h_length, buf, buflen);
  604. hent->h_addr_list[1] = NULL;
  605. /* Reserve space for mapping IPv4 address to IPv6 address in place */
  606. if (hent->h_addrtype == AF_INET) {
  607. HENT_COPY(buf, NAT64_PAD, sizeof(NAT64_PAD), buf, buflen);
  608. }
  609. HENT_SCOPY(hent->h_name, name, buf, buflen);
  610. for (size_t i = 0; i < anum; i++) HENT_SCOPY(hent->h_aliases[i], aliases[i], buf, buflen);
  611. hent->h_aliases[anum] = NULL;
  612. *he = NETDB_SUCCESS;
  613. free(p);
  614. return hent;
  615. nospc:
  616. free(p);
  617. errno = ENOSPC;
  618. *he = NETDB_INTERNAL;
  619. return NULL;
  620. }
  621. static void map_v4v6_address(const char* src, char* dst) {
  622. u_char* p = (u_char*) dst;
  623. char tmp[NS_INADDRSZ];
  624. int i;
  625. _DIAGASSERT(src != NULL);
  626. _DIAGASSERT(dst != NULL);
  627. /* Stash a temporary copy so our caller can update in place. */
  628. memcpy(tmp, src, NS_INADDRSZ);
  629. /* Mark this ipv6 addr as a mapped ipv4. */
  630. for (i = 0; i < 10; i++) *p++ = 0x00;
  631. *p++ = 0xff;
  632. *p++ = 0xff;
  633. /* Retrieve the saved copy and we're done. */
  634. memcpy(p, tmp, NS_INADDRSZ);
  635. }
  636. static void convert_v4v6_hostent(struct hostent* hp, char** bpp, char* ep,
  637. std::function<void(struct hostent* hp)> map_param,
  638. std::function<void(char* src, char* dst)> map_addr) {
  639. _DIAGASSERT(hp != NULL);
  640. _DIAGASSERT(bpp != NULL);
  641. _DIAGASSERT(ep != NULL);
  642. if (hp->h_addrtype != AF_INET || hp->h_length != NS_INADDRSZ) return;
  643. map_param(hp);
  644. for (char** ap = hp->h_addr_list; *ap; ap++) {
  645. int i = (int) (sizeof(align) - (size_t)((u_long) *bpp % sizeof(align)));
  646. if (ep - *bpp < (i + NS_IN6ADDRSZ)) {
  647. /* Out of memory. Truncate address list here. XXX */
  648. *ap = NULL;
  649. return;
  650. }
  651. *bpp += i;
  652. map_addr(*ap, *bpp);
  653. *ap = *bpp;
  654. *bpp += NS_IN6ADDRSZ;
  655. }
  656. }
  657. static void map_v4v6_hostent(struct hostent* hp, char** bpp, char* ep) {
  658. convert_v4v6_hostent(hp, bpp, ep,
  659. [](struct hostent* hp) {
  660. hp->h_addrtype = AF_INET6;
  661. hp->h_length = NS_IN6ADDRSZ;
  662. },
  663. [](char* src, char* dst) { map_v4v6_address(src, dst); });
  664. }
  665. /* Reserve space for mapping IPv4 address to IPv6 address in place */
  666. static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep) {
  667. convert_v4v6_hostent(hp, bpp, ep,
  668. [](struct hostent* hp) {
  669. (void) hp; /* unused */
  670. },
  671. [](char* src, char* dst) {
  672. memcpy(dst, src, NS_INADDRSZ);
  673. memcpy(dst + NS_INADDRSZ, NAT64_PAD, sizeof(NAT64_PAD));
  674. });
  675. }
  676. static void addrsort(char** ap, int num, res_state res) {
  677. int i, j;
  678. char** p;
  679. short aval[MAXADDRS];
  680. int needsort = 0;
  681. _DIAGASSERT(ap != NULL);
  682. p = ap;
  683. for (i = 0; i < num; i++, p++) {
  684. for (j = 0; (unsigned) j < res->nsort; j++)
  685. if (res->sort_list[j].addr.s_addr ==
  686. (((struct in_addr*) (void*) (*p))->s_addr & res->sort_list[j].mask))
  687. break;
  688. aval[i] = j;
  689. if (needsort == 0 && i > 0 && j < aval[i - 1]) needsort = i;
  690. }
  691. if (!needsort) return;
  692. while (needsort < num) {
  693. for (j = needsort - 1; j >= 0; j--) {
  694. if (aval[j] > aval[j + 1]) {
  695. char* hp;
  696. i = aval[j];
  697. aval[j] = aval[j + 1];
  698. aval[j + 1] = i;
  699. hp = ap[j];
  700. ap[j] = ap[j + 1];
  701. ap[j + 1] = hp;
  702. } else
  703. break;
  704. }
  705. needsort++;
  706. }
  707. }
  708. static int dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) {
  709. int n, type;
  710. info->hp->h_addrtype = addr_type;
  711. switch (info->hp->h_addrtype) {
  712. case AF_INET:
  713. info->hp->h_length = NS_INADDRSZ;
  714. type = T_A;
  715. break;
  716. case AF_INET6:
  717. info->hp->h_length = NS_IN6ADDRSZ;
  718. type = T_AAAA;
  719. break;
  720. default:
  721. return EAI_FAMILY;
  722. }
  723. auto buf = std::make_unique<querybuf>();
  724. res_state res = res_get_state();
  725. if (!res) return EAI_MEMORY;
  726. int he;
  727. n = res_nsearch(res, name, C_IN, type, buf->buf, (int)sizeof(buf->buf), &he);
  728. if (n < 0) {
  729. LOG(DEBUG) << __func__ << ": res_nsearch failed (" << n << ")";
  730. // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.
  731. // Note that res_nsearch() doesn't set the pair NETDB_INTERNAL and errno.
  732. // See also herrnoToAiErrno().
  733. return herrnoToAiErrno(he);
  734. }
  735. hostent* hp = getanswer(buf.get(), n, name, type, res, info->hp, info->buf, info->buflen, &he);
  736. if (hp == NULL) return herrnoToAiErrno(he);
  737. return 0;
  738. }
  739. static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
  740. const android_net_context* netcontext, getnamaddr* info,
  741. NetworkDnsEventReported* event) {
  742. char qbuf[MAXDNAME + 1], *qp, *ep;
  743. int n;
  744. int advance;
  745. info->hp->h_length = len;
  746. info->hp->h_addrtype = af;
  747. switch (info->hp->h_addrtype) {
  748. case AF_INET:
  749. (void) snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff),
  750. (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
  751. break;
  752. case AF_INET6:
  753. qp = qbuf;
  754. ep = qbuf + sizeof(qbuf) - 1;
  755. for (n = NS_IN6ADDRSZ - 1; n >= 0; n--) {
  756. advance = snprintf(qp, (size_t)(ep - qp), "%x.%x.", uaddr[n] & 0xf,
  757. ((unsigned int) uaddr[n] >> 4) & 0xf);
  758. if (advance > 0 && qp + advance < ep)
  759. qp += advance;
  760. else {
  761. // TODO: Consider converting to a private extended EAI_* error code.
  762. // Currently, the EAI_* value has no corresponding error code for an internal
  763. // out of buffer space. In order to not rely on errno, convert the original
  764. // error code EAI_SYSTEM to EAI_MEMORY.
  765. return EAI_MEMORY;
  766. }
  767. }
  768. if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) {
  769. // TODO: Consider converting to a private extended EAI_* error code.
  770. // Currently, the EAI_* value has no corresponding error code for an internal
  771. // out of buffer space. In order to not rely on errno, convert the original
  772. // error code EAI_SYSTEM to EAI_MEMORY.
  773. return EAI_MEMORY;
  774. }
  775. break;
  776. default:
  777. return EAI_FAMILY;
  778. }
  779. auto buf = std::make_unique<querybuf>();
  780. res_state res = res_get_state();
  781. if (!res) return EAI_MEMORY;
  782. res_setnetcontext(res, netcontext, event);
  783. int he;
  784. n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int)sizeof(buf->buf), &he);
  785. if (n < 0) {
  786. LOG(DEBUG) << __func__ << ": res_nquery failed (" << n << ")";
  787. // Note that res_nquery() doesn't set the pair NETDB_INTERNAL and errno.
  788. // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.
  789. // See also herrnoToAiErrno().
  790. return herrnoToAiErrno(he);
  791. }
  792. hostent* hp = getanswer(buf.get(), n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, &he);
  793. if (hp == NULL) return herrnoToAiErrno(he);
  794. char* bf = (char*) (hp->h_addr_list + 2);
  795. size_t blen = (size_t)(bf - info->buf);
  796. if (blen + info->hp->h_length > info->buflen) goto nospc;
  797. hp->h_addr_list[0] = bf;
  798. hp->h_addr_list[1] = NULL;
  799. memcpy(bf, uaddr, (size_t) info->hp->h_length);
  800. if (info->hp->h_addrtype == AF_INET && (res->options & RES_USE_INET6)) {
  801. if (blen + NS_IN6ADDRSZ > info->buflen) goto nospc;
  802. map_v4v6_address(bf, bf);
  803. hp->h_addrtype = AF_INET6;
  804. hp->h_length = NS_IN6ADDRSZ;
  805. }
  806. /* Reserve enough space for mapping IPv4 address to IPv6 address in place */
  807. if (info->hp->h_addrtype == AF_INET) {
  808. if (blen + NS_IN6ADDRSZ > info->buflen) goto nospc;
  809. // Pad zero to the unused address space
  810. memcpy(bf + NS_INADDRSZ, NAT64_PAD, sizeof(NAT64_PAD));
  811. }
  812. return 0;
  813. nospc:
  814. return EAI_MEMORY;
  815. }
  816. /*
  817. * Non-reentrant versions.
  818. */
  819. int android_gethostbynamefornetcontext(const char* name, int af,
  820. const struct android_net_context* netcontext, hostent** hp,
  821. NetworkDnsEventReported* event) {
  822. assert(event != nullptr);
  823. res_state res = res_get_state();
  824. if (res == NULL) return EAI_MEMORY;
  825. res_static* rs = res_get_static(); // For thread-safety.
  826. int error;
  827. error = gethostbyname_internal(name, af, res, &rs->host, rs->hostbuf, sizeof(rs->hostbuf),
  828. netcontext, event);
  829. if (error == 0) {
  830. *hp = &rs->host;
  831. }
  832. return error;
  833. }
  834. int android_gethostbyaddrfornetcontext(const void* addr, socklen_t len, int af,
  835. const struct android_net_context* netcontext, hostent** hp,
  836. NetworkDnsEventReported* event) {
  837. return android_gethostbyaddrfornetcontext_proxy(addr, len, af, netcontext, hp, event);
  838. }
  839. static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
  840. const struct android_net_context* netcontext,
  841. hostent** hp, NetworkDnsEventReported* event) {
  842. assert(event != nullptr);
  843. struct res_static* rs = res_get_static(); // For thread-safety.
  844. int error = android_gethostbyaddrfornetcontext_proxy_internal(
  845. addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), netcontext, event);
  846. if (error == 0) *hp = &rs->host;
  847. return error;
  848. }
  849. int herrnoToAiErrno(int he) {
  850. switch (he) {
  851. // extended h_errno
  852. case NETD_RESOLV_H_ERRNO_EXT_TIMEOUT:
  853. return NETD_RESOLV_TIMEOUT;
  854. // legacy h_errno
  855. case NETDB_SUCCESS:
  856. return 0;
  857. case HOST_NOT_FOUND: // TODO: Perhaps convert HOST_NOT_FOUND to EAI_NONAME instead
  858. case NO_DATA: // NO_ADDRESS
  859. return EAI_NODATA;
  860. case TRY_AGAIN:
  861. return EAI_AGAIN;
  862. case NETDB_INTERNAL:
  863. // TODO: Remove ENOSPC and call abort() immediately whenever any allocation fails.
  864. if (errno == ENOSPC) return EAI_MEMORY;
  865. // Theoretically, this should not happen. Leave this here just in case.
  866. // Currently, getanswer() of {gethnamaddr, getaddrinfo}.cpp, res_nsearch() and
  867. // res_searchN() use this function to convert error code. Only getanswer()
  868. // of gethnamaddr.cpp may return the error code pair, herrno NETDB_INTERNAL and
  869. // errno ENOSPC, which has already converted to EAI_MEMORY. The remaining functions
  870. // don't set the pair herrno and errno.
  871. return EAI_SYSTEM; // see errno for detail
  872. case NO_RECOVERY:
  873. default:
  874. return EAI_FAIL; // TODO: Perhaps convert default to EAI_MAX (unknown error) instead
  875. }
  876. }