aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-09-06 22:31:48 -0700
committerRob Landley <rob@landley.net>2019-09-07 17:26:51 -0500
commit4247dca900e08daa6a8a2333baca6136bdbba31d (patch)
tree107f2c6b6e11453b7c9a9bb4a451c3d431a8f7a2 /toys
parentacc9e87d164dcb037ab86cd2ecff7262d4b13792 (diff)
downloadtoybox-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.c39
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;
}