X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fnetwork%2Flookup_name.c;h=de0fefeeaf6c5c705aa821e584962038374f764d;hb=41603c7706f8a4c1b1a2a23e49ff7490f6860dc2;hp=bec6ba22f8095f3bde03e9b26b5e49465f5c906a;hpb=1e7fb12f775a3e599be08da9835422d96c56f479;p=musl diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c index bec6ba22..de0fefee 100644 --- a/src/network/lookup_name.c +++ b/src/network/lookup_name.c @@ -79,7 +79,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati case 0: continue; default: - badfam = EAI_NONAME; + badfam = EAI_NODATA; break; } @@ -102,12 +102,15 @@ struct dpc_ctx { struct address *addrs; char *canon; int cnt; + int rrtype; }; #define RR_A 1 #define RR_CNAME 5 #define RR_AAAA 28 +#define ABUF_SIZE 768 + static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet) { char tmp[256]; @@ -115,19 +118,21 @@ static int dns_parse_callback(void *c, int rr, const void *data, int len, const if (ctx->cnt >= MAXADDRS) return -1; switch (rr) { case RR_A: + if (rr != ctx->rrtype) return 0; if (len != 4) return -1; ctx->addrs[ctx->cnt].family = AF_INET; ctx->addrs[ctx->cnt].scopeid = 0; memcpy(ctx->addrs[ctx->cnt++].addr, data, 4); break; case RR_AAAA: + if (rr != ctx->rrtype) return 0; if (len != 16) return -1; ctx->addrs[ctx->cnt].family = AF_INET6; ctx->addrs[ctx->cnt].scopeid = 0; memcpy(ctx->addrs[ctx->cnt++].addr, data, 16); break; case RR_CNAME: - if (__dn_expand(packet, (const unsigned char *)packet + 512, + if (__dn_expand(packet, (const unsigned char *)packet + ABUF_SIZE, data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp)) strcpy(ctx->canon, tmp); break; @@ -137,10 +142,10 @@ static int dns_parse_callback(void *c, int rr, const void *data, int len, const static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf) { - unsigned char qbuf[2][280], abuf[2][512]; + unsigned char qbuf[2][280], abuf[2][ABUF_SIZE]; const unsigned char *qp[2] = { qbuf[0], qbuf[1] }; unsigned char *ap[2] = { abuf[0], abuf[1] }; - int qlens[2], alens[2]; + int qlens[2], alens[2], qtypes[2]; int i, nq = 0; struct dpc_ctx ctx = { .addrs = buf, .canon = canon }; static const struct { int af; int rr; } afrr[2] = { @@ -154,6 +159,7 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 0, 0, 0, qbuf[nq], sizeof *qbuf); if (qlens[nq] == -1) return 0; + qtypes[nq] = afrr[i].rr; qbuf[nq][3] = 0; /* don't need AD flag */ /* Ensure query IDs are distinct. */ if (nq && qbuf[nq][0] == qbuf[0][0]) @@ -171,11 +177,13 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static if ((abuf[i][3] & 15) != 0) return EAI_FAIL; } - for (i=0; i=0; i--) { + ctx.rrtype = qtypes[i]; __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx); + } if (ctx.cnt) return ctx.cnt; - return EAI_NONAME; + return EAI_NODATA; } static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)