wait, Maxdest is a count, see:
dest = emalloc(Maxdest * sizeof *dest); /* dest can't be on stack */
code like:
Dest *curdest; /* pointer to next to fill */
p = dp->dest;
...
if (qp->ndest > qp->curdest - p) {
and
for(p = qp->dest; p < qp->curdest; p++)
indicates that dp->curdest is an end pointer. so it should be perfectly valid
for it to point at &dp->dest[Maxdest].
the check at the top of serveraddrs() should really be:
if(nd >= Maxdest) /* dest array is full? */
return Maxdest;
serveraddr() really returns a count. which is the same as an
end pointer index.
the result check of that serveraddr() call should really be:
if (j < 0 || j > Maxdest) {
dnslog("serveraddrs() result %d out of range", j);
abort();
}
qp->curdest = &qp->dest[j];
and the destck(dp->curdest); should be removed.
--- a/sys/src/cmd/ndb/dnresolve.c Wed Aug 22 00:11:42 2012 +0200
+++ b/sys/src/cmd/ndb/dnresolve.c Wed Aug 22 12:28:34 2012 +0200
@@ -832,7 +832,7 @@
Dest *cur;
if(nd >= Maxdest) /* dest array is full? */
- return Maxdest - 1;
+ return Maxdest;
/*
* look for a server whose address we already know.
@@ -1080,13 +1080,12 @@
*/
if (qp->ndest > qp->curdest - p) {
j = serveraddrs(qp, qp->curdest - p, depth);
- if (j < 0 || j >= Maxdest) {
+ if (j < 0 || j > Maxdest) {
dnslog("serveraddrs() result %d out of range", j);
abort();
}
qp->curdest = &qp->dest[j];
}
- destck(qp->curdest);
/* no servers, punt */
if (qp->ndest == 0)
--
cinap