37 {
38 int cbyte, rrstart, wantedrrs, rri, foundsoa, foundns, cname_here;
39 int id,
f1,
f2, qdcount, ancount, nscount, arcount;
40 int flg_ra, flg_rd, flg_tc, flg_qr, opcode;
41 int rrtype, rrclass, rdlength, rdstart;
42 int anstart, nsstart, arstart;
43 int ownermatched,
l, nrrs;
44 unsigned long ttl, soattl;
50 byte *newquery, *rrsdata;
52
54 adns__diag(
ads,serv,0,
"received datagram too short for message header (%d)",dglen);
55 return;
56 }
66
73
74 cname_here= 0;
75
76 if (!flg_qr) {
77 adns__diag(
ads,serv,0,
"server sent us a query, not a response");
78 return;
79 }
80 if (opcode) {
81 adns__diag(
ads,serv,0,
"server sent us unknown opcode %d (wanted 0=QUERY)",opcode);
82 return;
83 }
84
85 qu= 0;
86
87
88 if (qdcount == 1) {
89 for (qu= viatcp ?
ads->tcpw.head :
ads->udpw.head; qu; qu= nqu) {
91 if (qu->
id !=
id)
continue;
92 if (dglen < qu->query_dglen) continue;
96 continue;
97 if (viatcp) {
99 } else {
101 if (!(qu->
udpsent & (1<<serv)))
continue;
102 }
103 break;
104 }
105 if (qu) {
106
109 }
110 }
111
112
113
114
115
119 break;
121 adns__warn(
ads,serv,qu,
"server cannot understand our query (Format Error)");
123 return;
126 else adns__debug(
ads,serv,qu,
"server failure on unidentifiable query");
127 return;
129 adns__warn(
ads,serv,qu,
"server claims not to implement our query");
131 return;
135 return;
136 default:
139 return;
140 }
141
142 if (!qu) {
143 if (!qdcount) {
144 adns__diag(
ads,serv,0,
"server sent reply without quoting our question");
145 } else if (qdcount>1) {
146 adns__diag(
ads,serv,0,
"server claimed to answer %d questions with one message",
147 qdcount);
150 adns__debug(
ads,serv,0,
"reply not found, id %02x, query owner %s",
153 }
154 return;
155 }
156
157
158
160 arstart= -1;
161
162
163
164
165 wantedrrs= 0;
167 for (rri= 0; rri<ancount; rri++) {
170 &rrtype,&rrclass,&ttl, &rdlength,&rdstart,
171 &ownermatched);
173 if (rrtype == -1) goto x_truncated;
174
176 adns__diag(
ads,serv,qu,
"ignoring answer RR with wrong class %d (expected IN=%d)",
178 continue;
179 }
180 if (!ownermatched) {
182 adns__debug(
ads,serv,qu,
"ignoring RR with an unexpected owner %s",
184 }
185 continue;
186 }
191 return;
193 adns__debug(
ads,serv,qu,
"allegedly canonical name %s is actually alias for %s",
197 return;
198 } else if (wantedrrs) {
199 adns__debug(
ads,serv,qu,
"ignoring CNAME (to %s) coexisting with RR",
201 } else {
206 dgram,dglen, &rdstart,rdstart+rdlength);
207 if (!qu->
vb.
used)
goto x_truncated;
212
215
217 cname_here= 1;
219
220
221
222
223
224 }
226 wantedrrs++;
227 } else {
228 adns__debug(
ads,serv,qu,
"ignoring answer RR with irrelevant type %d",rrtype);
229 }
230 }
231
232
233
234
235 if (flg_tc) goto x_truncated;
236
238
239 if (!wantedrrs) {
240
241
242
243 foundsoa= 0; soattl= 0; foundns= 0;
244 for (rri= 0; rri<nscount; rri++) {
247 &rrtype,&rrclass,&ttl, &rdlength,&rdstart, 0);
249 if (rrtype==-1) goto x_truncated;
252 "ignoring authority RR with wrong class %d (expected IN=%d)",
254 continue;
255 }
256 if (rrtype ==
adns_r_soa_raw) { foundsoa= 1; soattl= ttl;
break; }
258 }
259
261
263
266 } else {
268 }
269 return;
270 }
271
272 if (foundsoa || !foundns) {
273
276 return;
277 }
278
279
280
281
282
283
284 if (cname_here) goto x_restartquery;
285
286
287 if (!flg_ra) {
288 adns__diag(
ads,serv,qu,
"server is not willing to do recursive lookups for us");
290 } else {
291 if (!flg_rd)
292 adns__diag(
ads,serv,qu,
"server thinks we didn't ask for recursive lookup");
293 else
294 adns__debug(
ads,serv,qu,
"server claims to do recursion, but gave us a referral");
296 }
297 return;
298 }
299
300
301
304
308
318
319 for (rri=0, nrrs=0; rri<ancount; rri++) {
321 &rrtype,&rrclass,&ttl, &rdlength,&rdstart,
322 &ownermatched);
326 !ownermatched)
327 continue;
329 st= typei->
parse(&pai, rdstart,rdstart+rdlength, rrsdata+nrrs*typei->
rrsz);
331 if (rdstart==-1) goto x_truncated;
332 nrrs++;
333 }
336
337
339 qu->
state= query_childw;
341 return;
342 }
344 return;
345
346 x_truncated:
347
348 if (!flg_tc) {
349 adns__diag(
ads,serv,qu,
"server sent datagram which points outside itself");
351 return;
352 }
354
355 x_restartquery:
361
364
368 }
369
370 if (qu->
state == query_tcpw) qu->
state= query_tosend;
374}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
ACPI_SIZE strlen(const char *String)
@ adns_s_rcodeformaterror
@ adns_s_rcodenotimplemented
@ adns_qf_quotefail_cname
#define memcpy(s1, s2, n)
#define LIST_UNLINK(list, node)
#define LIST_LINK_TAIL(list, node)
void adns__vbuf_init(vbuf *vb)
void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt,...)
void adns__vbuf_free(vbuf *vb)
void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt,...)
const char * adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, const byte *dgram, int dglen, int cbyte)
void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt,...)
void * adns__alloc_preserved(adns_query qu, size_t sz)
void * adns__alloc_interim(adns_query qu, size_t sz)
adns_status adns__findrr(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, unsigned long *ttl_r, int *rdlen_r, int *rdstart_r, int *ownermatchedquery_r)
void adns__query_fail(adns_query qu, adns_status stat)
void * adns__alloc_mine(adns_query qu, size_t sz)
adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, adns_queryflags flags, const byte *dgram, int dglen, int *cbyte_io, int max)
void adns__search_next(adns_state ads, adns_query qu, struct timeval now)
void adns__reset_preserved(adns_query qu)
adns_status adns__mkquery_frdgram(adns_state ads, vbuf *vb, int *id_r, const byte *qd_dgram, int qd_dglen, int qd_begin, adns_rrtype type, adns_queryflags flags)
void adns__query_send(adns_query qu, struct timeval now)
void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now)
void adns__query_done(adns_query qu)
struct adns__query::@4220 children
enum adns__query::@4219 state
union adns_answer::@4217 rrs
adns_status(* parse)(const parseinfo *pai, int cbyte, int max, void *store_r)