OpenDNSSEC-signer  2.1.6
query.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "config.h"
33 #include "daemon/dnshandler.h"
34 #include "daemon/engine.h"
35 #include "file.h"
36 #include "util.h"
37 #include "wire/axfr.h"
38 #include "wire/query.h"
39 
40 const char* query_str = "query";
41 
42 
49 {
50  query_type* q = NULL;
51  CHECKALLOC(q = (query_type*) malloc(sizeof(query_type)));
52  q->buffer = NULL;
53  q->tsig_rr = NULL;
54  q->axfr_fd = NULL;
56  if (!q->buffer) {
57  query_cleanup(q);
58  return NULL;
59  }
60  q->tsig_rr = tsig_rr_create();
61  if (!q->tsig_rr) {
62  query_cleanup(q);
63  return NULL;
64  }
65  q->edns_rr = edns_rr_create();
66  if (!q->edns_rr) {
67  query_cleanup(q);
68  return NULL;
69  }
71  return q;
72 }
73 
74 
79 void
80 query_reset(query_type* q, size_t maxlen, int is_tcp)
81 {
82  if (!q) {
83  return;
84  }
85  q->addrlen = sizeof(q->addr);
86  q->maxlen = maxlen;
87  q->reserved_space = 0;
88  buffer_clear(q->buffer);
89  tsig_rr_reset(q->tsig_rr, NULL, NULL);
91  q->tsig_prepare_it = 1;
92  q->tsig_update_it = 1;
93  q->tsig_sign_it = 1;
94  q->tcp = is_tcp;
95  /* qname, qtype, qclass */
96  q->zone = NULL;
97  /* domain, opcode, cname count, delegation, compression, temp */
98  q->axfr_is_done = 0;
99  if (q->axfr_fd) {
100  ods_fclose(q->axfr_fd);
101  q->axfr_fd = NULL;
102  }
103  q->serial = 0;
104  q->startpos = 0;
105 }
106 
107 
112 static query_state
113 query_error(query_type* q, ldns_pkt_rcode rcode)
114 {
115  size_t limit = 0;
116  if (!q) {
117  return QUERY_DISCARDED;
118  }
119  limit = buffer_limit(q->buffer);
120  buffer_clear(q->buffer);
122  buffer_pkt_set_rcode(q->buffer, rcode);
126  buffer_set_position(q->buffer, limit);
127  return QUERY_PROCESSED;
128 }
129 
130 
135 static query_state
136 query_formerr(query_type* q)
137 {
138  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
139  if (!q) {
140  return QUERY_DISCARDED;
141  }
142  opcode = buffer_pkt_opcode(q->buffer);
143  /* preserve the RD flag, clear the rest */
145  buffer_pkt_set_opcode(q->buffer, opcode);
147  ods_log_debug("[%s] formerr", query_str);
148  return query_error(q, LDNS_RCODE_FORMERR);
149 }
150 
151 
156 static query_state
157 query_servfail(query_type* q)
158 {
159  if (!q) {
160  return QUERY_DISCARDED;
161  }
162  ods_log_debug("[%s] servfail", query_str);
166  return query_error(q, LDNS_RCODE_SERVFAIL);
167 }
168 
169 
174 static query_state
175 query_notimpl(query_type* q)
176 {
177  if (!q) {
178  return QUERY_DISCARDED;
179  }
180  ods_log_debug("[%s] notimpl", query_str);
181  return query_error(q, LDNS_RCODE_NOTIMPL);
182 }
183 
184 
189 static query_state
190 query_refused(query_type* q)
191 {
192  if (!q) {
193  return QUERY_DISCARDED;
194  }
195  ods_log_debug("[%s] refused", query_str);
196  return query_error(q, LDNS_RCODE_REFUSED);
197 }
198 
199 
204 static query_state
205 query_notauth(query_type* q)
206 {
207  if (!q) {
208  return QUERY_DISCARDED;
209  }
210  ods_log_debug("[%s] notauth", query_str);
211  return query_error(q, LDNS_RCODE_NOTAUTH);
212 }
213 
214 
220 static int
221 query_parse_soa(buffer_type* buffer, uint32_t* serial)
222 {
223  ldns_rr_type type = 0;
224  ods_log_assert(buffer);
225  if (!buffer_available(buffer, 10)) {
226  ods_log_error("[%s] bad soa: packet too short", query_str);
227  return 0;
228  }
229  type = (ldns_rr_type) buffer_read_u16(buffer);
230  if (type != LDNS_RR_TYPE_SOA) {
231  ods_log_error("[%s] bad soa: rr is not soa (%d)", query_str, type);
232  return 0;
233  }
234  (void)buffer_read_u16(buffer);
235  (void)buffer_read_u32(buffer);
236  /* rdata length */
237  if (!buffer_available(buffer, buffer_read_u16(buffer))) {
238  ods_log_error("[%s] bad soa: missing rdlength", query_str);
239  return 0;
240  }
241  /* MNAME */
242  if (!buffer_skip_dname(buffer)) {
243  ods_log_error("[%s] bad soa: missing mname", query_str);
244  return 0;
245  }
246  /* RNAME */
247  if (!buffer_skip_dname(buffer)) {
248  ods_log_error("[%s] bad soa: missing rname", query_str);
249  return 0;
250  }
251  if (serial) {
252  *serial = buffer_read_u32(buffer);
253  }
254  return 1;
255 }
256 
257 
264 static query_state
265 query_process_notify(query_type* q, ldns_rr_type qtype, engine_type* engine)
266 {
267  dnsin_type* dnsin = NULL;
268  uint16_t count = 0;
269  uint16_t rrcount = 0;
270  uint32_t serial = 0;
271  size_t pos = 0;
272  char address[128];
273  if (!engine || !q || !q->zone) {
274  return QUERY_DISCARDED;
275  }
276  ods_log_assert(engine->dnshandler);
277  ods_log_assert(q->zone->name);
278  ods_log_verbose("[%s] incoming notify for zone %s", query_str,
279  q->zone->name);
280  if (buffer_pkt_rcode(q->buffer) != LDNS_RCODE_NOERROR ||
281  buffer_pkt_qr(q->buffer) ||
282  !buffer_pkt_aa(q->buffer) ||
283  buffer_pkt_tc(q->buffer) ||
284  buffer_pkt_rd(q->buffer) ||
285  buffer_pkt_ra(q->buffer) ||
286  buffer_pkt_ad(q->buffer) ||
287  buffer_pkt_cd(q->buffer) ||
288  buffer_pkt_qdcount(q->buffer) != 1 ||
289  buffer_pkt_ancount(q->buffer) > 1 ||
290  qtype != LDNS_RR_TYPE_SOA) {
291  return query_formerr(q);
292  }
293  if (!q->zone->adinbound || q->zone->adinbound->type != ADAPTER_DNS) {
294  ods_log_error("[%s] zone %s is not configured to have input dns "
295  "adapter", query_str, q->zone->name);
296  return query_notauth(q);
297  }
298  ods_log_assert(q->zone->adinbound->config);
299  dnsin = (dnsin_type*) q->zone->adinbound->config;
300  if (!acl_find(dnsin->allow_notify, &q->addr, q->tsig_rr)) {
301  if (addr2ip(q->addr, address, sizeof(address))) {
302  ods_log_info("[%s] unauthorized notify for zone %s from %s: "
303  "no acl matches", query_str, q->zone->name, address);
304  } else {
305  ods_log_info("[%s] unauthorized notify for zone %s from unknown "
306  "source: no acl matches", query_str, q->zone->name);
307  }
308  return query_notauth(q);
309  }
310  ods_log_assert(q->zone->xfrd);
311  /* skip header and question section */
313  count = buffer_pkt_qdcount(q->buffer);
314  for (rrcount = 0; rrcount < count; rrcount++) {
315  if (!buffer_skip_rr(q->buffer, 1)) {
316  if (addr2ip(q->addr, address, sizeof(address))) {
317  ods_log_info("[%s] dropped packet: zone %s received bad "
318  "notify from %s (bad question section)", query_str,
319  q->zone->name, address);
320  } else {
321  ods_log_info("[%s] dropped packet: zone %s received bad "
322  "notify from unknown source (bad question section)",
323  query_str, q->zone->name);
324  }
325  return QUERY_DISCARDED;
326  }
327  }
328  pos = buffer_position(q->buffer);
329 
330  /* examine answer section */
331  count = buffer_pkt_ancount(q->buffer);
332  if (count) {
333  if (!buffer_skip_dname(q->buffer) ||
334  !query_parse_soa(q->buffer, &serial)) {
335  if (addr2ip(q->addr, address, sizeof(address))) {
336  ods_log_info("[%s] dropped packet: zone %s received bad "
337  "notify from %s (bad soa in answer section)", query_str,
338  q->zone->name, address);
339  } else {
340  ods_log_info("[%s] dropped packet: zone %s received bad "
341  "notify from unknown source (bad soa in answer section)",
342  query_str, q->zone->name);
343  }
344  return QUERY_DISCARDED;
345  }
346 
347  pthread_mutex_lock(&q->zone->xfrd->serial_lock);
348  if (!util_serial_gt(serial, q->zone->xfrd->serial_disk)) {
349  if (addr2ip(q->addr, address, sizeof(address))) {
350  ods_log_info("[%s] ignore notify from %s: already got "
351  "zone %s serial %u on disk (received %u)", query_str,
352  address, q->zone->name, q->zone->xfrd->serial_disk,
353  serial);
354  } else {
355  ods_log_info("[%s] ignore notify: already got zone %s "
356  "serial %u on disk (received %u)", query_str,
357  q->zone->name, q->zone->xfrd->serial_disk, serial);
358  }
359  pthread_mutex_unlock(&q->zone->xfrd->serial_lock);
360  } else if (q->zone->xfrd->serial_notify_acquired) {
361  pthread_mutex_unlock(&q->zone->xfrd->serial_lock);
362  if (addr2ip(q->addr, address, sizeof(address))) {
363  ods_log_info("[%s] ignore notify from %s: zone %s "
364  "transfer in progress", query_str, address,
365  q->zone->name);
366  } else {
367  ods_log_info("[%s] ignore notify: zone %s transfer in "
368  "progress", query_str, q->zone->name);
369  }
370  } else {
371  q->zone->xfrd->serial_notify = serial;
372  q->zone->xfrd->serial_notify_acquired = time_now();
373  pthread_mutex_unlock(&q->zone->xfrd->serial_lock);
374  /* forward notify to xfrd */
375  if (addr2ip(q->addr, address, sizeof(address))) {
376  ods_log_verbose("[%s] forward notify for zone %s from client %s",
377  query_str, q->zone->name, address);
378  } else {
379  ods_log_verbose("[%s] forward notify for zone %s", query_str,
380  q->zone->name);
381  }
385  }
386  } else { /* Empty answer section, no SOA. We still need to process
387  the notify according to the RFC */
388  /* forward notify to xfrd */
389  if (addr2ip(q->addr, address, sizeof(address))) {
390  ods_log_verbose("[%s] forward notify for zone %s from client %s",
391  query_str, q->zone->name, address);
392  } else {
393  ods_log_verbose("[%s] forward notify for zone %s", query_str,
394  q->zone->name);
395  }
399  }
400 
401  /* send notify ok */
405 
406  buffer_clear(q->buffer); /* lim = pos, pos = 0; */
407  buffer_set_position(q->buffer, pos);
411  return QUERY_PROCESSED;
412 }
413 
414 
419 static query_state
420 query_process_ixfr(query_type* q)
421 {
422  uint16_t count = 0;
423  ods_log_assert(q);
424  ods_log_assert(q->buffer);
425  ods_log_assert(buffer_pkt_qdcount(q->buffer) == 1);
426  /* skip header and question section */
428  if (!buffer_skip_rr(q->buffer, 1)) {
429  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
430  "request (bad question section)", query_str, q->zone->name);
431  return QUERY_DISCARDED;
432  }
433  /* answer section is empty */
434  ods_log_assert(buffer_pkt_ancount(q->buffer) == 0);
435  /* examine auth section */
437  count = buffer_pkt_nscount(q->buffer);
438  if (count) {
439  if (!buffer_skip_dname(q->buffer) ||
440  !query_parse_soa(q->buffer, &(q->serial))) {
441  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
442  "request (bad soa in auth section)", query_str, q->zone->name);
443  return QUERY_DISCARDED;
444  }
445  ods_log_debug("[%s] found ixfr request zone %s serial=%u", query_str,
446  q->zone->name, q->serial);
447  return QUERY_PROCESSED;
448  }
449  ods_log_debug("[%s] ixfr request zone %s has no auth section", query_str,
450  q->zone->name);
451  q->serial = 0;
452  return QUERY_PROCESSED;
453 }
454 
455 
460 static int
461 response_add_rrset(response_type* r, rrset_type* rrset,
462  ldns_pkt_section section)
463 {
464  if (!r || !rrset || !section) {
465  return 0;
466  }
467  /* duplicates? */
468  r->sections[r->rrset_count] = section;
469  r->rrsets[r->rrset_count] = rrset;
470  ++r->rrset_count;
471  return 1;
472 }
473 
474 
479 static int
480 response_encode_rr(query_type* q, ldns_rr* rr, ldns_pkt_section section)
481 {
482  uint8_t *data = NULL;
483  size_t size = 0;
484  ldns_status status = LDNS_STATUS_OK;
485  ods_log_assert(q);
486  ods_log_assert(rr);
487  ods_log_assert(section);
488  status = ldns_rr2wire(&data, rr, section, &size);
489  if (status != LDNS_STATUS_OK) {
490  ods_log_error("[%s] unable to send good response: ldns_rr2wire() "
491  "failed (%s)", query_str, ldns_get_errorstr_by_id(status));
492  return 0;
493  }
494  buffer_write(q->buffer, (const void*) data, size);
495  LDNS_FREE(data);
496  return 1;
497 }
498 
499 
504 static uint16_t
505 response_encode_rrset(query_type* q, rrset_type* rrset, ldns_pkt_section section)
506 {
507  rrsig_type* rrsig;
508  uint16_t i = 0;
509  uint16_t added = 0;
510  ods_log_assert(q);
511  ods_log_assert(rrset);
512  ods_log_assert(section);
513 
514  for (i = 0; i < rrset->rr_count; i++) {
515  added += response_encode_rr(q, rrset->rrs[i].rr, section);
516  }
517  if (q->edns_rr && q->edns_rr->dnssec_ok) {
518  while((rrsig = collection_iterator(rrset->rrsigs))) {
519  added += response_encode_rr(q, rrsig->rr, section);
520  }
521  }
522  /* truncation? */
523  return added;
524 }
525 
526 
531 static void
532 response_encode(query_type* q, response_type* r)
533 {
534  uint16_t counts[LDNS_SECTION_ANY];
535  ldns_pkt_section s = LDNS_SECTION_QUESTION;
536  size_t i = 0;
537  ods_log_assert(q);
538  ods_log_assert(r);
539  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
540  counts[s] = 0;
541  }
542  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
543  for (i = 0; i < r->rrset_count; i++) {
544  if (r->sections[i] == s) {
545  counts[s] += response_encode_rrset(q, r->rrsets[i], s);
546  }
547  }
548  }
549  buffer_pkt_set_ancount(q->buffer, counts[LDNS_SECTION_ANSWER]);
550  buffer_pkt_set_nscount(q->buffer, counts[LDNS_SECTION_AUTHORITY]);
551  buffer_pkt_set_arcount(q->buffer, counts[LDNS_SECTION_ADDITIONAL]);
554 }
555 
556 
561 static query_state
562 query_response(query_type* q, ldns_rr_type qtype)
563 {
564  rrset_type* rrset = NULL;
565  response_type r;
566  if (!q || !q->zone) {
567  return QUERY_DISCARDED;
568  }
569  r.rrset_count = 0;
570  pthread_mutex_lock(&q->zone->zone_lock);
571  rrset = zone_lookup_rrset(q->zone, q->zone->apex, qtype);
572  if (rrset) {
573  if (!response_add_rrset(&r, rrset, LDNS_SECTION_ANSWER)) {
574  pthread_mutex_unlock(&q->zone->zone_lock);
575  return query_servfail(q);
576  }
577  /* NS RRset goes into Authority Section */
578  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_NS);
579  if (rrset) {
580  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
581  pthread_mutex_unlock(&q->zone->zone_lock);
582  return query_servfail(q);
583  }
584  } /* else: not having NS RRs is not fatal */
585  } else if (qtype != LDNS_RR_TYPE_SOA) {
586  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_SOA);
587  if (!rrset) {
588  pthread_mutex_unlock(&q->zone->zone_lock);
589  return query_servfail(q);
590  }
591  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
592  pthread_mutex_unlock(&q->zone->zone_lock);
593  return query_servfail(q);
594  }
595  } else {
596  pthread_mutex_unlock(&q->zone->zone_lock);
597  return query_servfail(q);
598  }
599  pthread_mutex_unlock(&q->zone->zone_lock);
600 
601  response_encode(q, &r);
602  /* compression */
603  return QUERY_PROCESSED;
604 }
605 
606 
611 void
613 {
614  uint16_t limit = 0;
615  uint16_t flags = 0;
616  ods_log_assert(q);
617  ods_log_assert(q->buffer);
618  limit = buffer_limit(q->buffer);
619  flags = buffer_pkt_flags(q->buffer);
620  flags &= 0x0100U; /* preserve the rd flag */
621  flags |= 0x8000U; /* set the qr flag */
622  buffer_pkt_set_flags(q->buffer, flags);
623  buffer_clear(q->buffer);
624  buffer_set_position(q->buffer, limit);
628 }
629 
630 
635 static query_state
636 query_process_query(query_type* q, ldns_rr_type qtype, engine_type* engine)
637 {
638  dnsout_type* dnsout = NULL;
639  if (!q || !q->zone) {
640  return QUERY_DISCARDED;
641  }
642  ods_log_assert(q->zone->name);
643  ods_log_debug("[%s] incoming query qtype=%s for zone %s", query_str,
644  rrset_type2str(qtype), q->zone->name);
645  /* sanity checks */
646  if (buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_tc(q->buffer)) {
648  return query_formerr(q);
649  }
650  if (buffer_pkt_ancount(q->buffer) != 0 ||
651  (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) {
653  return query_formerr(q);
654  }
655  /* acl */
656  if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) {
657  ods_log_error("[%s] zone %s is not configured to have output dns "
658  "adapter", query_str, q->zone->name);
659  return query_refused(q);
660  }
661  ods_log_assert(q->zone->adoutbound->config);
662  dnsout = (dnsout_type*) q->zone->adoutbound->config;
663  /* acl also in use for soa and other queries */
664  if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) {
665  ods_log_debug("[%s] zone %s acl query refused", query_str,
666  q->zone->name);
667  return query_refused(q);
668  }
669 
670  query_prepare(q);
671  /* ixfr? */
672  if (qtype == LDNS_RR_TYPE_IXFR) {
673  ods_log_assert(q->zone->name);
674  ods_log_debug("[%s] incoming ixfr request serial=%u for zone %s",
675  query_str, q->serial, q->zone->name);
676  return ixfr(q, engine);
677  }
678  /* axfr? */
679  if (qtype == LDNS_RR_TYPE_AXFR) {
680  ods_log_assert(q->zone->name);
681  ods_log_debug("[%s] incoming axfr request for zone %s",
682  query_str, q->zone->name);
683  return axfr(q, engine, 0);
684  }
685  /* (soa) query */
686  if (qtype == LDNS_RR_TYPE_SOA) {
687  ods_log_assert(q->zone->name);
688  ods_log_debug("[%s] incoming soa request for zone %s",
689  query_str, q->zone->name);
690  return soa_request(q, engine);
691  }
692  /* other qtypes */
693  return query_response(q, qtype);
694 }
695 
696 
701 static query_state
702 query_process_update(query_type* q)
703 {
704  if (!q || !q->zone) {
705  return QUERY_DISCARDED;
706  }
707  ods_log_debug("[%s] dynamic update not implemented", query_str);
708  return query_notimpl(q);
709 }
710 
711 
716 static ldns_pkt_rcode
717 query_process_tsig(query_type* q)
718 {
719  if (!q || !q->tsig_rr) {
720  return LDNS_RCODE_SERVFAIL;
721  }
722  if (q->tsig_rr->status == TSIG_ERROR) {
723  return LDNS_RCODE_FORMERR;
724  }
725  if (q->tsig_rr->status == TSIG_OK) {
726  if (!tsig_rr_lookup(q->tsig_rr)) {
727  ods_log_debug("[%s] tsig unknown key/algorithm", query_str);
728  return LDNS_RCODE_REFUSED;
729  }
734  if (!tsig_rr_verify(q->tsig_rr)) {
735  ods_log_debug("[%s] bad tsig signature", query_str);
736  return LDNS_RCODE_NOTAUTH;
737  }
738  }
739  return LDNS_RCODE_NOERROR;
740 }
741 
742 
747 static ldns_pkt_rcode
748 query_process_edns(query_type* q)
749 {
750  if (!q || !q->edns_rr) {
751  return LDNS_RCODE_SERVFAIL;
752  }
753  if (q->edns_rr->status == EDNS_ERROR) {
754  /* The only error is VERSION not implemented */
755  return LDNS_RCODE_FORMERR;
756  }
757  if (q->edns_rr->status == EDNS_OK) {
758  /* Only care about UDP size larger than normal... */
759  if (!q->tcp && q->edns_rr->maxlen > UDP_MAX_MESSAGE_LEN) {
760  if (q->edns_rr->maxlen < EDNS_MAX_MESSAGE_LEN) {
761  q->maxlen = q->edns_rr->maxlen;
762  } else {
764  }
765  }
766  /* Strip the OPT resource record off... */
770  }
771  return LDNS_RCODE_NOERROR;
772 }
773 
774 
779 static int
780 query_find_tsig(query_type* q)
781 {
782  size_t saved_pos = 0;
783  size_t rrcount = 0;
784  size_t i = 0;
785 
786  ods_log_assert(q);
787  ods_log_assert(q->tsig_rr);
788  ods_log_assert(q->buffer);
789  if (buffer_pkt_arcount(q->buffer) == 0) {
791  return 1;
792  }
793  saved_pos = buffer_position(q->buffer);
794  rrcount = buffer_pkt_qdcount(q->buffer) + buffer_pkt_ancount(q->buffer) +
797  for (i=0; i < rrcount; i++) {
798  if (!buffer_skip_rr(q->buffer, i < buffer_pkt_qdcount(q->buffer))) {
799  buffer_set_position(q->buffer, saved_pos);
800  return 0;
801  }
802  }
803 
804  rrcount = buffer_pkt_arcount(q->buffer);
805  ods_log_assert(rrcount != 0);
806  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
807  ods_log_debug("[%s] got bad tsig", query_str);
808  return 0;
809  }
810  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
811  --rrcount;
812  }
813  if (rrcount) {
814  if (edns_rr_parse(q->edns_rr, q->buffer)) {
815  --rrcount;
816  }
817  }
818  if (rrcount && q->tsig_rr->status == TSIG_NOT_PRESENT) {
819  /* see if tsig is after the edns record */
820  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
821  ods_log_debug("[%s] got bad tsig", query_str);
822  return 0;
823  }
824  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
825  --rrcount;
826  }
827  }
828  if (rrcount > 0) {
829  ods_log_debug("[%s] too many additional rrs", query_str);
830  return 0;
831  }
832  buffer_set_position(q->buffer, saved_pos);
833  return 1;
834 }
835 
836 
843 {
844  ldns_status status = LDNS_STATUS_OK;
845  ldns_pkt* pkt = NULL;
846  ldns_rr* rr = NULL;
847  ldns_pkt_rcode rcode = LDNS_RCODE_NOERROR;
848  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
849  ldns_rr_type qtype = LDNS_RR_TYPE_SOA;
850  ods_log_assert(engine);
851  ods_log_assert(q);
852  ods_log_assert(q->buffer);
854  ods_log_debug("[%s] drop query: packet too small", query_str);
855  return QUERY_DISCARDED; /* too small */
856  }
857  if (buffer_pkt_qr(q->buffer)) {
858  ods_log_debug("[%s] drop query: qr bit set", query_str);
859  return QUERY_DISCARDED; /* not a query */
860  }
861  /* parse packet */
862  status = ldns_wire2pkt(&pkt, buffer_current(q->buffer),
864  if (status != LDNS_STATUS_OK) {
865  ods_log_debug("[%s] got bad packet: %s", query_str,
866  ldns_get_errorstr_by_id(status));
867  return query_formerr(q);
868  }
869  rr = ldns_rr_list_rr(ldns_pkt_question(pkt), 0);
870  if (!rr) {
871  ods_log_debug("[%s] no RRset in query section, ignoring", query_str);
872  return QUERY_DISCARDED; /* no RRset in query */
873  }
874  pthread_mutex_lock(&engine->zonelist->zl_lock);
875  /* we can just lookup the zone, because we will only handle SOA queries,
876  zone transfers, updates and notifies */
877  q->zone = zonelist_lookup_zone_by_dname(engine->zonelist, ldns_rr_owner(rr),
878  ldns_rr_get_class(rr));
879  /* don't answer for zones that are just added */
880  if (q->zone && q->zone->zl_status == ZONE_ZL_ADDED) {
881  ods_log_assert(q->zone->name);
882  ods_log_warning("[%s] zone %s just added, don't answer for now",
883  query_str, q->zone->name);
884  q->zone = NULL;
885  }
886  pthread_mutex_unlock(&engine->zonelist->zl_lock);
887  if (!q->zone) {
888  ods_log_debug("[%s] zone not found", query_str);
889  return query_servfail(q);
890  }
891  /* see if it is tsig signed */
892  if (!query_find_tsig(q)) {
893  return query_formerr(q);
894  }
895  /* else: valid tsig, or no tsig present */
896  ods_log_debug("[%s] tsig %s", query_str, tsig_status2str(q->tsig_rr->status));
897  /* get opcode, qtype, ixfr=serial */
898  opcode = ldns_pkt_get_opcode(pkt);
899  qtype = ldns_rr_get_type(rr);
900  if (qtype == LDNS_RR_TYPE_IXFR) {
901  ods_log_assert(q->zone->name);
902  ods_log_debug("[%s] incoming ixfr request for zone %s",
903  query_str, q->zone->name);
904  if (query_process_ixfr(q) != QUERY_PROCESSED) {
905  return query_formerr(q);
906  }
907  }
908  /* process tsig */
909  rcode = query_process_tsig(q);
910  if (rcode != LDNS_RCODE_NOERROR) {
911  return query_error(q, rcode);
912  }
913  /* process edns */
914  rcode = query_process_edns(q);
915  if (rcode != LDNS_RCODE_NOERROR) {
916  /* We should not return FORMERR, but BADVERS (=16).
917  * BADVERS is created with Ext. RCODE, followed by RCODE.
918  * Ext. RCODE is set to 1, RCODE must be 0 (getting 0x10 = 16).
919  * Thus RCODE = NOERROR = NSD_RC_OK. */
920  return query_error(q, LDNS_RCODE_NOERROR);
921  }
922  /* handle incoming request */
923  ldns_pkt_free(pkt);
924  switch (opcode) {
925  case LDNS_PACKET_NOTIFY:
926  return query_process_notify(q, qtype, engine);
927  case LDNS_PACKET_QUERY:
928  return query_process_query(q, qtype, engine);
929  case LDNS_PACKET_UPDATE:
930  return query_process_update(q);
931  default:
932  break;
933  }
934  return query_notimpl(q);
935 }
936 
937 
942 static int
943 query_overflow(query_type* q)
944 {
945  ods_log_assert(q);
946  ods_log_assert(q->buffer);
947  return buffer_position(q->buffer) > (q->maxlen - q->reserved_space);
948 }
949 
950 
955 void
957 {
958  edns_data_type* edns = NULL;
959  if (!q || !engine) {
960  return;
961  }
963  if (q->edns_rr) {
964  edns = &engine->edns;
965  switch (q->edns_rr->status) {
966  case EDNS_NOT_PRESENT:
967  break;
968  case EDNS_OK:
969  ods_log_debug("[%s] add edns opt ok", query_str);
970  if (q->edns_rr->dnssec_ok) {
971  edns->ok[7] = 0x80;
972  } else {
973  edns->ok[7] = 0x00;
974  }
975  buffer_write(q->buffer, edns->ok, OPT_LEN);
976  /* fill with NULLs */
979  buffer_pkt_arcount(q->buffer) + 1);
980  break;
981  case EDNS_ERROR:
982  ods_log_debug("[%s] add edns opt err", query_str);
983  if (q->edns_rr->dnssec_ok) {
984  edns->ok[7] = 0x80;
985  } else {
986  edns->ok[7] = 0x00;
987  }
988  buffer_write(q->buffer, edns->error, OPT_LEN);
991  buffer_pkt_arcount(q->buffer) + 1);
992  break;
993  default:
994  break;
995  }
996  }
997 
999  if (!q->tsig_rr) {
1000  return;
1001  }
1002  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
1003 
1004  if (q->tsig_rr->status == TSIG_ERROR ||
1005  q->tsig_rr->error_code != LDNS_RCODE_NOERROR) {
1006  ods_log_debug("[%s] add tsig err", query_str);
1007  tsig_rr_error(q->tsig_rr);
1008  tsig_rr_append(q->tsig_rr, q->buffer);
1010  buffer_pkt_arcount(q->buffer)+1);
1011  } else if (q->tsig_rr->status == TSIG_OK &&
1012  q->tsig_rr->error_code == LDNS_RCODE_NOERROR) {
1013  ods_log_debug("[%s] add tsig ok", query_str);
1014  if (q->tsig_prepare_it)
1016  if (q->tsig_update_it)
1017  tsig_rr_update(q->tsig_rr, q->buffer,
1018  buffer_position(q->buffer));
1019  if (q->tsig_sign_it) {
1020  tsig_rr_sign(q->tsig_rr);
1021  tsig_rr_append(q->tsig_rr, q->buffer);
1023  buffer_pkt_arcount(q->buffer)+1);
1024  }
1025  }
1026  }
1027 }
1028 
1029 
1034 int
1035 query_add_rr(query_type* q, ldns_rr* rr)
1036 {
1037  size_t i = 0;
1038  size_t tc_mark = 0;
1039  size_t rdlength_pos = 0;
1040  uint16_t rdlength = 0;
1041 
1042  ods_log_assert(q);
1043  ods_log_assert(q->buffer);
1044  ods_log_assert(rr);
1045 
1046  /* set truncation mark, in case rr does not fit */
1047  tc_mark = buffer_position(q->buffer);
1048  /* owner type class ttl */
1049  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_owner(rr)))) {
1050  goto query_add_rr_tc;
1051  }
1052  buffer_write_rdf(q->buffer, ldns_rr_owner(rr));
1053  if (!buffer_available(q->buffer, sizeof(uint16_t) + sizeof(uint16_t) +
1054  sizeof(uint32_t) + sizeof(rdlength))) {
1055  goto query_add_rr_tc;
1056  }
1057  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_type(rr));
1058  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_class(rr));
1059  buffer_write_u32(q->buffer, (uint32_t) ldns_rr_ttl(rr));
1060  /* skip rdlength */
1061  rdlength_pos = buffer_position(q->buffer);
1062  buffer_skip(q->buffer, sizeof(rdlength));
1063  /* write rdata */
1064  for (i=0; i < ldns_rr_rd_count(rr); i++) {
1065  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_rdf(rr, i)))) {
1066  goto query_add_rr_tc;
1067  }
1068  buffer_write_rdf(q->buffer, ldns_rr_rdf(rr, i));
1069  }
1070 
1071  if (!query_overflow(q)) {
1072  /* write rdlength */
1073  rdlength = buffer_position(q->buffer) - rdlength_pos - sizeof(rdlength);
1074  buffer_write_u16_at(q->buffer, rdlength_pos, rdlength);
1075  /* position updated by buffer_write() */
1076  return 1;
1077  }
1078 
1079 query_add_rr_tc:
1080  buffer_set_position(q->buffer, tc_mark);
1081  ods_log_assert(!query_overflow(q));
1082  return 0;
1083 
1084 }
1085 
1086 
1091 void
1093 {
1094  if (!q) {
1095  return;
1096  }
1097  if (q->axfr_fd) {
1098  ods_fclose(q->axfr_fd);
1099  q->axfr_fd = NULL;
1100  }
1101  buffer_cleanup(q->buffer);
1104  free(q);
1105 }
TSIG_ERROR
@ TSIG_ERROR
Definition: tsig.h:58
ZONE_ZL_ADDED
@ ZONE_ZL_ADDED
Definition: zone.h:35
edns_rr_create
edns_rr_type * edns_rr_create()
Definition: edns.c:50
axfr
query_state axfr(query_type *q, engine_type *engine, int fallback)
Definition: axfr.c:152
QUERY_DISCARDED
@ QUERY_DISCARDED
Definition: query.h:48
tsig_rr_struct::error_code
uint16_t error_code
Definition: tsig.h:142
adapter_struct::type
adapter_mode type
Definition: adapter.h:58
ixfr
query_state ixfr(query_type *q, engine_type *engine)
Definition: axfr.c:389
tsig_rr_error
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:742
query_struct::addrlen
socklen_t addrlen
Definition: query.h:62
buffer_pkt_qr
int buffer_pkt_qr(buffer_type *buffer)
Definition: buffer.c:810
query_struct::axfr_is_done
unsigned axfr_is_done
Definition: query.h:85
xfrd_struct::serial_lock
pthread_mutex_t serial_lock
Definition: xfrd.h:97
buffer_pkt_ad
int buffer_pkt_ad(buffer_type *buffer)
Definition: buffer.c:930
buffer_pkt_set_ancount
void buffer_pkt_set_ancount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1030
ADAPTER_DNS
@ ADAPTER_DNS
Definition: adapter.h:42
QUERY_PROCESSED
@ QUERY_PROCESSED
Definition: query.h:47
EDNS_MAX_MESSAGE_LEN
#define EDNS_MAX_MESSAGE_LEN
Definition: edns.h:47
buffer_set_limit
void buffer_set_limit(buffer_type *buffer, size_t limit)
Definition: buffer.c:385
query_struct::tcp
int tcp
Definition: query.h:71
tsig_rr_prepare
void tsig_rr_prepare(tsig_rr_type *trr)
Definition: tsig.c:537
buffer_pkt_set_arcount
void buffer_pkt_set_arcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1078
dnshandler_fwd_notify
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
Definition: dnshandler.c:231
query_state
enum query_enum query_state
Definition: query.h:52
buffer_pkt_flags
uint16_t buffer_pkt_flags(buffer_type *buffer)
Definition: buffer.c:786
buffer_pkt_ancount
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1018
buffer_pkt_cd
int buffer_pkt_cd(buffer_type *buffer)
Definition: buffer.c:942
tsig_rr_cleanup
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition: tsig.c:832
edns_data_struct::ok
unsigned char ok[OPT_LEN]
Definition: edns.h:55
buffer_pkt_ra
int buffer_pkt_ra(buffer_type *buffer)
Definition: buffer.c:918
query_struct::axfr_fd
FILE * axfr_fd
Definition: query.h:81
zone_struct::zone_lock
pthread_mutex_t zone_lock
Definition: zone.h:86
tsig_rr_update
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition: tsig.c:559
buffer_capacity
size_t buffer_capacity(buffer_type *buffer)
Definition: buffer.c:401
query_cleanup
void query_cleanup(query_type *q)
Definition: query.c:1092
buffer_position
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:125
tsig_status2str
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:759
zonelist_struct::zl_lock
pthread_mutex_t zl_lock
Definition: zonelist.h:50
rrset_struct
Definition: rrset.h:59
buffer_begin
uint8_t * buffer_begin(buffer_type *buffer)
Definition: buffer.c:426
zone_struct::xfrd
xfrd_type * xfrd
Definition: zone.h:82
dnsin_struct
Definition: addns.h:49
buffer_pkt_tc
int buffer_pkt_tc(buffer_type *buffer)
Definition: buffer.c:894
PACKET_BUFFER_SIZE
#define PACKET_BUFFER_SIZE
Definition: buffer.h:50
edns_rr_struct::dnssec_ok
int dnssec_ok
Definition: edns.h:80
edns_data_struct::rdata_none
unsigned char rdata_none[OPT_RDATA]
Definition: edns.h:57
xfrd_struct::serial_notify_acquired
time_t serial_notify_acquired
Definition: xfrd.h:117
rrset_struct::rrs
rr_type * rrs
Definition: rrset.h:64
buffer_write_u16
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition: buffer.c:565
zone_struct::apex
ldns_rdf * apex
Definition: zone.h:61
zone_struct::name
const char * name
Definition: zone.h:69
tsig_rr_parse
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:322
zonelist_lookup_zone_by_dname
zone_type * zonelist_lookup_zone_by_dname(zonelist_type *zonelist, ldns_rdf *dname, ldns_rr_class klass)
Definition: zonelist.c:182
rrsig_struct
Definition: rrset.h:44
query.h
buffer_pkt_set_qr
void buffer_pkt_set_qr(buffer_type *buffer)
Definition: buffer.c:822
buffer_read_u32
uint32_t buffer_read_u32(buffer_type *buffer)
Definition: buffer.c:736
edns_rr_reserved_space
size_t edns_rr_reserved_space(edns_rr_type *err)
Definition: edns.c:162
edns_rr_parse
int edns_rr_parse(edns_rr_type *err, buffer_type *buffer)
Definition: edns.c:107
query_struct::edns_rr
edns_rr_type * edns_rr
Definition: query.h:69
xfrd_set_timer_now
void xfrd_set_timer_now(xfrd_type *xfrd)
Definition: xfrd.c:454
OPT_RDATA
#define OPT_RDATA
Definition: edns.h:44
zone_lookup_rrset
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
Definition: zone.c:512
edns_data_struct
Definition: edns.h:54
buffer_write_u16_at
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition: buffer.c:512
buffer_pkt_set_aa
void buffer_pkt_set_aa(buffer_type *buffer)
Definition: buffer.c:882
buffer_set_position
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:137
response_struct::sections
ldns_pkt_section sections[QUERY_RESPONSE_MAX_RRSET]
Definition: query.h:98
edns_rr_cleanup
void edns_rr_cleanup(edns_rr_type *err)
Definition: edns.c:172
buffer_pkt_opcode
ldns_pkt_opcode buffer_pkt_opcode(buffer_type *buffer)
Definition: buffer.c:846
rrsig_struct::rr
ldns_rr * rr
Definition: rrset.h:45
response_struct::rrset_count
size_t rrset_count
Definition: query.h:97
UDP_MAX_MESSAGE_LEN
#define UDP_MAX_MESSAGE_LEN
Definition: query.h:42
engine_struct::dnshandler
dnshandler_type * dnshandler
Definition: engine.h:70
buffer_pkt_set_rcode
void buffer_pkt_set_rcode(buffer_type *buffer, ldns_pkt_rcode rcode)
Definition: buffer.c:966
buffer_pkt_aa
int buffer_pkt_aa(buffer_type *buffer)
Definition: buffer.c:870
buffer_remaining
size_t buffer_remaining(buffer_type *buffer)
Definition: buffer.c:463
edns_rr_struct::position
size_t position
Definition: edns.h:78
buffer_pkt_rd
int buffer_pkt_rd(buffer_type *buffer)
Definition: buffer.c:906
buffer_pkt_nscount
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition: buffer.c:1042
OPT_LEN
#define OPT_LEN
Definition: edns.h:43
acl_find
acl_type * acl_find(acl_type *acl, struct sockaddr_storage *addr, tsig_rr_type *trr)
Definition: acl.c:437
query_struct::tsig_update_it
unsigned tsig_update_it
Definition: query.h:87
adapter_struct::config
void * config
Definition: adapter.h:61
rrset_type2str
const char * rrset_type2str(ldns_rr_type type)
Definition: rrset.c:158
buffer_skip
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition: buffer.c:150
response_struct
Definition: query.h:96
query_struct::reserved_space
size_t reserved_space
Definition: query.h:65
buffer_pkt_arcount
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition: buffer.c:1066
buffer_struct
Definition: buffer.h:112
buffer_write_rdf
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition: buffer.c:591
rr_struct::rr
ldns_rr * rr
Definition: rrset.h:52
query_add_rr
int query_add_rr(query_type *q, ldns_rr *rr)
Definition: query.c:1035
engine_struct::edns
edns_data_type edns
Definition: engine.h:72
buffer_pkt_set_flags
void buffer_pkt_set_flags(buffer_type *buffer, uint16_t flags)
Definition: buffer.c:798
tsig_rr_struct::position
size_t position
Definition: tsig.h:125
rrset_struct::rrsigs
collection_t rrsigs
Definition: rrset.h:66
edns_data_struct::error
unsigned char error[OPT_LEN]
Definition: edns.h:56
axfr.h
tsig_rr_reset
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.c:292
buffer_pkt_rcode
ldns_pkt_rcode buffer_pkt_rcode(buffer_type *buffer)
Definition: buffer.c:954
query_reset
void query_reset(query_type *q, size_t maxlen, int is_tcp)
Definition: query.c:80
dnsout_struct
Definition: addns.h:61
query_struct::maxlen
size_t maxlen
Definition: query.h:64
edns_rr_reset
void edns_rr_reset(edns_rr_type *err)
Definition: edns.c:90
query_struct::tsig_prepare_it
unsigned tsig_prepare_it
Definition: query.h:86
engine_struct
Definition: engine.h:51
TSIG_NOT_PRESENT
@ TSIG_NOT_PRESENT
Definition: tsig.h:56
addr2ip
int addr2ip(struct sockaddr_storage addr, char *ip, size_t len)
Definition: acl.c:416
tsig_rr_reserved_space
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition: tsig.c:713
edns_rr_struct::maxlen
size_t maxlen
Definition: edns.h:79
query_struct::serial
uint32_t serial
Definition: query.h:82
query_struct::buffer
buffer_type * buffer
Definition: query.h:73
buffer_create
buffer_type * buffer_create(size_t capacity)
Definition: buffer.c:78
buffer_current
uint8_t * buffer_current(buffer_type *buffer)
Definition: buffer.c:438
buffer_pkt_set_nscount
void buffer_pkt_set_nscount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1054
buffer_write
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition: buffer.c:538
tsig_rr_append
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:672
query_struct::startpos
size_t startpos
Definition: query.h:83
engine_struct::zonelist
zonelist_type * zonelist
Definition: engine.h:69
response_struct::rrsets
rrset_type * rrsets[QUERY_RESPONSE_MAX_RRSET]
Definition: query.h:99
xfrd_struct::serial_disk
uint32_t serial_disk
Definition: xfrd.h:113
EDNS_ERROR
@ EDNS_ERROR
Definition: edns.h:67
buffer_limit
size_t buffer_limit(buffer_type *buffer)
Definition: buffer.c:373
rrset_struct::rr_count
size_t rr_count
Definition: rrset.h:65
query_struct::addr
struct sockaddr_storage addr
Definition: query.h:61
EDNS_NOT_PRESENT
@ EDNS_NOT_PRESENT
Definition: edns.h:65
BUFFER_PKT_HEADER_SIZE
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:43
EDNS_OK
@ EDNS_OK
Definition: edns.h:66
query_struct
Definition: query.h:59
TSIG_OK
@ TSIG_OK
Definition: tsig.h:57
tsig_rr_create
tsig_rr_type * tsig_rr_create()
Definition: tsig.c:274
buffer_skip_dname
int buffer_skip_dname(buffer_type *buffer)
Definition: buffer.c:310
query_struct::zone
zone_type * zone
Definition: query.h:77
edns_rr_struct::status
edns_status status
Definition: edns.h:77
buffer_cleanup
void buffer_cleanup(buffer_type *buffer)
Definition: buffer.c:1145
engine.h
query_struct::tsig_rr
tsig_rr_type * tsig_rr
Definition: query.h:67
buffer_pkt_set_opcode
void buffer_pkt_set_opcode(buffer_type *buffer, ldns_pkt_opcode opcode)
Definition: buffer.c:858
buffer_read_u16
uint16_t buffer_read_u16(buffer_type *buffer)
Definition: buffer.c:721
soa_request
query_state soa_request(query_type *q, engine_type *engine)
Definition: axfr.c:53
query_add_optional
void query_add_optional(query_type *q, engine_type *engine)
Definition: query.c:956
tsig_rr_verify
int tsig_rr_verify(tsig_rr_type *trr)
Definition: tsig.c:650
query_create
query_type * query_create(void)
Definition: query.c:48
zone_struct::adoutbound
adapter_type * adoutbound
Definition: zone.h:75
buffer_clear
void buffer_clear(buffer_type *buffer)
Definition: buffer.c:99
zone_struct::zl_status
zone_zl_status zl_status
Definition: zone.h:72
query_process
query_state query_process(query_type *q, engine_type *engine)
Definition: query.c:842
buffer_write_u32
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition: buffer.c:578
tsig_rr_struct::status
tsig_status status
Definition: tsig.h:124
dnsin_struct::allow_notify
acl_type * allow_notify
Definition: addns.h:51
dnshandler.h
query_prepare
void query_prepare(query_type *q)
Definition: query.c:612
tsig_rr_lookup
int tsig_rr_lookup(tsig_rr_type *trr)
Definition: tsig.c:469
buffer_pkt_qdcount
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition: buffer.c:994
buffer_skip_rr
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition: buffer.c:342
xfrd_struct::serial_notify
uint32_t serial_notify
Definition: xfrd.h:111
zone_struct::adinbound
adapter_type * adinbound
Definition: zone.h:74
tsig_rr_sign
void tsig_rr_sign(tsig_rr_type *trr)
Definition: tsig.c:629
buffer_pkt_set_qdcount
void buffer_pkt_set_qdcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1006
dnsout_struct::provide_xfr
acl_type * provide_xfr
Definition: addns.h:62
query_struct::tsig_sign_it
unsigned tsig_sign_it
Definition: query.h:88
query_str
const char * query_str
Definition: query.c:40
buffer_available
int buffer_available(buffer_type *buffer, size_t count)
Definition: buffer.c:487