X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Fcheck.c;h=44f52b909e31cd1792144dab8d3939c8556aa9ef;hp=04c5c8e0c30dee087511ae3d0a9ba1400942ef62;hb=c0ec02b59a25b13bb6a04abd518d0d2da0fefc88;hpb=bfc2c80e5bed3c17f3cf7451939458b0357bfd38 diff --git a/src/check.c b/src/check.c index 04c5c8e..44f52b9 100644 --- a/src/check.c +++ b/src/check.c @@ -3,7 +3,11 @@ * - consistency checks */ /* - * This file is part of adns, which is Copyright (C) 1997-1999 Ian Jackson + * This file is part of adns, which is + * Copyright (C) 1997-2000,2003,2006 Ian Jackson + * Copyright (C) 1999-2000,2003,2006 Tony Finch + * Copyright (C) 1991 Massachusetts Institute of Technology + * (See the file INSTALL for full details.) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,24 +30,26 @@ void adns_checkconsistency(adns_state ads, adns_query qu) { adns__consistency(ads,qu,cc_user); } -#define DLIST_CHECK(list, nodevar, part, body) \ - if ((list).head) { \ - assert(! (list).head->part back); \ - for ((nodevar)= (list).head; (nodevar); (nodevar)= (nodevar)->part next) { \ - assert((nodevar)->part next \ - ? (nodevar) == (nodevar)->part next->part back \ - : (nodevar) == (list).tail); \ - body \ - } \ +#define DLIST_CHECK(list, nodevar, part, body) \ + if ((list).head) { \ + assert(! (list).head->part back); \ + for ((nodevar)= (list).head; \ + (nodevar); \ + (nodevar)= (nodevar)->part next) { \ + assert((nodevar)->part next \ + ? (nodevar) == (nodevar)->part next->part back \ + : (nodevar) == (list).tail); \ + body \ + } \ } -#define DLIST_ASSERTON(node, nodevar, list, part) \ - do { \ - for ((nodevar)= (list).head; \ - (nodevar) != (node); \ - (nodevar)= (nodevar)->part next) { \ - assert((nodevar)); \ - } \ +#define DLIST_ASSERTON(node, nodevar, list, part) \ + do { \ + for ((nodevar)= (list).head; \ + (nodevar) != (node); \ + (nodevar)= (nodevar)->part next) { \ + assert((nodevar)); \ + } \ } while(0) static void checkc_query_alloc(adns_state ads, adns_query qu) { @@ -58,31 +64,46 @@ static void checkc_query(adns_state ads, adns_query qu) { assert(qu->udpnextserver < ads->nservers); assert(!(qu->udpsent & (~0UL << ads->nservers))); - assert(!(qu->tcpfailed & (~0UL << ads->nservers))); - assert(qu->udpretries <= UDPMAXRETRIES); assert(qu->search_pos <= ads->nsearchlist); if (qu->parent) DLIST_ASSERTON(qu, child, qu->parent->children, siblings.); } +static void checkc_notcpbuf(adns_state ads) { + assert(!ads->tcpsend.used); + assert(!ads->tcprecv.used); + assert(!ads->tcprecv_skip); +} + static void checkc_global(adns_state ads) { + const struct sortlist *sl; int i; assert(ads->udpsocket >= 0); - for (i=0; insortlist; i++) - assert(!(ads->sortlist[i].base.s_addr & ~ads->sortlist[i].mask.s_addr)); + for (i=0; insortlist; i++) { + assert(ads->sortlist[i].af==AF_INET); + assert(!(ads->sortlist[i].base.v4.s_addr & + ~ads->sortlist[i].mask.v4.s_addr)); + sl= &ads->sortlist[i]; + assert(sl->af==AF_INET); + assert(!(sl->base.v4.s_addr & ~sl->mask.v4.s_addr)); + } assert(ads->tcpserver >= 0 && ads->tcpserver < ads->nservers); switch (ads->tcpstate) { case server_connecting: assert(ads->tcpsocket >= 0); - case server_disconnected: /* fall through */ - assert(!ads->tcprecv.used); - assert(!ads->tcpsend.used); + checkc_notcpbuf(ads); + break; + case server_disconnected: + case server_broken: + assert(ads->tcpsocket == -1); + checkc_notcpbuf(ads); break; case server_ok: assert(ads->tcpsocket >= 0); + assert(ads->tcprecv_skip <= ads->tcprecv.used); break; default: assert(!"ads->tcpstate value"); @@ -91,24 +112,26 @@ static void checkc_global(adns_state ads) { assert(ads->searchlist || !ads->nsearchlist); } -static void checkc_queue_timew(adns_state ads) { +static void checkc_queue_udpw(adns_state ads) { adns_query qu; - DLIST_CHECK(ads->timew, qu, , { - switch (qu->state) { - case query_tosend: - assert(qu->udpsent); - assert(!qu->tcpfailed); - break; - case query_tcpwait: - assert(ads->tcpstate != server_ok); - break; - case query_tcpsent: - break; - default: - assert(!"timew state"); - } + DLIST_CHECK(ads->udpw, qu, , { + assert(qu->state==query_tosend); + assert(qu->retries <= UDPMAXRETRIES); + assert(qu->udpsent); + assert(!qu->children.head && !qu->children.tail); + checkc_query(ads,qu); + checkc_query_alloc(ads,qu); + }); +} + +static void checkc_queue_tcpw(adns_state ads) { + adns_query qu; + + DLIST_CHECK(ads->tcpw, qu, , { + assert(qu->state==query_tcpw); assert(!qu->children.head && !qu->children.tail); + assert(qu->retries <= ads->nservers+1); checkc_query(ads,qu); checkc_query_alloc(ads,qu); }); @@ -118,7 +141,7 @@ static void checkc_queue_childw(adns_state ads) { adns_query parent, child; DLIST_CHECK(ads->childw, parent, , { - assert(parent->state == query_child); + assert(parent->state == query_childw); assert(parent->children.head); DLIST_CHECK(parent->children, child, siblings., { assert(child->parent == parent); @@ -158,18 +181,20 @@ void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc) { } checkc_global(ads); - checkc_queue_timew(ads); + checkc_queue_udpw(ads); + checkc_queue_tcpw(ads); checkc_queue_childw(ads); checkc_queue_output(ads); if (qu) { switch (qu->state) { case query_tosend: - case query_tcpwait: - case query_tcpsent: - DLIST_ASSERTON(qu, search, ads->timew, ); + DLIST_ASSERTON(qu, search, ads->udpw, ); + break; + case query_tcpw: + DLIST_ASSERTON(qu, search, ads->tcpw, ); break; - case query_child: + case query_childw: DLIST_ASSERTON(qu, search, ads->childw, ); break; case query_done: