OpenDNSSEC-signer  1.4.7
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 
273 static query_state
274 query_process_notify(query_type* q, ldns_rr_type qtype, void* engine)
275 {
276  engine_type* e = (engine_type*) engine;
277  dnsin_type* dnsin = NULL;
278  uint16_t count = 0;
279  uint16_t rrcount = 0;
280  uint32_t serial = 0;
281  size_t pos = 0;
282  char address[128];
283  if (!e || !q || !q->zone) {
284  return QUERY_DISCARDED;
285  }
287  ods_log_assert(q->zone->name);
288  ods_log_verbose("[%s] incoming notify for zone %s", query_str,
289  q->zone->name);
290  if (buffer_pkt_rcode(q->buffer) != LDNS_RCODE_NOERROR ||
291  buffer_pkt_qr(q->buffer) ||
292  !buffer_pkt_aa(q->buffer) ||
293  buffer_pkt_tc(q->buffer) ||
294  buffer_pkt_rd(q->buffer) ||
295  buffer_pkt_ra(q->buffer) ||
296  buffer_pkt_ad(q->buffer) ||
297  buffer_pkt_cd(q->buffer) ||
298  buffer_pkt_qdcount(q->buffer) != 1 ||
299  buffer_pkt_ancount(q->buffer) > 1 ||
300  qtype != LDNS_RR_TYPE_SOA) {
301  return query_formerr(q);
302  }
303  if (!q->zone->adinbound || q->zone->adinbound->type != ADAPTER_DNS) {
304  ods_log_error("[%s] zone %s is not configured to have input dns "
305  "adapter", query_str, q->zone->name);
306  return query_notauth(q);
307  }
309  dnsin = (dnsin_type*) q->zone->adinbound->config;
310  if (!acl_find(dnsin->allow_notify, &q->addr, q->tsig_rr)) {
311  if (addr2ip(q->addr, address, sizeof(address))) {
312  ods_log_info("[%s] unauthorized notify for zone %s from %s: "
313  "no acl matches", query_str, q->zone->name, address);
314  } else {
315  ods_log_info("[%s] unauthorized notify for zone %s from unknown "
316  "source: no acl matches", query_str, q->zone->name);
317  }
318  return query_notauth(q);
319  }
320  ods_log_assert(q->zone->xfrd);
321  /* skip header and question section */
323  count = buffer_pkt_qdcount(q->buffer);
324  for (rrcount = 0; rrcount < count; rrcount++) {
325  if (!buffer_skip_rr(q->buffer, 1)) {
326  if (addr2ip(q->addr, address, sizeof(address))) {
327  ods_log_info("[%s] dropped packet: zone %s received bad "
328  "notify from %s (bad question section)", query_str,
329  q->zone->name, address);
330  } else {
331  ods_log_info("[%s] dropped packet: zone %s received bad "
332  "notify from unknown source (bad question section)",
333  query_str, q->zone->name);
334  }
335  return QUERY_DISCARDED;
336  }
337  }
338  pos = buffer_position(q->buffer);
339 
340  /* examine answer section */
341  count = buffer_pkt_ancount(q->buffer);
342  if (count) {
343  if (!buffer_skip_dname(q->buffer) ||
344  !query_parse_soa(q->buffer, &serial)) {
345  if (addr2ip(q->addr, address, sizeof(address))) {
346  ods_log_info("[%s] dropped packet: zone %s received bad "
347  "notify from %s (bad soa in answer section)", query_str,
348  q->zone->name, address);
349  } else {
350  ods_log_info("[%s] dropped packet: zone %s received bad "
351  "notify from unknown source (bad soa in answer section)",
352  query_str, q->zone->name);
353  }
354  return QUERY_DISCARDED;
355  }
357  if (q->zone->xfrd->serial_notify_acquired) {
359  q->zone->xfrd->serial_disk)) {
360 
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", query_str, address,
364  q->zone->name, q->zone->xfrd->serial_notify);
365  } else {
366  ods_log_info("[%s] ignore notify: already got zone %s "
367  "serial %u on disk", query_str, q->zone->name,
368  q->zone->xfrd->serial_notify);
369  }
371  } else {
372  if (addr2ip(q->addr, address, sizeof(address))) {
373  ods_log_info("[%s] ignore notify from %s: zone %s "
374  "transfer in progress", query_str, address,
375  q->zone->name);
376  } else {
377  ods_log_info("[%s] ignore notify: zone %s transfer in "
378  "progress", query_str, q->zone->name);
379  }
380  /* update values */
381  q->zone->xfrd->serial_notify = serial;
383  }
385  goto send_notify_ok;
386  }
387  q->zone->xfrd->serial_notify = serial;
390  }
391 
392  /* forward notify to xfrd */
393  if (addr2ip(q->addr, address, sizeof(address))) {
394  ods_log_verbose("[%s] forward notify for zone %s from client %s",
395  query_str, q->zone->name, address);
396  } else {
397  ods_log_verbose("[%s] forward notify for zone %s", query_str,
398  q->zone->name);
399  }
403 
404 send_notify_ok:
405  /* send notify ok */
409 
410  buffer_clear(q->buffer); /* lim = pos, pos = 0; */
411  buffer_set_position(q->buffer, pos);
415  return QUERY_PROCESSED;
416 }
417 
418 
423 static query_state
424 query_process_ixfr(query_type* q)
425 {
426  uint16_t count = 0;
427  ods_log_assert(q);
430  /* skip header and question section */
432  if (!buffer_skip_rr(q->buffer, 1)) {
433  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
434  "request (bad question section)", query_str, q->zone->name);
435  return QUERY_DISCARDED;
436  }
437  /* answer section is empty */
439  /* examine auth section */
441  count = buffer_pkt_nscount(q->buffer);
442  if (count) {
443  if (!buffer_skip_dname(q->buffer) ||
444  !query_parse_soa(q->buffer, &(q->serial))) {
445  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
446  "request (bad soa in auth section)", query_str, q->zone->name);
447  return QUERY_DISCARDED;
448  }
449  ods_log_debug("[%s] found ixfr request zone %s serial=%u", query_str,
450  q->zone->name, q->serial);
451  return QUERY_PROCESSED;
452  }
453  ods_log_debug("[%s] ixfr request zone %s has no auth section", query_str,
454  q->zone->name);
455  q->serial = 0;
456  return QUERY_PROCESSED;
457 }
458 
459 
464 static int
465 response_add_rrset(response_type* r, rrset_type* rrset,
466  ldns_pkt_section section)
467 {
468  if (!r || !rrset || !section) {
469  return 0;
470  }
471  /* duplicates? */
472  r->sections[r->rrset_count] = section;
473  r->rrsets[r->rrset_count] = rrset;
474  ++r->rrset_count;
475  return 1;
476 }
477 
478 
483 static int
484 response_encode_rr(query_type* q, ldns_rr* rr, ldns_pkt_section section)
485 {
486  uint8_t *data = NULL;
487  size_t size = 0;
488  ldns_status status = LDNS_STATUS_OK;
489  ods_log_assert(q);
490  ods_log_assert(rr);
491  ods_log_assert(section);
492  status = ldns_rr2wire(&data, rr, section, &size);
493  if (status != LDNS_STATUS_OK) {
494  ods_log_error("[%s] unable to send good response: ldns_rr2wire() "
495  "failed (%s)", query_str, ldns_get_errorstr_by_id(status));
496  return 0;
497  }
498  buffer_write(q->buffer, (const void*) data, size);
499  LDNS_FREE(data);
500  return 1;
501 }
502 
503 
508 static uint16_t
509 response_encode_rrset(query_type* q, rrset_type* rrset, ldns_pkt_section section)
510 {
511  uint16_t i = 0;
512  uint16_t added = 0;
513  ods_log_assert(q);
514  ods_log_assert(rrset);
515  ods_log_assert(section);
516 
517  for (i = 0; i < rrset->rr_count; i++) {
518  added += response_encode_rr(q, rrset->rrs[i].rr, section);
519  }
520  if (q->edns_rr && q->edns_rr->dnssec_ok) {
521  for (i = 0; i < rrset->rrsig_count; i++) {
522  added += response_encode_rr(q, rrset->rrsigs[i].rr, section);
523  }
524  }
525  /* truncation? */
526  return added;
527 }
528 
529 
534 static void
535 response_encode(query_type* q, response_type* r)
536 {
537  uint16_t counts[LDNS_SECTION_ANY];
538  ldns_pkt_section s = LDNS_SECTION_QUESTION;
539  size_t i = 0;
540  ods_log_assert(q);
541  ods_log_assert(r);
542  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
543  counts[s] = 0;
544  }
545  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
546  for (i = 0; i < r->rrset_count; i++) {
547  if (r->sections[i] == s) {
548  counts[s] += response_encode_rrset(q, r->rrsets[i], s);
549  }
550  }
551  }
552  buffer_pkt_set_ancount(q->buffer, counts[LDNS_SECTION_ANSWER]);
553  buffer_pkt_set_nscount(q->buffer, counts[LDNS_SECTION_AUTHORITY]);
554  buffer_pkt_set_arcount(q->buffer, counts[LDNS_SECTION_ADDITIONAL]);
557  return;
558 }
559 
560 
565 static query_state
566 query_response(query_type* q, ldns_rr_type qtype)
567 {
568  rrset_type* rrset = NULL;
569  response_type r;
570  if (!q || !q->zone) {
571  return QUERY_DISCARDED;
572  }
573  r.rrset_count = 0;
575  rrset = zone_lookup_rrset(q->zone, q->zone->apex, qtype);
576  if (rrset) {
577  if (!response_add_rrset(&r, rrset, LDNS_SECTION_ANSWER)) {
579  return query_servfail(q);
580  }
581  /* NS RRset goes into Authority Section */
582  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_NS);
583  if (rrset) {
584  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
586  return query_servfail(q);
587  }
588  }
589  } else if (qtype != LDNS_RR_TYPE_SOA) {
590  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_SOA);
591  if (rrset) {
592  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
594  return query_servfail(q);
595  }
596  }
597  } else {
599  return query_servfail(q);
600  }
602 
603  response_encode(q, &r);
604  /* compression */
605  return QUERY_PROCESSED;
606 }
607 
608 
613 void
615 {
616  uint16_t limit = 0;
617  uint16_t flags = 0;
618  ods_log_assert(q);
620  limit = buffer_limit(q->buffer);
621  flags = buffer_pkt_flags(q->buffer);
622  flags &= 0x0100U; /* preserve the rd flag */
623  flags |= 0x8000U; /* set the qr flag */
624  buffer_pkt_set_flags(q->buffer, flags);
625  buffer_clear(q->buffer);
626  buffer_set_position(q->buffer, limit);
630  return;
631 }
632 
633 
638 static query_state
639 query_process_query(query_type* q, ldns_rr_type qtype, engine_type* engine)
640 {
641  dnsout_type* dnsout = NULL;
642  if (!q || !q->zone) {
643  return QUERY_DISCARDED;
644  }
645  ods_log_assert(q->zone->name);
646  ods_log_debug("[%s] incoming query qtype=%s for zone %s", query_str,
647  rrset_type2str(qtype), q->zone->name);
648  /* sanity checks */
649  if (buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_tc(q->buffer)) {
651  return query_formerr(q);
652  }
653  if (buffer_pkt_ancount(q->buffer) != 0 ||
654  (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) {
656  return query_formerr(q);
657  }
658  /* acl */
659  if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) {
660  ods_log_error("[%s] zone %s is not configured to have output dns "
661  "adapter", query_str, q->zone->name);
662  return query_refused(q);
663  }
665  dnsout = (dnsout_type*) q->zone->adoutbound->config;
666  /* acl also in use for soa and other queries */
667  if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) {
668  ods_log_debug("[%s] zone %s acl query refused", query_str,
669  q->zone->name);
670  return query_refused(q);
671  }
672 
673  query_prepare(q);
674  /* ixfr? */
675  if (qtype == LDNS_RR_TYPE_IXFR) {
676  ods_log_assert(q->zone->name);
677  ods_log_debug("[%s] incoming ixfr request serial=%u for zone %s",
678  query_str, q->serial, q->zone->name);
679  return ixfr(q, engine);
680  }
681  /* axfr? */
682  if (qtype == LDNS_RR_TYPE_AXFR) {
683  ods_log_assert(q->zone->name);
684  ods_log_debug("[%s] incoming axfr request for zone %s",
685  query_str, q->zone->name);
686  return axfr(q, engine, 0);
687  }
688  /* (soa) query */
689  if (qtype == LDNS_RR_TYPE_SOA) {
690  ods_log_assert(q->zone->name);
691  ods_log_debug("[%s] incoming soa request for zone %s",
692  query_str, q->zone->name);
693  return soa_request(q, engine);
694  }
695  /* other qtypes */
696  return query_response(q, qtype);
697 }
698 
699 
704 static query_state
705 query_process_update(query_type* q)
706 {
707  if (!q || !q->zone) {
708  return QUERY_DISCARDED;
709  }
710  ods_log_debug("[%s] dynamic update not implemented", query_str);
711  return query_notimpl(q);
712 }
713 
714 
719 static ldns_pkt_rcode
720 query_process_tsig(query_type* q)
721 {
722  if (!q || !q->tsig_rr) {
723  return LDNS_RCODE_SERVFAIL;
724  }
725  if (q->tsig_rr->status == TSIG_ERROR) {
726  return LDNS_RCODE_FORMERR;
727  }
728  if (q->tsig_rr->status == TSIG_OK) {
729  if (!tsig_rr_lookup(q->tsig_rr)) {
730  ods_log_debug("[%s] tsig unknown key/algorithm", query_str);
731  return LDNS_RCODE_REFUSED;
732  }
737  if (!tsig_rr_verify(q->tsig_rr)) {
738  ods_log_debug("[%s] bad tsig signature", query_str);
739  return LDNS_RCODE_NOTAUTH;
740  }
741  }
742  return LDNS_RCODE_NOERROR;
743 }
744 
745 
750 static ldns_pkt_rcode
751 query_process_edns(query_type* q)
752 {
753  if (!q || !q->edns_rr) {
754  return LDNS_RCODE_SERVFAIL;
755  }
756  if (q->edns_rr->status == EDNS_ERROR) {
757  /* The only error is VERSION not implemented */
758  return LDNS_RCODE_FORMERR;
759  }
760  if (q->edns_rr->status == EDNS_OK) {
761  /* Only care about UDP size larger than normal... */
762  if (!q->tcp && q->edns_rr->maxlen > UDP_MAX_MESSAGE_LEN) {
763  if (q->edns_rr->maxlen < EDNS_MAX_MESSAGE_LEN) {
764  q->maxlen = q->edns_rr->maxlen;
765  } else {
767  }
768  }
769  /* Strip the OPT resource record off... */
773  }
774  return LDNS_RCODE_NOERROR;
775 }
776 
777 
782 static int
783 query_find_tsig(query_type* q)
784 {
785  size_t saved_pos = 0;
786  size_t rrcount = 0;
787  size_t i = 0;
788 
789  ods_log_assert(q);
792  if (buffer_pkt_arcount(q->buffer) == 0) {
794  return 1;
795  }
796  saved_pos = buffer_position(q->buffer);
797  rrcount = buffer_pkt_qdcount(q->buffer) + buffer_pkt_ancount(q->buffer) +
800  for (i=0; i < rrcount; i++) {
801  if (!buffer_skip_rr(q->buffer, i < buffer_pkt_qdcount(q->buffer))) {
802  buffer_set_position(q->buffer, saved_pos);
803  return 0;
804  }
805  }
806 
807  rrcount = buffer_pkt_arcount(q->buffer);
808  ods_log_assert(rrcount != 0);
809  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
810  ods_log_debug("[%s] got bad tsig", query_str);
811  return 0;
812  }
813  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
814  --rrcount;
815  }
816  if (rrcount) {
817  if (edns_rr_parse(q->edns_rr, q->buffer)) {
818  --rrcount;
819  }
820  }
821  if (rrcount && q->tsig_rr->status == TSIG_NOT_PRESENT) {
822  /* see if tsig is after the edns record */
823  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
824  ods_log_debug("[%s] got bad tsig", query_str);
825  return 0;
826  }
827  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
828  --rrcount;
829  }
830  }
831  if (rrcount > 0) {
832  ods_log_debug("[%s] too many additional rrs", query_str);
833  return 0;
834  }
835  buffer_set_position(q->buffer, saved_pos);
836  return 1;
837 }
838 
839 
845 query_process(query_type* q, void* engine)
846 {
847  ldns_status status = LDNS_STATUS_OK;
848  ldns_pkt* pkt = NULL;
849  ldns_rr* rr = NULL;
850  ldns_pkt_rcode rcode = LDNS_RCODE_NOERROR;
851  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
852  ldns_rr_type qtype = LDNS_RR_TYPE_SOA;
853  engine_type* e = (engine_type*) engine;
854  ods_log_assert(e);
855  ods_log_assert(q);
857  if (!e || !q || !q->buffer) {
858  ods_log_error("[%s] drop query: assertion error", query_str);
859  return QUERY_DISCARDED; /* should not happen */
860  }
862  ods_log_debug("[%s] drop query: packet too small", query_str);
863  return QUERY_DISCARDED; /* too small */
864  }
865  if (buffer_pkt_qr(q->buffer)) {
866  ods_log_debug("[%s] drop query: qr bit set", query_str);
867  return QUERY_DISCARDED; /* not a query */
868  }
869  /* parse packet */
870  status = ldns_wire2pkt(&pkt, buffer_current(q->buffer),
872  if (status != LDNS_STATUS_OK) {
873  ods_log_debug("[%s] got bad packet: %s", query_str,
874  ldns_get_errorstr_by_id(status));
875  return query_formerr(q);
876  }
877  rr = ldns_rr_list_rr(ldns_pkt_question(pkt), 0);
879  /* we can just lookup the zone, because we will only handle SOA queries,
880  zone transfers, updates and notifies */
881  q->zone = zonelist_lookup_zone_by_dname(e->zonelist, ldns_rr_owner(rr),
882  ldns_rr_get_class(rr));
883  /* don't answer for zones that are just added */
884  if (q->zone && q->zone->zl_status == ZONE_ZL_ADDED) {
885  ods_log_assert(q->zone->name);
886  ods_log_warning("[%s] zone %s just added, don't answer for now",
887  query_str, q->zone->name);
888  q->zone = NULL;
889  }
891  if (!q->zone) {
892  ods_log_debug("[%s] zone not found", query_str);
893  return query_servfail(q);
894  }
895  /* see if it is tsig signed */
896  if (!query_find_tsig(q)) {
897  return query_formerr(q);
898  }
899  /* else: valid tsig, or no tsig present */
900  ods_log_debug("[%s] tsig %s", query_str, tsig_status2str(q->tsig_rr->status));
901  /* get opcode, qtype, ixfr=serial */
902  opcode = ldns_pkt_get_opcode(pkt);
903  qtype = ldns_rr_get_type(rr);
904  if (qtype == LDNS_RR_TYPE_IXFR) {
905  ods_log_assert(q->zone->name);
906  ods_log_debug("[%s] incoming ixfr request for zone %s",
907  query_str, q->zone->name);
908  if (query_process_ixfr(q) != QUERY_PROCESSED) {
909  return query_formerr(q);
910  }
911  }
912  /* process tsig */
913  rcode = query_process_tsig(q);
914  if (rcode != LDNS_RCODE_NOERROR) {
915  return query_error(q, rcode);
916  }
917  /* process edns */
918  rcode = query_process_edns(q);
919  if (rcode != LDNS_RCODE_NOERROR) {
920  /* We should not return FORMERR, but BADVERS (=16).
921  * BADVERS is created with Ext. RCODE, followed by RCODE.
922  * Ext. RCODE is set to 1, RCODE must be 0 (getting 0x10 = 16).
923  * Thus RCODE = NOERROR = NSD_RC_OK. */
924  return query_error(q, LDNS_RCODE_NOERROR);
925  }
926  /* handle incoming request */
927  ldns_pkt_free(pkt);
928  switch (opcode) {
929  case LDNS_PACKET_NOTIFY:
930  return query_process_notify(q, qtype, engine);
931  case LDNS_PACKET_QUERY:
932  return query_process_query(q, qtype, engine);
933  case LDNS_PACKET_UPDATE:
934  return query_process_update(q);
935  default:
936  break;
937  }
938  return query_notimpl(q);
939 }
940 
941 
946 static int
947 query_overflow(query_type* q)
948 {
949  ods_log_assert(q);
951  return buffer_position(q->buffer) > (q->maxlen - q->reserved_space);
952 }
953 
954 
959 void
961 {
962  engine_type* e = (engine_type*) engine;
963  edns_data_type* edns = NULL;
964  if (!q || !e) {
965  return;
966  }
968  if (q->edns_rr) {
969  edns = &e->edns;
970  switch (q->edns_rr->status) {
971  case EDNS_NOT_PRESENT:
972  break;
973  case EDNS_OK:
974  ods_log_debug("[%s] add edns opt ok", query_str);
975  if (q->edns_rr->dnssec_ok) {
976  edns->ok[7] = 0x80;
977  } else {
978  edns->ok[7] = 0x00;
979  }
980  buffer_write(q->buffer, edns->ok, OPT_LEN);
981  /* fill with NULLs */
984  buffer_pkt_arcount(q->buffer) + 1);
985  break;
986  case EDNS_ERROR:
987  ods_log_debug("[%s] add edns opt err", query_str);
988  if (q->edns_rr->dnssec_ok) {
989  edns->ok[7] = 0x80;
990  } else {
991  edns->ok[7] = 0x00;
992  }
993  buffer_write(q->buffer, edns->error, OPT_LEN);
996  buffer_pkt_arcount(q->buffer) + 1);
997  break;
998  default:
999  break;
1000  }
1001  }
1002 
1004  if (!q->tsig_rr) {
1005  return;
1006  }
1007  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
1008 
1009  if (q->tsig_rr->status == TSIG_ERROR ||
1010  q->tsig_rr->error_code != LDNS_RCODE_NOERROR) {
1011  ods_log_debug("[%s] add tsig err", query_str);
1012  tsig_rr_error(q->tsig_rr);
1013  tsig_rr_append(q->tsig_rr, q->buffer);
1015  buffer_pkt_arcount(q->buffer)+1);
1016  } else if (q->tsig_rr->status == TSIG_OK &&
1017  q->tsig_rr->error_code == LDNS_RCODE_NOERROR) {
1018  ods_log_debug("[%s] add tsig ok", query_str);
1019  if (q->tsig_prepare_it)
1021  if (q->tsig_update_it)
1022  tsig_rr_update(q->tsig_rr, q->buffer,
1023  buffer_position(q->buffer));
1024  if (q->tsig_sign_it) {
1025  tsig_rr_sign(q->tsig_rr);
1026  tsig_rr_append(q->tsig_rr, q->buffer);
1028  buffer_pkt_arcount(q->buffer)+1);
1029  }
1030  }
1031  }
1032  return;
1033 }
1034 
1035 
1040 int
1041 query_add_rr(query_type* q, ldns_rr* rr)
1042 {
1043  size_t i = 0;
1044  size_t tc_mark = 0;
1045  size_t rdlength_pos = 0;
1046  uint16_t rdlength = 0;
1047 
1048  ods_log_assert(q);
1049  ods_log_assert(q->buffer);
1050  ods_log_assert(rr);
1051 
1052  /* set truncation mark, in case rr does not fit */
1053  tc_mark = buffer_position(q->buffer);
1054  /* owner type class ttl */
1055  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_owner(rr)))) {
1056  goto query_add_rr_tc;
1057  }
1058  buffer_write_rdf(q->buffer, ldns_rr_owner(rr));
1059  if (!buffer_available(q->buffer, sizeof(uint16_t) + sizeof(uint16_t) +
1060  sizeof(uint32_t) + sizeof(rdlength))) {
1061  goto query_add_rr_tc;
1062  }
1063  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_type(rr));
1064  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_class(rr));
1065  buffer_write_u32(q->buffer, (uint32_t) ldns_rr_ttl(rr));
1066  /* skip rdlength */
1067  rdlength_pos = buffer_position(q->buffer);
1068  buffer_skip(q->buffer, sizeof(rdlength));
1069  /* write rdata */
1070  for (i=0; i < ldns_rr_rd_count(rr); i++) {
1071  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_rdf(rr, i)))) {
1072  goto query_add_rr_tc;
1073  }
1074  buffer_write_rdf(q->buffer, ldns_rr_rdf(rr, i));
1075  }
1076 
1077  if (!query_overflow(q)) {
1078  /* write rdlength */
1079  rdlength = buffer_position(q->buffer) - rdlength_pos - sizeof(rdlength);
1080  buffer_write_u16_at(q->buffer, rdlength_pos, rdlength);
1081  /* position updated by buffer_write() */
1082  return 1;
1083  }
1084 
1085 query_add_rr_tc:
1086  buffer_set_position(q->buffer, tc_mark);
1087  ods_log_assert(!query_overflow(q));
1088  return 0;
1089 
1090 }
1091 
1092 
1097 void
1099 {
1100  allocator_type* allocator = NULL;
1101  if (!q) {
1102  return;
1103  }
1104  allocator = q->allocator;
1105  if (q->axfr_fd) {
1106  ods_fclose(q->axfr_fd);
1107  q->axfr_fd = NULL;
1108  }
1109  buffer_cleanup(q->buffer, allocator);
1111  allocator_deallocate(allocator, (void*)q);
1112  allocator_cleanup(allocator);
1113  return;
1114 }
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:604
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:1098
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:363
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:108
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:111
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:332
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:720
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:579
void buffer_pkt_set_ancount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1098
#define lock_basic_lock(lock)
Definition: locks.h:91
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:809
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:883
query_state query_process(query_type *q, void *engine)
Definition: query.c:845
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:698
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:305
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:791
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:545
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:510
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:676
void query_prepare(query_type *q)
Definition: query.c:614
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:1041
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:92
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:109
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:762
rr_type * rrs
Definition: rrset.h:77
void query_add_optional(query_type *q, void *engine)
Definition: query.c:960