--- dnscache.c.orig 2001-02-11 13:11:45.000000000 -0800 +++ dnscache.c 2011-11-18 16:26:25.000000000 -0800 @@ -48,7 +48,7 @@ static char myipoutgoing[4]; static char myipincoming[4]; -static char buf[1024]; +static char buf[65535]; uint64 numqueries = 0; @@ -207,8 +207,9 @@ void t_rw(int j) { struct tcpclient *x; - char ch; + char *ch; static char *q = 0; + unsigned int toread; char qtype[2]; char qclass[2]; int r; @@ -224,20 +225,25 @@ } return; } - - r = read(x->tcp,&ch,1); + switch (x->state) { + case 1: toread = 2U; break; + case 2: toread = 1U; break; + case 3: toread = x->len - x->pos; break; + default: return; /* impossible */ + } + r = read(x->tcp, buf, toread); if (r == 0) { errno = error_pipe; t_close(j); return; } if (r < 0) { t_close(j); return; } - + ch = buf; if (x->state == 1) { - x->len = (unsigned char) ch; + x->len = (unsigned char) *ch++; x->len <<= 8; x->state = 2; - return; + if (--r <= 0) return; } if (x->state == 2) { - x->len += (unsigned char) ch; - if (!x->len) { errno = error_proto; t_close(j); return; } + x->len += (unsigned char) *ch; + if (x->len < 12) { errno = error_proto; t_close(j); return; } x->buf = alloc(x->len); if (!x->buf) { t_close(j); return; } x->pos = 0; @@ -247,7 +253,8 @@ if (x->state != 3) return; /* impossible */ - x->buf[x->pos++] = ch; + byte_copy(&x->buf[x->pos], r, ch); + x->pos += r; if (x->pos < x->len) return; if (!packetquery(x->buf,x->len,&q,qtype,qclass,x->id)) { t_close(j); return; }