okay, attached is a version using dynamic allocation...
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` --- toys/pending/host.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) On Sat, Sep 7, 2019 at 12:09 AM Rob Landley <[email protected]> wrote: > > On 9/7/19 12:37 AM, enh via Toybox wrote: > > 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. > > I don't want that on the stack for nommu systems. (64k is a common nommu total > process stack size, since it has to be a single contiguous allocation that is > preallocated whether it's used or not.) > > As for maxdname, 4.3bsd had it as 256, it's currently 1025 (gratuitously NOT a > power of 2?) and at that rate of growth I don't particularly want it on the > stack either. > > Rob
From 851b6624a835967f843e85411a4842a6565f25d9 Mon Sep 17 00:00:00 2001 From: Elliott Hughes <[email protected]> Date: Fri, 6 Sep 2019 22:31:48 -0700 Subject: [PATCH] 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` --- toys/pending/host.c | 39 +++++++++++++++++++++++---------------- 1 file 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; } -- 2.23.0.187.g17f5b7556c-goog
_______________________________________________ Toybox mailing list [email protected] http://lists.landley.net/listinfo.cgi/toybox-landley.net
