Licensing: Update copyright dates for Ian Jackson
[adns] / src / check.c
CommitLineData
3e2e5fab 1/*
2 * check.c
3 * - consistency checks
4 */
5/*
ae8cc977 6 * This file is part of adns, which is
26e1c3d6 7 * Copyright (C) 1997-2000,2003,2006,2014 Ian Jackson
ae8cc977 8 * Copyright (C) 1999-2000,2003,2006 Tony Finch
9 * Copyright (C) 1991 Massachusetts Institute of Technology
10 * (See the file INSTALL for full details.)
3e2e5fab 11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
7f8bbe29 14 * the Free Software Foundation; either version 3, or (at your option)
3e2e5fab 15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
8c09a4c6 23 * along with this program; if not, write to the Free Software Foundation.
3e2e5fab 24 */
25
26#include "internal.h"
27
28de6442 28void adns_checkconsistency(adns_state ads, adns_query qu) {
29 adns__consistency(ads,qu,cc_user);
30}
3e2e5fab 31
609133ee 32#define DLIST_CHECK(list, nodevar, part, body) \
33 if ((list).head) { \
34 assert(! (list).head->part back); \
35 for ((nodevar)= (list).head; \
36 (nodevar); \
37 (nodevar)= (nodevar)->part next) { \
38 assert((nodevar)->part next \
39 ? (nodevar) == (nodevar)->part next->part back \
40 : (nodevar) == (list).tail); \
41 body \
42 } \
3e2e5fab 43 }
44
609133ee 45#define DLIST_ASSERTON(node, nodevar, list, part) \
46 do { \
47 for ((nodevar)= (list).head; \
48 (nodevar) != (node); \
49 (nodevar)= (nodevar)->part next) { \
50 assert((nodevar)); \
51 } \
28de6442 52 } while(0)
53
3e2e5fab 54static void checkc_query_alloc(adns_state ads, adns_query qu) {
55 allocnode *an;
56
57 DLIST_CHECK(qu->allocations, an, , {
58 });
59}
60
61static void checkc_query(adns_state ads, adns_query qu) {
28de6442 62 adns_query child;
63
3e2e5fab 64 assert(qu->udpnextserver < ads->nservers);
65 assert(!(qu->udpsent & (~0UL << ads->nservers)));
3e2e5fab 66 assert(qu->search_pos <= ads->nsearchlist);
28de6442 67 if (qu->parent) DLIST_ASSERTON(qu, child, qu->parent->children, siblings.);
3e2e5fab 68}
69
f7f83b4a 70static void checkc_notcpbuf(adns_state ads) {
71 assert(!ads->tcpsend.used);
72 assert(!ads->tcprecv.used);
73 assert(!ads->tcprecv_skip);
74}
75
3e2e5fab 76static void checkc_global(adns_state ads) {
f930c455 77 const struct sortlist *sl;
3e2e5fab 78 int i;
79
97a937c8 80 assert(ads->udpsockets >= 0);
3e2e5fab 81
f930c455 82 for (i=0; i<ads->nsortlist; i++) {
f930c455 83 sl= &ads->sortlist[i];
82ae109e
IJ
84 assert(adns__addr_matches(sl->base.sa.sa_family,
85 adns__sockaddr_addr(&sl->base.sa),
86 &sl->base,&sl->mask));
f930c455 87 }
3e2e5fab 88
89 assert(ads->tcpserver >= 0 && ads->tcpserver < ads->nservers);
90
91 switch (ads->tcpstate) {
92 case server_connecting:
93 assert(ads->tcpsocket >= 0);
f7f83b4a 94 checkc_notcpbuf(ads);
95 break;
96 case server_disconnected:
97 case server_broken:
98 assert(ads->tcpsocket == -1);
99 checkc_notcpbuf(ads);
3e2e5fab 100 break;
101 case server_ok:
102 assert(ads->tcpsocket >= 0);
70ad7a2a 103 assert(ads->tcprecv_skip <= ads->tcprecv.used);
3e2e5fab 104 break;
105 default:
106 assert(!"ads->tcpstate value");
107 }
108
109 assert(ads->searchlist || !ads->nsearchlist);
110}
111
f7f83b4a 112static void checkc_queue_udpw(adns_state ads) {
3e2e5fab 113 adns_query qu;
114
f7f83b4a 115 DLIST_CHECK(ads->udpw, qu, , {
116 assert(qu->state==query_tosend);
117 assert(qu->retries <= UDPMAXRETRIES);
118 assert(qu->udpsent);
3e2e5fab 119 assert(!qu->children.head && !qu->children.tail);
120 checkc_query(ads,qu);
121 checkc_query_alloc(ads,qu);
122 });
123}
124
f7f83b4a 125static void checkc_queue_tcpw(adns_state ads) {
126 adns_query qu;
127
128 DLIST_CHECK(ads->tcpw, qu, , {
129 assert(qu->state==query_tcpw);
130 assert(!qu->children.head && !qu->children.tail);
131 assert(qu->retries <= ads->nservers+1);
132 checkc_query(ads,qu);
133 checkc_query_alloc(ads,qu);
134 });
135}
136
3e2e5fab 137static void checkc_queue_childw(adns_state ads) {
138 adns_query parent, child;
139
140 DLIST_CHECK(ads->childw, parent, , {
f7f83b4a 141 assert(parent->state == query_childw);
3e2e5fab 142 assert(parent->children.head);
143 DLIST_CHECK(parent->children, child, siblings., {
144 assert(child->parent == parent);
145 assert(child->state != query_done);
146 });
147 checkc_query(ads,parent);
148 checkc_query_alloc(ads,parent);
149 });
150}
151
b582ca0f
IJ
152static void checkc_query_done(adns_state ads, adns_query qu) {
153 assert(qu->state == query_done);
154 assert(!qu->children.head && !qu->children.tail);
155 checkc_query(ads,qu);
156}
157
3e2e5fab 158static void checkc_queue_output(adns_state ads) {
159 adns_query qu;
160
161 DLIST_CHECK(ads->output, qu, , {
3e2e5fab 162 assert(!qu->parent);
bfc2c80e 163 assert(!qu->allocations.head && !qu->allocations.tail);
b582ca0f
IJ
164 checkc_query_done(ads,qu);
165 });
166}
167
168static void checkc_queue_intdone(adns_state ads) {
169 adns_query qu;
170
171 DLIST_CHECK(ads->intdone, qu, , {
172 assert(qu->parent);
173 assert(qu->ctx.callback);
174 checkc_query_done(ads,qu);
3e2e5fab 175 });
176}
177
28de6442 178void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc) {
179 adns_query search;
180
3e2e5fab 181 switch (cc) {
182 case cc_user:
183 break;
184 case cc_entex:
185 if (!(ads->iflags & adns_if_checkc_entex)) return;
b582ca0f 186 assert(!ads->intdone.head);
3e2e5fab 187 break;
188 case cc_freq:
189 if ((ads->iflags & adns_if_checkc_freq) != adns_if_checkc_freq) return;
190 break;
191 default:
192 abort();
193 }
194
195 checkc_global(ads);
f7f83b4a 196 checkc_queue_udpw(ads);
197 checkc_queue_tcpw(ads);
3e2e5fab 198 checkc_queue_childw(ads);
199 checkc_queue_output(ads);
b582ca0f 200 checkc_queue_intdone(ads);
28de6442 201
202 if (qu) {
203 switch (qu->state) {
204 case query_tosend:
f7f83b4a 205 DLIST_ASSERTON(qu, search, ads->udpw, );
206 break;
207 case query_tcpw:
208 DLIST_ASSERTON(qu, search, ads->tcpw, );
28de6442 209 break;
f7f83b4a 210 case query_childw:
28de6442 211 DLIST_ASSERTON(qu, search, ads->childw, );
212 break;
213 case query_done:
b582ca0f
IJ
214 if (qu->parent)
215 DLIST_ASSERTON(qu, search, ads->intdone, );
216 else
217 DLIST_ASSERTON(qu, search, ads->output, );
28de6442 218 break;
219 default:
220 assert(!"specific query state");
221 }
222 }
3e2e5fab 223}