X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fnetwork%2Flookup_name.c;h=be0c0bdd9b919db77680645616de517c27021af6;hb=0a7b4323b0f2b944dbd47a813c0c6e6813e7fd67;hp=aa558c197abe813865ba28c1228be272bae62924;hpb=f1198ea3cfae3a3567e4ab4d2c741ed98b86f976;p=musl diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c index aa558c19..be0c0bdd 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,32 +102,37 @@ 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]; struct dpc_ctx *ctx = c; - if (ctx->cnt >= MAXADDRS) return -1; + if (ctx->cnt >= MAXADDRS) return 0; 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] = { @@ -153,8 +158,12 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr, 0, 0, 0, qbuf[nq], sizeof *qbuf); if (qlens[nq] == -1) - return EAI_NONAME; + 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]) + qbuf[nq][0]++; nq++; } } @@ -168,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)