diff options
author | Elliott Hughes <enh@google.com> | 2019-09-06 22:31:48 -0700 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-09-07 17:26:51 -0500 |
commit | 4247dca900e08daa6a8a2333baca6136bdbba31d (patch) | |
tree | 107f2c6b6e11453b7c9a9bb4a451c3d431a8f7a2 /toys | |
parent | acc9e87d164dcb037ab86cd2ecff7262d4b13792 (diff) | |
download | toybox-4247dca900e08daa6a8a2333baca6136bdbba31d.tar.gz |
host: cope with large DNS responses.
DNS responses were limited to 512 bytes back when they were UDP only,
but if you have a TCP connection you can get up to 64KiB.
Also use the existing constant for the size of rrname.
Also update the help text.
Also consistently use `sizeof(T)` rather than `sizeof T`.
Also use consistently use `ARRAY_LEN`.
Fixes #56.
Test: `toybox host value.testing.express`
Diffstat (limited to 'toys')
-rw-r--r-- | toys/pending/host.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/toys/pending/host.c b/toys/pending/host.c index fe0f23aa..1610301e 100644 --- a/toys/pending/host.c +++ b/toys/pending/host.c @@ -16,8 +16,8 @@ config HOST or an IPv4 dotted or IPv6 colon-separated address to reverse lookup. SERVER (if present) is the DNS server to use. - -a no idea - -t not a clue + -a -v -t ANY + -t TYPE query records of type TYPE -v verbose */ @@ -68,10 +68,13 @@ static const char rct[16][32] = { void host_main(void) { int verbose=(toys.optflags & (FLAG_a|FLAG_v)), type, - i, j, ret, sec, count, rcode, qlen, alen, pllen = 0; + i, j, ret, sec, count, rcode, qlen, alen, pllen = 0, + abuf_len = 65536; // Largest TCP response. unsigned ttl, pri, v[5]; - unsigned char qbuf[280], abuf[512], *p; - char *name, *nsname, rrname[256], plname[640], ptrbuf[128]; + unsigned char *abuf = xmalloc(abuf_len); + char *rrname = xmalloc(MAXDNAME); + unsigned char qbuf[280], *p; + char *name, *nsname, plname[640], ptrbuf[128]; struct addrinfo *ai, iplit_hints = { .ai_flags = AI_NUMERICHOST }; name = *toys.optargs; @@ -113,7 +116,7 @@ void host_main(void) if (type < 0) error_exit("Invalid query type: %s", TT.type_str); } - qlen = res_mkquery(0, name, 1, type, 0, 0, 0, qbuf, sizeof qbuf); + qlen = res_mkquery(0, name, 1, type, 0, 0, 0, qbuf, sizeof(qbuf)); if (qlen < 0) error_exit("Invalid query parameters: %s", name); if (nsname) { @@ -127,8 +130,8 @@ void host_main(void) sizeof(struct timeval)); printf("Using domain server %s:\n", nsname); send(s, qbuf, qlen, 0); - alen = recv(s, abuf, sizeof abuf, 0); - } else alen = res_send(qbuf, qlen, abuf, sizeof abuf); + alen = recv(s, abuf, abuf_len, 0); + } else alen = res_send(qbuf, qlen, abuf, abuf_len); if (alen < 12) error_exit("Host not found."); @@ -150,7 +153,7 @@ void host_main(void) : "Additional information:"); for (; count--; p += pllen) { - p += dn_expand(abuf, abuf+alen, p, rrname, sizeof(rrname)); + p += dn_expand(abuf, abuf+alen, p, rrname, MAXDNAME); type = (p[0]<<8) + p[1]; p += 4; if (!sec) continue; @@ -159,18 +162,18 @@ void host_main(void) pllen = (p[0]<<8) + p[1]; p += 2; - switch (type<sizeof(rrt)/sizeof(*rrt) ? rrt[type].pl : 0) { + switch (type<ARRAY_LEN(rrt) ? rrt[type].pl : 0) { case PL_IP: - inet_ntop(rrt[type].af, p, plname, sizeof plname); + inet_ntop(rrt[type].af, p, plname, sizeof(plname)); break; case PL_NAME: - dn_expand(abuf, abuf+alen, p, plname, sizeof plname); + dn_expand(abuf, abuf+alen, p, plname, sizeof(plname)); break; case PL_TEXT: - snprintf(plname, sizeof plname, "\"%.*s\"", pllen, p); + snprintf(plname, sizeof(plname), "\"%.*s\"", pllen, p); break; case PL_SOA: - i = dn_expand(abuf, abuf+alen, p, plname, sizeof plname - 1); + i = dn_expand(abuf, abuf+alen, p, plname, sizeof(plname) - 1); strcat(plname, " "); i += dn_expand(abuf, abuf+alen, p+i, plname+strlen(plname), sizeof(plname)-strlen(plname)); @@ -188,13 +191,13 @@ void host_main(void) pri = (p[0]<<8)+p[1]; snprintf(plname, sizeof(plname), verbose ? "%d " : "(pri=%d) by ", pri); dn_expand(abuf, abuf+alen, p+2, plname+strlen(plname), - sizeof plname - strlen(plname)); + sizeof(plname) - strlen(plname)); break; case PL_SRV: for (j=0; j<3; j++) v[j] = (p[2*j]<<8) + p[1+2*j]; snprintf(plname, sizeof(plname), "%u %u %u ", v[0], v[1], v[2]); dn_expand(abuf, abuf+alen, p+6, plname+strlen(plname), - sizeof plname - strlen(plname)); + sizeof(plname) - strlen(plname)); break; default: printf("%s unsupported RR type %u\n", rrname, type); @@ -209,5 +212,9 @@ void host_main(void) if (!verbose && sec==1) break; } + if (CFG_TOYBOX_FREE) { + free(abuf); + free(rrname); + } toys.exitval = rcode; } |