OpenDNSSEC-signer  1.4.5
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_debug("[%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 client %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  "client: 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  ods_log_error("[%s] dropped packet: zone %s received bad notify "
327  "(bad question section)", query_str, q->zone->name);
328  return QUERY_DISCARDED;
329  }
330  }
331  pos = buffer_position(q->buffer);
332 
333  /* examine answer section */
334  count = buffer_pkt_ancount(q->buffer);
335  if (count) {
336  if (!buffer_skip_dname(q->buffer) ||
337  !query_parse_soa(q->buffer, &serial)) {
338  ods_log_error("[%s] dropped packet: zone %s received bad notify "
339  "(bad soa in answer section)", query_str, q->zone->name);
340  return QUERY_DISCARDED;
341  }
343  if (q->zone->xfrd->serial_notify_acquired) {
345  q->zone->xfrd->serial_disk)) {
346  ods_log_debug("[%s] ignore notify: already got zone %s serial "
347  "%u on disk", query_str, q->zone->name,
348  q->zone->xfrd->serial_notify);
350  } else {
351  ods_log_debug("[%s] ignore notify: zone %s transfer in process",
352  query_str, q->zone->name);
353  /* update values */
354  q->zone->xfrd->serial_notify = serial;
356  }
358  goto send_notify_ok;
359  }
360  q->zone->xfrd->serial_notify = serial;
363  /* forward notify to xfrd */
367  }
368 
369 send_notify_ok:
370  /* send notify ok */
374 
375  buffer_clear(q->buffer); /* lim = pos, pos = 0; */
376  buffer_set_position(q->buffer, pos);
380  return QUERY_PROCESSED;
381 }
382 
383 
388 static query_state
389 query_process_ixfr(query_type* q)
390 {
391  uint16_t count = 0;
392  ods_log_assert(q);
395  /* skip header and question section */
397  if (!buffer_skip_rr(q->buffer, 1)) {
398  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
399  "request (bad question section)", query_str, q->zone->name);
400  return QUERY_DISCARDED;
401  }
402  /* answer section is empty */
404  /* examine auth section */
406  count = buffer_pkt_nscount(q->buffer);
407  if (count) {
408  if (!buffer_skip_dname(q->buffer) ||
409  !query_parse_soa(q->buffer, &(q->serial))) {
410  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
411  "request (bad soa in auth section)", query_str, q->zone->name);
412  return QUERY_DISCARDED;
413  }
414  ods_log_debug("[%s] found ixfr request zone %s serial=%u", query_str,
415  q->zone->name, q->serial);
416  return QUERY_PROCESSED;
417  }
418  ods_log_debug("[%s] ixfr request zone %s has no auth section", query_str,
419  q->zone->name);
420  q->serial = 0;
421  return QUERY_PROCESSED;
422 }
423 
424 
429 static int
430 response_add_rrset(response_type* r, rrset_type* rrset,
431  ldns_pkt_section section)
432 {
433  if (!r || !rrset || !section) {
434  return 0;
435  }
436  /* duplicates? */
437  r->sections[r->rrset_count] = section;
438  r->rrsets[r->rrset_count] = rrset;
439  ++r->rrset_count;
440  return 1;
441 }
442 
443 
448 static int
449 response_encode_rr(query_type* q, ldns_rr* rr, ldns_pkt_section section)
450 {
451  uint8_t *data = NULL;
452  size_t size = 0;
453  ldns_status status = LDNS_STATUS_OK;
454  ods_log_assert(q);
455  ods_log_assert(rr);
456  ods_log_assert(section);
457  status = ldns_rr2wire(&data, rr, section, &size);
458  if (status != LDNS_STATUS_OK) {
459  ods_log_error("[%s] unable to send good response: ldns_rr2wire() "
460  "failed (%s)", query_str, ldns_get_errorstr_by_id(status));
461  return 0;
462  }
463  buffer_write(q->buffer, (const void*) data, size);
464  LDNS_FREE(data);
465  return 1;
466 }
467 
468 
473 static uint16_t
474 response_encode_rrset(query_type* q, rrset_type* rrset, ldns_pkt_section section)
475 {
476  uint16_t i = 0;
477  uint16_t added = 0;
478  ods_log_assert(q);
479  ods_log_assert(rrset);
480  ods_log_assert(section);
481 
482  for (i = 0; i < rrset->rr_count; i++) {
483  added += response_encode_rr(q, rrset->rrs[i].rr, section);
484  }
485  if (q->edns_rr && q->edns_rr->dnssec_ok) {
486  for (i = 0; i < rrset->rrsig_count; i++) {
487  added += response_encode_rr(q, rrset->rrsigs[i].rr, section);
488  }
489  }
490  /* truncation? */
491  return added;
492 }
493 
494 
499 static void
500 response_encode(query_type* q, response_type* r)
501 {
502  uint16_t counts[LDNS_SECTION_ANY];
503  ldns_pkt_section s = LDNS_SECTION_QUESTION;
504  size_t i = 0;
505  ods_log_assert(q);
506  ods_log_assert(r);
507  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
508  counts[s] = 0;
509  }
510  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
511  for (i = 0; i < r->rrset_count; i++) {
512  if (r->sections[i] == s) {
513  counts[s] += response_encode_rrset(q, r->rrsets[i], s);
514  }
515  }
516  }
517  buffer_pkt_set_ancount(q->buffer, counts[LDNS_SECTION_ANSWER]);
518  buffer_pkt_set_nscount(q->buffer, counts[LDNS_SECTION_AUTHORITY]);
519  buffer_pkt_set_arcount(q->buffer, counts[LDNS_SECTION_ADDITIONAL]);
522  return;
523 }
524 
525 
530 static query_state
531 query_response(query_type* q, ldns_rr_type qtype)
532 {
533  rrset_type* rrset = NULL;
534  response_type r;
535  if (!q || !q->zone) {
536  return QUERY_DISCARDED;
537  }
538  r.rrset_count = 0;
540  rrset = zone_lookup_rrset(q->zone, q->zone->apex, qtype);
541  if (rrset) {
542  if (!response_add_rrset(&r, rrset, LDNS_SECTION_ANSWER)) {
544  return query_servfail(q);
545  }
546  /* NS RRset goes into Authority Section */
547  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_NS);
548  if (rrset) {
549  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
551  return query_servfail(q);
552  }
553  }
554  } else if (qtype != LDNS_RR_TYPE_SOA) {
555  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_SOA);
556  if (rrset) {
557  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
559  return query_servfail(q);
560  }
561  }
562  } else {
564  return query_servfail(q);
565  }
567 
568  response_encode(q, &r);
569  /* compression */
570  return QUERY_PROCESSED;
571 }
572 
573 
578 void
580 {
581  uint16_t limit = 0;
582  uint16_t flags = 0;
583  ods_log_assert(q);
585  limit = buffer_limit(q->buffer);
586  flags = buffer_pkt_flags(q->buffer);
587  flags &= 0x0100U; /* preserve the rd flag */
588  flags |= 0x8000U; /* set the qr flag */
589  buffer_pkt_set_flags(q->buffer, flags);
590  buffer_clear(q->buffer);
591  buffer_set_position(q->buffer, limit);
595  return;
596 }
597 
598 
603 static query_state
604 query_process_query(query_type* q, ldns_rr_type qtype, engine_type* engine)
605 {
606  dnsout_type* dnsout = NULL;
607  if (!q || !q->zone) {
608  return QUERY_DISCARDED;
609  }
610  ods_log_assert(q->zone->name);
611  ods_log_debug("[%s] incoming query qtype=%s for zone %s", query_str,
612  rrset_type2str(qtype), q->zone->name);
613  /* sanity checks */
614  if (buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_tc(q->buffer)) {
616  return query_formerr(q);
617  }
618  if (buffer_pkt_ancount(q->buffer) != 0 ||
619  (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) {
621  return query_formerr(q);
622  }
623  /* acl */
624  if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) {
625  ods_log_error("[%s] zone %s is not configured to have output dns "
626  "adapter", query_str, q->zone->name);
627  return query_refused(q);
628  }
630  dnsout = (dnsout_type*) q->zone->adoutbound->config;
631  /* acl also in use for soa and other queries */
632  if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) {
633  ods_log_debug("[%s] zone %s acl query refused", query_str,
634  q->zone->name);
635  return query_refused(q);
636  }
637 
638  query_prepare(q);
639  /* ixfr? */
640  if (qtype == LDNS_RR_TYPE_IXFR) {
641  ods_log_assert(q->zone->name);
642  ods_log_debug("[%s] incoming ixfr request serial=%u for zone %s",
643  query_str, q->serial, q->zone->name);
644  return ixfr(q, engine);
645  }
646  /* axfr? */
647  if (qtype == LDNS_RR_TYPE_AXFR) {
648  ods_log_assert(q->zone->name);
649  ods_log_debug("[%s] incoming axfr request for zone %s",
650  query_str, q->zone->name);
651  return axfr(q, engine, 0);
652  }
653  /* (soa) query */
654  if (qtype == LDNS_RR_TYPE_SOA) {
655  ods_log_assert(q->zone->name);
656  ods_log_debug("[%s] incoming soa request for zone %s",
657  query_str, q->zone->name);
658  return soa_request(q, engine);
659  }
660  /* other qtypes */
661  return query_response(q, qtype);
662 }
663 
664 
669 static query_state
670 query_process_update(query_type* q)
671 {
672  if (!q || !q->zone) {
673  return QUERY_DISCARDED;
674  }
675  ods_log_debug("[%s] dynamic update not implemented", query_str);
676  return query_notimpl(q);
677 }
678 
679 
684 static ldns_pkt_rcode
685 query_process_tsig(query_type* q)
686 {
687  if (!q || !q->tsig_rr) {
688  return LDNS_RCODE_SERVFAIL;
689  }
690  if (q->tsig_rr->status == TSIG_ERROR) {
691  return LDNS_RCODE_FORMERR;
692  }
693  if (q->tsig_rr->status == TSIG_OK) {
694  if (!tsig_rr_lookup(q->tsig_rr)) {
695  ods_log_debug("[%s] tsig unknown key/algorithm", query_str);
696  return LDNS_RCODE_REFUSED;
697  }
702  if (!tsig_rr_verify(q->tsig_rr)) {
703  ods_log_debug("[%s] bad tsig signature", query_str);
704  return LDNS_RCODE_NOTAUTH;
705  }
706  }
707  return LDNS_RCODE_NOERROR;
708 }
709 
710 
715 static ldns_pkt_rcode
716 query_process_edns(query_type* q)
717 {
718  if (!q || !q->edns_rr) {
719  return LDNS_RCODE_SERVFAIL;
720  }
721  if (q->edns_rr->status == EDNS_ERROR) {
722  /* The only error is VERSION not implemented */
723  return LDNS_RCODE_FORMERR;
724  }
725  if (q->edns_rr->status == EDNS_OK) {
726  /* Only care about UDP size larger than normal... */
727  if (!q->tcp && q->edns_rr->maxlen > UDP_MAX_MESSAGE_LEN) {
728  if (q->edns_rr->maxlen < EDNS_MAX_MESSAGE_LEN) {
729  q->maxlen = q->edns_rr->maxlen;
730  } else {
732  }
733  }
734  /* Strip the OPT resource record off... */
738  }
739  return LDNS_RCODE_NOERROR;
740 }
741 
742 
747 static int
748 query_find_tsig(query_type* q)
749 {
750  size_t saved_pos = 0;
751  size_t rrcount = 0;
752  size_t i = 0;
753 
754  ods_log_assert(q);
757  if (buffer_pkt_arcount(q->buffer) == 0) {
759  return 1;
760  }
761  saved_pos = buffer_position(q->buffer);
762  rrcount = buffer_pkt_qdcount(q->buffer) + buffer_pkt_ancount(q->buffer) +
765  for (i=0; i < rrcount; i++) {
766  if (!buffer_skip_rr(q->buffer, i < buffer_pkt_qdcount(q->buffer))) {
767  buffer_set_position(q->buffer, saved_pos);
768  return 0;
769  }
770  }
771 
772  rrcount = buffer_pkt_arcount(q->buffer);
773  ods_log_assert(rrcount != 0);
774  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
775  ods_log_debug("[%s] got bad tsig", query_str);
776  return 0;
777  }
778  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
779  --rrcount;
780  }
781  if (rrcount) {
782  if (edns_rr_parse(q->edns_rr, q->buffer)) {
783  --rrcount;
784  }
785  }
786  if (rrcount && q->tsig_rr->status == TSIG_NOT_PRESENT) {
787  /* see if tsig is after the edns record */
788  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
789  ods_log_debug("[%s] got bad tsig", query_str);
790  return 0;
791  }
792  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
793  --rrcount;
794  }
795  }
796  if (rrcount > 0) {
797  ods_log_debug("[%s] too many additional rrs", query_str);
798  return 0;
799  }
800  buffer_set_position(q->buffer, saved_pos);
801  return 1;
802 }
803 
804 
810 query_process(query_type* q, void* engine)
811 {
812  ldns_status status = LDNS_STATUS_OK;
813  ldns_pkt* pkt = NULL;
814  ldns_rr* rr = NULL;
815  ldns_pkt_rcode rcode = LDNS_RCODE_NOERROR;
816  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
817  ldns_rr_type qtype = LDNS_RR_TYPE_SOA;
818  engine_type* e = (engine_type*) engine;
819  ods_log_assert(e);
820  ods_log_assert(q);
822  if (!e || !q || !q->buffer) {
823  ods_log_error("[%s] drop query: assertion error", query_str);
824  return QUERY_DISCARDED; /* should not happen */
825  }
827  ods_log_debug("[%s] drop query: packet too small", query_str);
828  return QUERY_DISCARDED; /* too small */
829  }
830  if (buffer_pkt_qr(q->buffer)) {
831  ods_log_debug("[%s] drop query: qr bit set", query_str);
832  return QUERY_DISCARDED; /* not a query */
833  }
834  /* parse packet */
835  status = ldns_wire2pkt(&pkt, buffer_current(q->buffer),
837  if (status != LDNS_STATUS_OK) {
838  ods_log_debug("[%s] got bad packet: %s", query_str,
839  ldns_get_errorstr_by_id(status));
840  return query_formerr(q);
841  }
842  rr = ldns_rr_list_rr(ldns_pkt_question(pkt), 0);
844  /* we can just lookup the zone, because we will only handle SOA queries,
845  zone transfers, updates and notifies */
846  q->zone = zonelist_lookup_zone_by_dname(e->zonelist, ldns_rr_owner(rr),
847  ldns_rr_get_class(rr));
848  /* don't answer for zones that are just added */
849  if (q->zone && q->zone->zl_status == ZONE_ZL_ADDED) {
850  ods_log_assert(q->zone->name);
851  ods_log_warning("[%s] zone %s just added, don't answer for now",
852  query_str, q->zone->name);
853  q->zone = NULL;
854  }
856  if (!q->zone) {
857  ods_log_debug("[%s] zone not found", query_str);
858  return query_servfail(q);
859  }
860  /* see if it is tsig signed */
861  if (!query_find_tsig(q)) {
862  return query_formerr(q);
863  }
864  /* else: valid tsig, or no tsig present */
865  ods_log_debug("[%s] tsig %s", query_str, tsig_status2str(q->tsig_rr->status));
866  /* get opcode, qtype, ixfr=serial */
867  opcode = ldns_pkt_get_opcode(pkt);
868  qtype = ldns_rr_get_type(rr);
869  if (qtype == LDNS_RR_TYPE_IXFR) {
870  ods_log_assert(q->zone->name);
871  ods_log_debug("[%s] incoming ixfr request for zone %s",
872  query_str, q->zone->name);
873  if (query_process_ixfr(q) != QUERY_PROCESSED) {
874  return query_formerr(q);
875  }
876  }
877  /* process tsig */
878  rcode = query_process_tsig(q);
879  if (rcode != LDNS_RCODE_NOERROR) {
880  return query_error(q, rcode);
881  }
882  /* process edns */
883  rcode = query_process_edns(q);
884  if (rcode != LDNS_RCODE_NOERROR) {
885  /* We should not return FORMERR, but BADVERS (=16).
886  * BADVERS is created with Ext. RCODE, followed by RCODE.
887  * Ext. RCODE is set to 1, RCODE must be 0 (getting 0x10 = 16).
888  * Thus RCODE = NOERROR = NSD_RC_OK. */
889  return query_error(q, LDNS_RCODE_NOERROR);
890  }
891  /* handle incoming request */
892  ldns_pkt_free(pkt);
893  switch (opcode) {
894  case LDNS_PACKET_NOTIFY:
895  return query_process_notify(q, qtype, engine);
896  case LDNS_PACKET_QUERY:
897  return query_process_query(q, qtype, engine);
898  case LDNS_PACKET_UPDATE:
899  return query_process_update(q);
900  default:
901  break;
902  }
903  return query_notimpl(q);
904 }
905 
906 
911 static int
912 query_overflow(query_type* q)
913 {
914  ods_log_assert(q);
916  return buffer_position(q->buffer) > (q->maxlen - q->reserved_space);
917 }
918 
919 
924 void
926 {
927  engine_type* e = (engine_type*) engine;
928  edns_data_type* edns = NULL;
929  if (!q || !e) {
930  return;
931  }
933  if (q->edns_rr) {
934  edns = &e->edns;
935  switch (q->edns_rr->status) {
936  case EDNS_NOT_PRESENT:
937  break;
938  case EDNS_OK:
939  ods_log_debug("[%s] add edns opt ok", query_str);
940  if (q->edns_rr->dnssec_ok) {
941  edns->ok[7] = 0x80;
942  } else {
943  edns->ok[7] = 0x00;
944  }
945  buffer_write(q->buffer, edns->ok, OPT_LEN);
946  /* fill with NULLs */
949  buffer_pkt_arcount(q->buffer) + 1);
950  break;
951  case EDNS_ERROR:
952  ods_log_debug("[%s] add edns opt err", query_str);
953  if (q->edns_rr->dnssec_ok) {
954  edns->ok[7] = 0x80;
955  } else {
956  edns->ok[7] = 0x00;
957  }
958  buffer_write(q->buffer, edns->error, OPT_LEN);
961  buffer_pkt_arcount(q->buffer) + 1);
962  break;
963  default:
964  break;
965  }
966  }
967 
969  if (!q->tsig_rr) {
970  return;
971  }
972  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
973 
974  if (q->tsig_rr->status == TSIG_ERROR ||
975  q->tsig_rr->error_code != LDNS_RCODE_NOERROR) {
976  ods_log_debug("[%s] add tsig err", query_str);
978  tsig_rr_append(q->tsig_rr, q->buffer);
980  buffer_pkt_arcount(q->buffer)+1);
981  } else if (q->tsig_rr->status == TSIG_OK &&
982  q->tsig_rr->error_code == LDNS_RCODE_NOERROR) {
983  ods_log_debug("[%s] add tsig ok", query_str);
984  if (q->tsig_prepare_it)
986  if (q->tsig_update_it)
988  buffer_position(q->buffer));
989  if (q->tsig_sign_it) {
990  tsig_rr_sign(q->tsig_rr);
991  tsig_rr_append(q->tsig_rr, q->buffer);
993  buffer_pkt_arcount(q->buffer)+1);
994  }
995  }
996  }
997  return;
998 }
999 
1000 
1005 int
1006 query_add_rr(query_type* q, ldns_rr* rr)
1007 {
1008  size_t i = 0;
1009  size_t tc_mark = 0;
1010  size_t rdlength_pos = 0;
1011  uint16_t rdlength = 0;
1012 
1013  ods_log_assert(q);
1014  ods_log_assert(q->buffer);
1015  ods_log_assert(rr);
1016 
1017  /* set truncation mark, in case rr does not fit */
1018  tc_mark = buffer_position(q->buffer);
1019  /* owner type class ttl */
1020  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_owner(rr)))) {
1021  goto query_add_rr_tc;
1022  }
1023  buffer_write_rdf(q->buffer, ldns_rr_owner(rr));
1024  if (!buffer_available(q->buffer, sizeof(uint16_t) + sizeof(uint16_t) +
1025  sizeof(uint32_t) + sizeof(rdlength))) {
1026  goto query_add_rr_tc;
1027  }
1028  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_type(rr));
1029  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_class(rr));
1030  buffer_write_u32(q->buffer, (uint32_t) ldns_rr_ttl(rr));
1031  /* skip rdlength */
1032  rdlength_pos = buffer_position(q->buffer);
1033  buffer_skip(q->buffer, sizeof(rdlength));
1034  /* write rdata */
1035  for (i=0; i < ldns_rr_rd_count(rr); i++) {
1036  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_rdf(rr, i)))) {
1037  goto query_add_rr_tc;
1038  }
1039  buffer_write_rdf(q->buffer, ldns_rr_rdf(rr, i));
1040  }
1041 
1042  if (!query_overflow(q)) {
1043  /* write rdlength */
1044  rdlength = buffer_position(q->buffer) - rdlength_pos - sizeof(rdlength);
1045  buffer_write_u16_at(q->buffer, rdlength_pos, rdlength);
1046  /* position updated by buffer_write() */
1047  return 1;
1048  }
1049 
1050 query_add_rr_tc:
1051  buffer_set_position(q->buffer, tc_mark);
1052  ods_log_assert(!query_overflow(q));
1053  return 0;
1054 
1055 }
1056 
1057 
1062 void
1064 {
1065  allocator_type* allocator = NULL;
1066  if (!q) {
1067  return;
1068  }
1069  allocator = q->allocator;
1070  if (q->axfr_fd) {
1071  ods_fclose(q->axfr_fd);
1072  q->axfr_fd = NULL;
1073  }
1074  buffer_cleanup(q->buffer, allocator);
1076  allocator_deallocate(allocator, (void*)q);
1077  allocator_cleanup(allocator);
1078  return;
1079 }
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:1063
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:810
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
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:245
socklen_t addrlen
Definition: query.h:64
void xfrd_set_timer_now(xfrd_type *xfrd)
Definition: xfrd.c:458
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:579
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:1006
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:925