OpenDNSSEC-signer  1.4.10
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 "shared/file.h"
36 #include "shared/util.h"
37 #include "wire/axfr.h"
38 #include "wire/query.h"
39 
40 const char* query_str = "query";
41 
42 
49 {
50  allocator_type* allocator = NULL;
51  query_type* q = NULL;
52  allocator = allocator_create(malloc, free);
53  if (!allocator) {
54  return NULL;
55  }
56  q = (query_type*) allocator_alloc(allocator, sizeof(query_type));
57  if (!q) {
58  allocator_cleanup(allocator);
59  return NULL;
60  }
61  q->allocator = allocator;
62  q->buffer = NULL;
63  q->tsig_rr = NULL;
64  q->axfr_fd = NULL;
65  q->buffer = buffer_create(allocator, PACKET_BUFFER_SIZE);
66  if (!q->buffer) {
67  query_cleanup(q);
68  return NULL;
69  }
70  q->tsig_rr = tsig_rr_create(allocator);
71  if (!q->tsig_rr) {
72  query_cleanup(q);
73  return NULL;
74  }
75  q->edns_rr = edns_rr_create(allocator);
76  if (!q->edns_rr) {
77  query_cleanup(q);
78  return NULL;
79  }
81  return q;
82 }
83 
84 
89 void
90 query_reset(query_type* q, size_t maxlen, int is_tcp)
91 {
92  if (!q) {
93  return;
94  }
95  q->addrlen = sizeof(q->addr);
96  q->maxlen = maxlen;
97  q->reserved_space = 0;
98  buffer_clear(q->buffer);
99  tsig_rr_reset(q->tsig_rr, NULL, NULL);
101  q->tsig_prepare_it = 1;
102  q->tsig_update_it = 1;
103  q->tsig_sign_it = 1;
104  q->tcp = is_tcp;
105  /* qname, qtype, qclass */
106  q->zone = NULL;
107  /* domain, opcode, cname count, delegation, compression, temp */
108  q->axfr_is_done = 0;
109  if (q->axfr_fd) {
110  ods_fclose(q->axfr_fd);
111  q->axfr_fd = NULL;
112  }
113  q->serial = 0;
114  q->startpos = 0;
115  return;
116 }
117 
118 
123 static query_state
124 query_error(query_type* q, ldns_pkt_rcode rcode)
125 {
126  size_t limit = 0;
127  if (!q) {
128  return QUERY_DISCARDED;
129  }
130  limit = buffer_limit(q->buffer);
131  buffer_clear(q->buffer);
133  buffer_pkt_set_rcode(q->buffer, rcode);
137  buffer_set_position(q->buffer, limit);
138  return QUERY_PROCESSED;
139 }
140 
141 
146 static query_state
147 query_formerr(query_type* q)
148 {
149  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
150  if (!q) {
151  return QUERY_DISCARDED;
152  }
153  opcode = buffer_pkt_opcode(q->buffer);
154  /* preserve the RD flag, clear the rest */
156  buffer_pkt_set_opcode(q->buffer, opcode);
158  ods_log_debug("[%s] formerr", query_str);
159  return query_error(q, LDNS_RCODE_FORMERR);
160 }
161 
162 
167 static query_state
168 query_servfail(query_type* q)
169 {
170  if (!q) {
171  return QUERY_DISCARDED;
172  }
173  ods_log_debug("[%s] servfail", query_str);
177  return query_error(q, LDNS_RCODE_SERVFAIL);
178 }
179 
180 
185 static query_state
186 query_notimpl(query_type* q)
187 {
188  if (!q) {
189  return QUERY_DISCARDED;
190  }
191  ods_log_debug("[%s] notimpl", query_str);
192  return query_error(q, LDNS_RCODE_NOTIMPL);
193 }
194 
195 
200 static query_state
201 query_refused(query_type* q)
202 {
203  if (!q) {
204  return QUERY_DISCARDED;
205  }
206  ods_log_debug("[%s] refused", query_str);
207  return query_error(q, LDNS_RCODE_REFUSED);
208 }
209 
210 
215 static query_state
216 query_notauth(query_type* q)
217 {
218  if (!q) {
219  return QUERY_DISCARDED;
220  }
221  ods_log_debug("[%s] notauth", query_str);
222  return query_error(q, LDNS_RCODE_NOTAUTH);
223 }
224 
225 
231 static int
232 query_parse_soa(buffer_type* buffer, uint32_t* serial)
233 {
234  ldns_rr_type type = 0;
235  ods_log_assert(buffer);
236  if (!buffer_available(buffer, 10)) {
237  ods_log_error("[%s] bad soa: packet too short", query_str);
238  return 0;
239  }
240  type = (ldns_rr_type) buffer_read_u16(buffer);
241  if (type != LDNS_RR_TYPE_SOA) {
242  ods_log_error("[%s] bad soa: rr is not soa (%d)", query_str, type);
243  return 0;
244  }
245  (void)buffer_read_u16(buffer);
246  (void)buffer_read_u32(buffer);
247  /* rdata length */
248  if (!buffer_available(buffer, buffer_read_u16(buffer))) {
249  ods_log_error("[%s] bad soa: missing rdlength", query_str);
250  return 0;
251  }
252  /* MNAME */
253  if (!buffer_skip_dname(buffer)) {
254  ods_log_error("[%s] bad soa: missing mname", query_str);
255  return 0;
256  }
257  /* RNAME */
258  if (!buffer_skip_dname(buffer)) {
259  ods_log_error("[%s] bad soa: missing rname", query_str);
260  return 0;
261  }
262  if (serial) {
263  *serial = buffer_read_u32(buffer);
264  }
265  return 1;
266 }
267 
268 
275 static query_state
276 query_process_notify(query_type* q, ldns_rr_type qtype, void* engine)
277 {
278  engine_type* e = (engine_type*) engine;
279  dnsin_type* dnsin = NULL;
280  uint16_t count = 0;
281  uint16_t rrcount = 0;
282  uint32_t serial = 0;
283  size_t pos = 0;
284  char address[128];
285  if (!e || !q || !q->zone) {
286  return QUERY_DISCARDED;
287  }
289  ods_log_assert(q->zone->name);
290  ods_log_verbose("[%s] incoming notify for zone %s", query_str,
291  q->zone->name);
292  if (buffer_pkt_rcode(q->buffer) != LDNS_RCODE_NOERROR ||
293  buffer_pkt_qr(q->buffer) ||
294  !buffer_pkt_aa(q->buffer) ||
295  buffer_pkt_tc(q->buffer) ||
296  buffer_pkt_rd(q->buffer) ||
297  buffer_pkt_ra(q->buffer) ||
298  buffer_pkt_ad(q->buffer) ||
299  buffer_pkt_cd(q->buffer) ||
300  buffer_pkt_qdcount(q->buffer) != 1 ||
301  buffer_pkt_ancount(q->buffer) > 1 ||
302  qtype != LDNS_RR_TYPE_SOA) {
303  return query_formerr(q);
304  }
305  if (!q->zone->adinbound || q->zone->adinbound->type != ADAPTER_DNS) {
306  ods_log_error("[%s] zone %s is not configured to have input dns "
307  "adapter", query_str, q->zone->name);
308  return query_notauth(q);
309  }
311  dnsin = (dnsin_type*) q->zone->adinbound->config;
312  if (!acl_find(dnsin->allow_notify, &q->addr, q->tsig_rr)) {
313  if (addr2ip(q->addr, address, sizeof(address))) {
314  ods_log_info("[%s] unauthorized notify for zone %s from %s: "
315  "no acl matches", query_str, q->zone->name, address);
316  } else {
317  ods_log_info("[%s] unauthorized notify for zone %s from unknown "
318  "source: no acl matches", query_str, q->zone->name);
319  }
320  return query_notauth(q);
321  }
322  ods_log_assert(q->zone->xfrd);
323  /* skip header and question section */
325  count = buffer_pkt_qdcount(q->buffer);
326  for (rrcount = 0; rrcount < count; rrcount++) {
327  if (!buffer_skip_rr(q->buffer, 1)) {
328  if (addr2ip(q->addr, address, sizeof(address))) {
329  ods_log_info("[%s] dropped packet: zone %s received bad "
330  "notify from %s (bad question section)", query_str,
331  q->zone->name, address);
332  } else {
333  ods_log_info("[%s] dropped packet: zone %s received bad "
334  "notify from unknown source (bad question section)",
335  query_str, q->zone->name);
336  }
337  return QUERY_DISCARDED;
338  }
339  }
340  pos = buffer_position(q->buffer);
341 
342  /* examine answer section */
343  count = buffer_pkt_ancount(q->buffer);
344  if (count) {
345  if (!buffer_skip_dname(q->buffer) ||
346  !query_parse_soa(q->buffer, &serial)) {
347  if (addr2ip(q->addr, address, sizeof(address))) {
348  ods_log_info("[%s] dropped packet: zone %s received bad "
349  "notify from %s (bad soa in answer section)", query_str,
350  q->zone->name, address);
351  } else {
352  ods_log_info("[%s] dropped packet: zone %s received bad "
353  "notify from unknown source (bad soa in answer section)",
354  query_str, q->zone->name);
355  }
356  return QUERY_DISCARDED;
357  }
358 
360  if (!util_serial_gt(serial, q->zone->xfrd->serial_disk)) {
361  if (addr2ip(q->addr, address, sizeof(address))) {
362  ods_log_info("[%s] ignore notify from %s: already got "
363  "zone %s serial %u on disk (received %u)", query_str,
364  address, q->zone->name, q->zone->xfrd->serial_disk,
365  serial);
366  } else {
367  ods_log_info("[%s] ignore notify: already got zone %s "
368  "serial %u on disk (received %u)", query_str,
369  q->zone->name, q->zone->xfrd->serial_disk, serial);
370  }
372  } else if (q->zone->xfrd->serial_notify_acquired) {
374  if (addr2ip(q->addr, address, sizeof(address))) {
375  ods_log_info("[%s] ignore notify from %s: zone %s "
376  "transfer in progress", query_str, address,
377  q->zone->name);
378  } else {
379  ods_log_info("[%s] ignore notify: zone %s transfer in "
380  "progress", query_str, q->zone->name);
381  }
382  } else {
383  q->zone->xfrd->serial_notify = serial;
386  /* forward notify to xfrd */
387  if (addr2ip(q->addr, address, sizeof(address))) {
388  ods_log_verbose("[%s] forward notify for zone %s from client %s",
389  query_str, q->zone->name, address);
390  } else {
391  ods_log_verbose("[%s] forward notify for zone %s", query_str,
392  q->zone->name);
393  }
397  }
398  }
399  /* send notify ok */
403 
404  buffer_clear(q->buffer); /* lim = pos, pos = 0; */
405  buffer_set_position(q->buffer, pos);
409  return QUERY_PROCESSED;
410 }
411 
412 
417 static query_state
418 query_process_ixfr(query_type* q)
419 {
420  uint16_t count = 0;
421  ods_log_assert(q);
424  /* skip header and question section */
426  if (!buffer_skip_rr(q->buffer, 1)) {
427  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
428  "request (bad question section)", query_str, q->zone->name);
429  return QUERY_DISCARDED;
430  }
431  /* answer section is empty */
433  /* examine auth section */
435  count = buffer_pkt_nscount(q->buffer);
436  if (count) {
437  if (!buffer_skip_dname(q->buffer) ||
438  !query_parse_soa(q->buffer, &(q->serial))) {
439  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
440  "request (bad soa in auth section)", query_str, q->zone->name);
441  return QUERY_DISCARDED;
442  }
443  ods_log_debug("[%s] found ixfr request zone %s serial=%u", query_str,
444  q->zone->name, q->serial);
445  return QUERY_PROCESSED;
446  }
447  ods_log_debug("[%s] ixfr request zone %s has no auth section", query_str,
448  q->zone->name);
449  q->serial = 0;
450  return QUERY_PROCESSED;
451 }
452 
453 
458 static int
459 response_add_rrset(response_type* r, rrset_type* rrset,
460  ldns_pkt_section section)
461 {
462  if (!r || !rrset || !section) {
463  return 0;
464  }
465  /* duplicates? */
466  r->sections[r->rrset_count] = section;
467  r->rrsets[r->rrset_count] = rrset;
468  ++r->rrset_count;
469  return 1;
470 }
471 
472 
477 static int
478 response_encode_rr(query_type* q, ldns_rr* rr, ldns_pkt_section section)
479 {
480  uint8_t *data = NULL;
481  size_t size = 0;
482  ldns_status status = LDNS_STATUS_OK;
483  ods_log_assert(q);
484  ods_log_assert(rr);
485  ods_log_assert(section);
486  status = ldns_rr2wire(&data, rr, section, &size);
487  if (status != LDNS_STATUS_OK) {
488  ods_log_error("[%s] unable to send good response: ldns_rr2wire() "
489  "failed (%s)", query_str, ldns_get_errorstr_by_id(status));
490  return 0;
491  }
492  buffer_write(q->buffer, (const void*) data, size);
493  LDNS_FREE(data);
494  return 1;
495 }
496 
497 
502 static uint16_t
503 response_encode_rrset(query_type* q, rrset_type* rrset, ldns_pkt_section section)
504 {
505  uint16_t i = 0;
506  uint16_t added = 0;
507  ods_log_assert(q);
508  ods_log_assert(rrset);
509  ods_log_assert(section);
510 
511  for (i = 0; i < rrset->rr_count; i++) {
512  added += response_encode_rr(q, rrset->rrs[i].rr, section);
513  }
514  if (q->edns_rr && q->edns_rr->dnssec_ok) {
515  for (i = 0; i < rrset->rrsig_count; i++) {
516  added += response_encode_rr(q, rrset->rrsigs[i].rr, section);
517  }
518  }
519  /* truncation? */
520  return added;
521 }
522 
523 
528 static void
529 response_encode(query_type* q, response_type* r)
530 {
531  uint16_t counts[LDNS_SECTION_ANY];
532  ldns_pkt_section s = LDNS_SECTION_QUESTION;
533  size_t i = 0;
534  ods_log_assert(q);
535  ods_log_assert(r);
536  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
537  counts[s] = 0;
538  }
539  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
540  for (i = 0; i < r->rrset_count; i++) {
541  if (r->sections[i] == s) {
542  counts[s] += response_encode_rrset(q, r->rrsets[i], s);
543  }
544  }
545  }
546  buffer_pkt_set_ancount(q->buffer, counts[LDNS_SECTION_ANSWER]);
547  buffer_pkt_set_nscount(q->buffer, counts[LDNS_SECTION_AUTHORITY]);
548  buffer_pkt_set_arcount(q->buffer, counts[LDNS_SECTION_ADDITIONAL]);
551  return;
552 }
553 
554 
559 static query_state
560 query_response(query_type* q, ldns_rr_type qtype)
561 {
562  rrset_type* rrset = NULL;
563  response_type r;
564  if (!q || !q->zone) {
565  return QUERY_DISCARDED;
566  }
567  r.rrset_count = 0;
569  rrset = zone_lookup_rrset(q->zone, q->zone->apex, qtype);
570  if (rrset) {
571  if (!response_add_rrset(&r, rrset, LDNS_SECTION_ANSWER)) {
573  return query_servfail(q);
574  }
575  /* NS RRset goes into Authority Section */
576  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_NS);
577  if (rrset) {
578  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
580  return query_servfail(q);
581  }
582  }
583  } else if (qtype != LDNS_RR_TYPE_SOA) {
584  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_SOA);
585  if (rrset) {
586  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
588  return query_servfail(q);
589  }
590  }
591  } else {
593  return query_servfail(q);
594  }
596 
597  response_encode(q, &r);
598  /* compression */
599  return QUERY_PROCESSED;
600 }
601 
602 
607 void
609 {
610  uint16_t limit = 0;
611  uint16_t flags = 0;
612  ods_log_assert(q);
614  limit = buffer_limit(q->buffer);
615  flags = buffer_pkt_flags(q->buffer);
616  flags &= 0x0100U; /* preserve the rd flag */
617  flags |= 0x8000U; /* set the qr flag */
618  buffer_pkt_set_flags(q->buffer, flags);
619  buffer_clear(q->buffer);
620  buffer_set_position(q->buffer, limit);
624  return;
625 }
626 
627 
632 static query_state
633 query_process_query(query_type* q, ldns_rr_type qtype, engine_type* engine)
634 {
635  dnsout_type* dnsout = NULL;
636  if (!q || !q->zone) {
637  return QUERY_DISCARDED;
638  }
639  ods_log_assert(q->zone->name);
640  ods_log_debug("[%s] incoming query qtype=%s for zone %s", query_str,
641  rrset_type2str(qtype), q->zone->name);
642  /* sanity checks */
643  if (buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_tc(q->buffer)) {
645  return query_formerr(q);
646  }
647  if (buffer_pkt_ancount(q->buffer) != 0 ||
648  (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) {
650  return query_formerr(q);
651  }
652  /* acl */
653  if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) {
654  ods_log_error("[%s] zone %s is not configured to have output dns "
655  "adapter", query_str, q->zone->name);
656  return query_refused(q);
657  }
659  dnsout = (dnsout_type*) q->zone->adoutbound->config;
660  /* acl also in use for soa and other queries */
661  if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) {
662  ods_log_debug("[%s] zone %s acl query refused", query_str,
663  q->zone->name);
664  return query_refused(q);
665  }
666 
667  query_prepare(q);
668  /* ixfr? */
669  if (qtype == LDNS_RR_TYPE_IXFR) {
670  ods_log_assert(q->zone->name);
671  ods_log_debug("[%s] incoming ixfr request serial=%u for zone %s",
672  query_str, q->serial, q->zone->name);
673  return ixfr(q, engine);
674  }
675  /* axfr? */
676  if (qtype == LDNS_RR_TYPE_AXFR) {
677  ods_log_assert(q->zone->name);
678  ods_log_debug("[%s] incoming axfr request for zone %s",
679  query_str, q->zone->name);
680  return axfr(q, engine, 0);
681  }
682  /* (soa) query */
683  if (qtype == LDNS_RR_TYPE_SOA) {
684  ods_log_assert(q->zone->name);
685  ods_log_debug("[%s] incoming soa request for zone %s",
686  query_str, q->zone->name);
687  return soa_request(q, engine);
688  }
689  /* other qtypes */
690  return query_response(q, qtype);
691 }
692 
693 
698 static query_state
699 query_process_update(query_type* q)
700 {
701  if (!q || !q->zone) {
702  return QUERY_DISCARDED;
703  }
704  ods_log_debug("[%s] dynamic update not implemented", query_str);
705  return query_notimpl(q);
706 }
707 
708 
713 static ldns_pkt_rcode
714 query_process_tsig(query_type* q)
715 {
716  if (!q || !q->tsig_rr) {
717  return LDNS_RCODE_SERVFAIL;
718  }
719  if (q->tsig_rr->status == TSIG_ERROR) {
720  return LDNS_RCODE_FORMERR;
721  }
722  if (q->tsig_rr->status == TSIG_OK) {
723  if (!tsig_rr_lookup(q->tsig_rr)) {
724  ods_log_debug("[%s] tsig unknown key/algorithm", query_str);
725  return LDNS_RCODE_REFUSED;
726  }
731  if (!tsig_rr_verify(q->tsig_rr)) {
732  ods_log_debug("[%s] bad tsig signature", query_str);
733  return LDNS_RCODE_NOTAUTH;
734  }
735  }
736  return LDNS_RCODE_NOERROR;
737 }
738 
739 
744 static ldns_pkt_rcode
745 query_process_edns(query_type* q)
746 {
747  if (!q || !q->edns_rr) {
748  return LDNS_RCODE_SERVFAIL;
749  }
750  if (q->edns_rr->status == EDNS_ERROR) {
751  /* The only error is VERSION not implemented */
752  return LDNS_RCODE_FORMERR;
753  }
754  if (q->edns_rr->status == EDNS_OK) {
755  /* Only care about UDP size larger than normal... */
756  if (!q->tcp && q->edns_rr->maxlen > UDP_MAX_MESSAGE_LEN) {
757  if (q->edns_rr->maxlen < EDNS_MAX_MESSAGE_LEN) {
758  q->maxlen = q->edns_rr->maxlen;
759  } else {
761  }
762  }
763  /* Strip the OPT resource record off... */
767  }
768  return LDNS_RCODE_NOERROR;
769 }
770 
771 
776 static int
777 query_find_tsig(query_type* q)
778 {
779  size_t saved_pos = 0;
780  size_t rrcount = 0;
781  size_t i = 0;
782 
783  ods_log_assert(q);
786  if (buffer_pkt_arcount(q->buffer) == 0) {
788  return 1;
789  }
790  saved_pos = buffer_position(q->buffer);
791  rrcount = buffer_pkt_qdcount(q->buffer) + buffer_pkt_ancount(q->buffer) +
794  for (i=0; i < rrcount; i++) {
795  if (!buffer_skip_rr(q->buffer, i < buffer_pkt_qdcount(q->buffer))) {
796  buffer_set_position(q->buffer, saved_pos);
797  return 0;
798  }
799  }
800 
801  rrcount = buffer_pkt_arcount(q->buffer);
802  ods_log_assert(rrcount != 0);
803  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
804  ods_log_debug("[%s] got bad tsig", query_str);
805  return 0;
806  }
807  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
808  --rrcount;
809  }
810  if (rrcount) {
811  if (edns_rr_parse(q->edns_rr, q->buffer)) {
812  --rrcount;
813  }
814  }
815  if (rrcount && q->tsig_rr->status == TSIG_NOT_PRESENT) {
816  /* see if tsig is after the edns record */
817  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
818  ods_log_debug("[%s] got bad tsig", query_str);
819  return 0;
820  }
821  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
822  --rrcount;
823  }
824  }
825  if (rrcount > 0) {
826  ods_log_debug("[%s] too many additional rrs", query_str);
827  return 0;
828  }
829  buffer_set_position(q->buffer, saved_pos);
830  return 1;
831 }
832 
833 
839 query_process(query_type* q, void* engine)
840 {
841  ldns_status status = LDNS_STATUS_OK;
842  ldns_pkt* pkt = NULL;
843  ldns_rr* rr = NULL;
844  ldns_pkt_rcode rcode = LDNS_RCODE_NOERROR;
845  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
846  ldns_rr_type qtype = LDNS_RR_TYPE_SOA;
847  engine_type* e = (engine_type*) engine;
848  ods_log_assert(e);
849  ods_log_assert(q);
851  if (!e || !q || !q->buffer) {
852  ods_log_error("[%s] drop query: assertion error", query_str);
853  return QUERY_DISCARDED; /* should not happen */
854  }
856  ods_log_debug("[%s] drop query: packet too small", query_str);
857  return QUERY_DISCARDED; /* too small */
858  }
859  if (buffer_pkt_qr(q->buffer)) {
860  ods_log_debug("[%s] drop query: qr bit set", query_str);
861  return QUERY_DISCARDED; /* not a query */
862  }
863  /* parse packet */
864  status = ldns_wire2pkt(&pkt, buffer_current(q->buffer),
866  if (status != LDNS_STATUS_OK) {
867  ods_log_debug("[%s] got bad packet: %s", query_str,
868  ldns_get_errorstr_by_id(status));
869  return query_formerr(q);
870  }
871  rr = ldns_rr_list_rr(ldns_pkt_question(pkt), 0);
873  /* we can just lookup the zone, because we will only handle SOA queries,
874  zone transfers, updates and notifies */
875  q->zone = zonelist_lookup_zone_by_dname(e->zonelist, ldns_rr_owner(rr),
876  ldns_rr_get_class(rr));
877  /* don't answer for zones that are just added */
878  if (q->zone && q->zone->zl_status == ZONE_ZL_ADDED) {
879  ods_log_assert(q->zone->name);
880  ods_log_warning("[%s] zone %s just added, don't answer for now",
881  query_str, q->zone->name);
882  q->zone = NULL;
883  }
885  if (!q->zone) {
886  ods_log_debug("[%s] zone not found", query_str);
887  return query_servfail(q);
888  }
889  /* see if it is tsig signed */
890  if (!query_find_tsig(q)) {
891  return query_formerr(q);
892  }
893  /* else: valid tsig, or no tsig present */
894  ods_log_debug("[%s] tsig %s", query_str, tsig_status2str(q->tsig_rr->status));
895  /* get opcode, qtype, ixfr=serial */
896  opcode = ldns_pkt_get_opcode(pkt);
897  qtype = ldns_rr_get_type(rr);
898  if (qtype == LDNS_RR_TYPE_IXFR) {
899  ods_log_assert(q->zone->name);
900  ods_log_debug("[%s] incoming ixfr request for zone %s",
901  query_str, q->zone->name);
902  if (query_process_ixfr(q) != QUERY_PROCESSED) {
903  return query_formerr(q);
904  }
905  }
906  /* process tsig */
907  rcode = query_process_tsig(q);
908  if (rcode != LDNS_RCODE_NOERROR) {
909  return query_error(q, rcode);
910  }
911  /* process edns */
912  rcode = query_process_edns(q);
913  if (rcode != LDNS_RCODE_NOERROR) {
914  /* We should not return FORMERR, but BADVERS (=16).
915  * BADVERS is created with Ext. RCODE, followed by RCODE.
916  * Ext. RCODE is set to 1, RCODE must be 0 (getting 0x10 = 16).
917  * Thus RCODE = NOERROR = NSD_RC_OK. */
918  return query_error(q, LDNS_RCODE_NOERROR);
919  }
920  /* handle incoming request */
921  ldns_pkt_free(pkt);
922  switch (opcode) {
923  case LDNS_PACKET_NOTIFY:
924  return query_process_notify(q, qtype, engine);
925  case LDNS_PACKET_QUERY:
926  return query_process_query(q, qtype, engine);
927  case LDNS_PACKET_UPDATE:
928  return query_process_update(q);
929  default:
930  break;
931  }
932  return query_notimpl(q);
933 }
934 
935 
940 static int
941 query_overflow(query_type* q)
942 {
943  ods_log_assert(q);
945  return buffer_position(q->buffer) > (q->maxlen - q->reserved_space);
946 }
947 
948 
953 void
955 {
956  engine_type* e = (engine_type*) engine;
957  edns_data_type* edns = NULL;
958  if (!q || !e) {
959  return;
960  }
962  if (q->edns_rr) {
963  edns = &e->edns;
964  switch (q->edns_rr->status) {
965  case EDNS_NOT_PRESENT:
966  break;
967  case EDNS_OK:
968  ods_log_debug("[%s] add edns opt ok", query_str);
969  if (q->edns_rr->dnssec_ok) {
970  edns->ok[7] = 0x80;
971  } else {
972  edns->ok[7] = 0x00;
973  }
974  buffer_write(q->buffer, edns->ok, OPT_LEN);
975  /* fill with NULLs */
978  buffer_pkt_arcount(q->buffer) + 1);
979  break;
980  case EDNS_ERROR:
981  ods_log_debug("[%s] add edns opt err", query_str);
982  if (q->edns_rr->dnssec_ok) {
983  edns->ok[7] = 0x80;
984  } else {
985  edns->ok[7] = 0x00;
986  }
987  buffer_write(q->buffer, edns->error, OPT_LEN);
990  buffer_pkt_arcount(q->buffer) + 1);
991  break;
992  default:
993  break;
994  }
995  }
996 
998  if (!q->tsig_rr) {
999  return;
1000  }
1001  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
1002 
1003  if (q->tsig_rr->status == TSIG_ERROR ||
1004  q->tsig_rr->error_code != LDNS_RCODE_NOERROR) {
1005  ods_log_debug("[%s] add tsig err", query_str);
1006  tsig_rr_error(q->tsig_rr);
1007  tsig_rr_append(q->tsig_rr, q->buffer);
1009  buffer_pkt_arcount(q->buffer)+1);
1010  } else if (q->tsig_rr->status == TSIG_OK &&
1011  q->tsig_rr->error_code == LDNS_RCODE_NOERROR) {
1012  ods_log_debug("[%s] add tsig ok", query_str);
1013  if (q->tsig_prepare_it)
1015  if (q->tsig_update_it)
1016  tsig_rr_update(q->tsig_rr, q->buffer,
1017  buffer_position(q->buffer));
1018  if (q->tsig_sign_it) {
1019  tsig_rr_sign(q->tsig_rr);
1020  tsig_rr_append(q->tsig_rr, q->buffer);
1022  buffer_pkt_arcount(q->buffer)+1);
1023  }
1024  }
1025  }
1026  return;
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  allocator_type* allocator = NULL;
1095  if (!q) {
1096  return;
1097  }
1098  allocator = q->allocator;
1099  if (q->axfr_fd) {
1100  ods_fclose(q->axfr_fd);
1101  q->axfr_fd = NULL;
1102  }
1103  buffer_cleanup(q->buffer, allocator);
1105  allocator_deallocate(allocator, (void*)q);
1106  allocator_cleanup(allocator);
1107  return;
1108 }
edns_data_type edns
Definition: engine.h:66
ldns_pkt_opcode buffer_pkt_opcode(buffer_type *buffer)
Definition: buffer.c:910
query_type * query_create(void)
Definition: query.c:48
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition: tsig.c:605
size_t maxlen
Definition: query.h:66
zonelist_type * zonelist
Definition: engine.h:60
tsig_status status
Definition: tsig.h:126
size_t rr_count
Definition: rrset.h:79
int edns_rr_parse(edns_rr_type *err, buffer_type *buffer)
Definition: edns.c:118
int buffer_pkt_rd(buffer_type *buffer)
Definition: buffer.c:972
unsigned tsig_sign_it
Definition: query.h:90
const char * rrset_type2str(ldns_rr_type type)
Definition: rrset.c:160
int tcp
Definition: query.h:73
void query_cleanup(query_type *q)
Definition: query.c:1092
void * config
Definition: adapter.h:61
void ods_log_debug(const char *format,...)
Definition: log.c:270
tsig_rr_type * tsig_rr
Definition: query.h:69
#define UDP_MAX_MESSAGE_LEN
Definition: query.h:42
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:364
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition: buffer.c:1136
zone_type * zone
Definition: query.h:79
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:43
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:66
uint16_t error_code
Definition: tsig.h:144
void edns_rr_reset(edns_rr_type *err)
Definition: edns.c:100
const char * query_str
Definition: query.c:40
uint32_t serial_notify
Definition: xfrd.h:110
unsigned tsig_update_it
Definition: query.h:89
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition: buffer.c:1061
#define OPT_RDATA
Definition: edns.h:44
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition: buffer.c:186
void buffer_pkt_set_flags(buffer_type *buffer, uint16_t flags)
Definition: buffer.c:859
uint16_t buffer_read_u16(buffer_type *buffer)
Definition: buffer.c:781
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition: buffer.c:380
void buffer_pkt_set_qdcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1073
void buffer_clear(buffer_type *buffer)
Definition: buffer.c:119
void ods_log_info(const char *format,...)
Definition: log.c:302
time_t serial_notify_acquired
Definition: xfrd.h:116
size_t rrset_count
Definition: query.h:99
lock_basic_type zone_lock
Definition: zone.h:95
void ods_log_error(const char *format,...)
Definition: log.c:334
size_t position
Definition: edns.h:79
adapter_mode type
Definition: adapter.h:58
zone_zl_status zl_status
Definition: zone.h:79
size_t reserved_space
Definition: query.h:67
void query_reset(query_type *q, size_t maxlen, int is_tcp)
Definition: query.c:90
int buffer_pkt_qr(buffer_type *buffer)
Definition: buffer.c:872
edns_rr_type * edns_rr
Definition: query.h:71
int dnssec_ok
Definition: edns.h:81
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.c:333
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:721
unsigned tsig_prepare_it
Definition: query.h:88
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition: buffer.c:592
struct sockaddr_storage addr
Definition: query.h:63
rrset_type * rrsets[QUERY_RESPONSE_MAX_RRSET]
Definition: query.h:101
lock_basic_type serial_lock
Definition: xfrd.h:96
uint8_t * buffer_current(buffer_type *buffer)
Definition: buffer.c:489
adapter_type * adoutbound
Definition: zone.h:82
int util_serial_gt(uint32_t serial_new, uint32_t serial_old)
Definition: util.c:72
buffer_type * buffer_create(allocator_type *allocator, size_t capacity)
Definition: buffer.c:78
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1086
size_t buffer_limit(buffer_type *buffer)
Definition: buffer.c:411
edns_rr_type * edns_rr_create(allocator_type *allocator)
Definition: edns.c:50
void tsig_rr_prepare(tsig_rr_type *trr)
Definition: tsig.c:580
void buffer_pkt_set_ancount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1098
#define lock_basic_lock(lock)
Definition: locks.h:94
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:810
void buffer_pkt_set_nscount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1123
allocator_type * allocator
Definition: query.h:61
void buffer_set_limit(buffer_type *buffer, size_t limit)
Definition: buffer.c:423
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
Definition: allocator.c:47
zone_type * zonelist_lookup_zone_by_dname(zonelist_type *zonelist, ldns_rdf *dname, ldns_rr_class klass)
Definition: zonelist.c:186
acl_type * provide_xfr
Definition: addns.h:65
uint16_t buffer_pkt_flags(buffer_type *buffer)
Definition: buffer.c:847
query_state axfr(query_type *q, engine_type *engine, int fallback)
Definition: axfr.c:152
ldns_rr * rr
Definition: rrset.h:48
Definition: edns.h:66
Definition: tsig.h:58
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition: tsig.c:884
query_state query_process(query_type *q, void *engine)
Definition: query.c:839
adapter_type * adinbound
Definition: zone.h:81
size_t buffer_capacity(buffer_type *buffer)
Definition: buffer.c:440
int buffer_skip_dname(buffer_type *buffer)
Definition: buffer.c:348
acl_type * allow_notify
Definition: addns.h:53
uint32_t buffer_read_u32(buffer_type *buffer)
Definition: buffer.c:796
void buffer_pkt_set_opcode(buffer_type *buffer, ldns_pkt_opcode opcode)
Definition: buffer.c:922
uint32_t serial
Definition: query.h:84
enum query_enum query_state
Definition: query.h:52
buffer_type * buffer
Definition: query.h:75
#define PACKET_BUFFER_SIZE
Definition: buffer.h:50
#define EDNS_MAX_MESSAGE_LEN
Definition: edns.h:47
int tsig_rr_verify(tsig_rr_type *trr)
Definition: tsig.c:699
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition: buffer.c:621
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition: buffer.c:635
void buffer_pkt_set_aa(buffer_type *buffer)
Definition: buffer.c:947
tsig_rr_type * tsig_rr_create(allocator_type *allocator)
Definition: tsig.c:306
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:792
size_t startpos
Definition: query.h:85
unsigned axfr_is_done
Definition: query.h:87
int buffer_pkt_aa(buffer_type *buffer)
Definition: buffer.c:935
query_state ixfr(query_type *q, engine_type *engine)
Definition: axfr.c:387
ldns_rr * rr
Definition: rrset.h:60
void ods_log_verbose(const char *format,...)
Definition: log.c:286
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition: buffer.c:1111
acl_type * acl_find(acl_type *acl, struct sockaddr_storage *addr, tsig_rr_type *trr)
Definition: acl.c:445
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
Definition: zone.c:548
size_t position
Definition: tsig.h:127
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition: buffer.c:564
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:172
void ods_fclose(FILE *fd)
Definition: file.c:250
socklen_t addrlen
Definition: query.h:64
void xfrd_set_timer_now(xfrd_type *xfrd)
Definition: xfrd.c:472
int buffer_available(buffer_type *buffer, size_t count)
Definition: buffer.c:538
size_t maxlen
Definition: edns.h:80
int buffer_pkt_ad(buffer_type *buffer)
Definition: buffer.c:996
void allocator_cleanup(allocator_type *allocator)
Definition: allocator.c:151
const char * name
Definition: zone.h:76
int tsig_rr_lookup(tsig_rr_type *trr)
Definition: tsig.c:511
size_t buffer_remaining(buffer_type *buffer)
Definition: buffer.c:514
void buffer_pkt_set_rcode(buffer_type *buffer, ldns_pkt_rcode rcode)
Definition: buffer.c:1032
#define OPT_LEN
Definition: edns.h:43
query_state soa_request(query_type *q, engine_type *engine)
Definition: axfr.c:53
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition: buffer.c:649
size_t rrsig_count
Definition: rrset.h:80
int buffer_pkt_ra(buffer_type *buffer)
Definition: buffer.c:984
void tsig_rr_sign(tsig_rr_type *trr)
Definition: tsig.c:677
void query_prepare(query_type *q)
Definition: query.c:608
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:135
int query_add_rr(query_type *q, ldns_rr *rr)
Definition: query.c:1035
size_t edns_rr_reserved_space(edns_rr_type *err)
Definition: edns.c:171
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:160
FILE * axfr_fd
Definition: query.h:83
unsigned char error[OPT_LEN]
Definition: edns.h:56
void buffer_cleanup(buffer_type *buffer, allocator_type *allocator)
Definition: buffer.c:1261
unsigned char ok[OPT_LEN]
Definition: edns.h:55
void buffer_pkt_set_arcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1148
rrsig_type * rrsigs
Definition: rrset.h:78
#define ods_log_assert(x)
Definition: log.h:154
edns_status status
Definition: edns.h:78
int buffer_pkt_cd(buffer_type *buffer)
Definition: buffer.c:1008
xfrd_type * xfrd
Definition: zone.h:89
ldns_pkt_section sections[QUERY_RESPONSE_MAX_RRSET]
Definition: query.h:100
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
Definition: dnshandler.c:247
int addr2ip(struct sockaddr_storage addr, char *ip, size_t len)
Definition: acl.c:424
#define lock_basic_unlock(lock)
Definition: locks.h:95
void ods_log_warning(const char *format,...)
Definition: log.c:318
ldns_rdf * apex
Definition: zone.h:68
lock_basic_type zl_lock
Definition: zonelist.h:55
unsigned char rdata_none[OPT_RDATA]
Definition: edns.h:57
void buffer_pkt_set_qr(buffer_type *buffer)
Definition: buffer.c:884
uint8_t * buffer_begin(buffer_type *buffer)
Definition: buffer.c:465
time_t time_now(void)
Definition: duration.c:513
uint32_t serial_disk
Definition: xfrd.h:112
ldns_pkt_rcode buffer_pkt_rcode(buffer_type *buffer)
Definition: buffer.c:1020
dnshandler_type * dnshandler
Definition: engine.h:64
int buffer_pkt_tc(buffer_type *buffer)
Definition: buffer.c:960
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition: tsig.c:763
rr_type * rrs
Definition: rrset.h:77
void query_add_optional(query_type *q, void *engine)
Definition: query.c:954