OpenDNSSEC-signer  1.4.3
query.c
Go to the documentation of this file.
1 /*
2  * $Id: query.c 4958 2011-04-18 07:11:09Z matthijs $
3  *
4  * Copyright (c) 2011 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "daemon/dnshandler.h"
36 #include "daemon/engine.h"
37 #include "shared/file.h"
38 #include "shared/util.h"
39 #include "wire/axfr.h"
40 #include "wire/query.h"
41 
42 const char* query_str = "query";
43 
44 
51 {
52  allocator_type* allocator = NULL;
53  query_type* q = NULL;
54  allocator = allocator_create(malloc, free);
55  if (!allocator) {
56  return NULL;
57  }
58  q = (query_type*) allocator_alloc(allocator, sizeof(query_type));
59  if (!q) {
60  allocator_cleanup(allocator);
61  return NULL;
62  }
63  q->allocator = allocator;
64  q->buffer = NULL;
65  q->tsig_rr = NULL;
66  q->axfr_fd = NULL;
67  q->buffer = buffer_create(allocator, PACKET_BUFFER_SIZE);
68  if (!q->buffer) {
69  query_cleanup(q);
70  return NULL;
71  }
72  q->tsig_rr = tsig_rr_create(allocator);
73  if (!q->tsig_rr) {
74  query_cleanup(q);
75  return NULL;
76  }
77  q->edns_rr = edns_rr_create(allocator);
78  if (!q->edns_rr) {
79  query_cleanup(q);
80  return NULL;
81  }
83  return q;
84 }
85 
86 
91 void
92 query_reset(query_type* q, size_t maxlen, int is_tcp)
93 {
94  if (!q) {
95  return;
96  }
97  q->addrlen = sizeof(q->addr);
98  q->maxlen = maxlen;
99  q->reserved_space = 0;
100  buffer_clear(q->buffer);
101  tsig_rr_reset(q->tsig_rr, NULL, NULL);
103  q->tsig_prepare_it = 1;
104  q->tsig_update_it = 1;
105  q->tsig_sign_it = 1;
106  q->tcp = is_tcp;
107  /* qname, qtype, qclass */
108  q->zone = NULL;
109  /* domain, opcode, cname count, delegation, compression, temp */
110  q->axfr_is_done = 0;
111  if (q->axfr_fd) {
112  ods_fclose(q->axfr_fd);
113  q->axfr_fd = NULL;
114  }
115  q->serial = 0;
116  q->startpos = 0;
117  return;
118 }
119 
120 
125 static query_state
126 query_error(query_type* q, ldns_pkt_rcode rcode)
127 {
128  size_t limit = 0;
129  if (!q) {
130  return QUERY_DISCARDED;
131  }
132  limit = buffer_limit(q->buffer);
133  buffer_clear(q->buffer);
135  buffer_pkt_set_rcode(q->buffer, rcode);
139  buffer_set_position(q->buffer, limit);
140  return QUERY_PROCESSED;
141 }
142 
143 
148 static query_state
149 query_formerr(query_type* q)
150 {
151  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
152  if (!q) {
153  return QUERY_DISCARDED;
154  }
155  opcode = buffer_pkt_opcode(q->buffer);
156  /* preserve the RD flag, clear the rest */
158  buffer_pkt_set_opcode(q->buffer, opcode);
160  ods_log_debug("[%s] formerr", query_str);
161  return query_error(q, LDNS_RCODE_FORMERR);
162 }
163 
164 
169 static query_state
170 query_servfail(query_type* q)
171 {
172  if (!q) {
173  return QUERY_DISCARDED;
174  }
175  ods_log_debug("[%s] servfail", query_str);
179  return query_error(q, LDNS_RCODE_SERVFAIL);
180 }
181 
182 
187 static query_state
188 query_notimpl(query_type* q)
189 {
190  if (!q) {
191  return QUERY_DISCARDED;
192  }
193  ods_log_debug("[%s] notimpl", query_str);
194  return query_error(q, LDNS_RCODE_NOTIMPL);
195 }
196 
197 
202 static query_state
203 query_refused(query_type* q)
204 {
205  if (!q) {
206  return QUERY_DISCARDED;
207  }
208  ods_log_debug("[%s] refused", query_str);
209  return query_error(q, LDNS_RCODE_REFUSED);
210 }
211 
212 
217 static query_state
218 query_notauth(query_type* q)
219 {
220  if (!q) {
221  return QUERY_DISCARDED;
222  }
223  ods_log_debug("[%s] notauth", query_str);
224  return query_error(q, LDNS_RCODE_NOTAUTH);
225 }
226 
227 
233 static int
234 query_parse_soa(buffer_type* buffer, uint32_t* serial)
235 {
236  ldns_rr_type type = 0;
237  ods_log_assert(buffer);
238  if (!buffer_available(buffer, 10)) {
239  ods_log_error("[%s] bad soa: packet too short", query_str);
240  return 0;
241  }
242  type = (ldns_rr_type) buffer_read_u16(buffer);
243  if (type != LDNS_RR_TYPE_SOA) {
244  ods_log_error("[%s] bad soa: rr is not soa (%d)", query_str, type);
245  return 0;
246  }
247  (void)buffer_read_u16(buffer);
248  (void)buffer_read_u32(buffer);
249  /* rdata length */
250  if (!buffer_available(buffer, buffer_read_u16(buffer))) {
251  ods_log_error("[%s] bad soa: missing rdlength", query_str);
252  return 0;
253  }
254  /* MNAME */
255  if (!buffer_skip_dname(buffer)) {
256  ods_log_error("[%s] bad soa: missing mname", query_str);
257  return 0;
258  }
259  /* RNAME */
260  if (!buffer_skip_dname(buffer)) {
261  ods_log_error("[%s] bad soa: missing rname", query_str);
262  return 0;
263  }
264  if (serial) {
265  *serial = buffer_read_u32(buffer);
266  }
267  return 1;
268 }
269 
270 
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_debug("[%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 client %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  "client: 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  ods_log_error("[%s] dropped packet: zone %s received bad notify "
329  "(bad question section)", query_str, q->zone->name);
330  return QUERY_DISCARDED;
331  }
332  }
333  pos = buffer_position(q->buffer);
334 
335  /* examine answer section */
336  count = buffer_pkt_ancount(q->buffer);
337  if (count) {
338  if (!buffer_skip_dname(q->buffer) ||
339  !query_parse_soa(q->buffer, &serial)) {
340  ods_log_error("[%s] dropped packet: zone %s received bad notify "
341  "(bad soa in answer section)", query_str, q->zone->name);
342  return QUERY_DISCARDED;
343  }
345  q->zone->xfrd->serial_notify = serial;
348  q->zone->xfrd->serial_disk)) {
349  ods_log_debug("[%s] ignore notify: already got zone %s serial "
350  "%u on disk", query_str, q->zone->name,
351  q->zone->xfrd->serial_notify);
353  goto send_notify_ok;
354  }
356  } else {
358  q->zone->xfrd->serial_notify = 0;
361  }
362  /* forward notify to xfrd */
366 
367 send_notify_ok:
368  /* send notify ok */
372 
373  buffer_clear(q->buffer); /* lim = pos, pos = 0; */
374  buffer_set_position(q->buffer, pos);
378  return QUERY_PROCESSED;
379 }
380 
381 
386 static query_state
387 query_process_ixfr(query_type* q)
388 {
389  uint16_t count = 0;
390  ods_log_assert(q);
393  /* skip header and question section */
395  if (!buffer_skip_rr(q->buffer, 1)) {
396  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
397  "request (bad question section)", query_str, q->zone->name);
398  return QUERY_DISCARDED;
399  }
400  /* answer section is empty */
402  /* examine auth section */
404  count = buffer_pkt_nscount(q->buffer);
405  if (count) {
406  if (!buffer_skip_dname(q->buffer) ||
407  !query_parse_soa(q->buffer, &(q->serial))) {
408  ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
409  "request (bad soa in auth section)", query_str, q->zone->name);
410  return QUERY_DISCARDED;
411  }
412  ods_log_debug("[%s] found ixfr request zone %s serial=%u", query_str,
413  q->zone->name, q->serial);
414  return QUERY_PROCESSED;
415  }
416  ods_log_debug("[%s] ixfr request zone %s has no auth section", query_str,
417  q->zone->name);
418  q->serial = 0;
419  return QUERY_PROCESSED;
420 }
421 
422 
427 static int
428 response_add_rrset(response_type* r, rrset_type* rrset,
429  ldns_pkt_section section)
430 {
431  if (!r || !rrset || !section) {
432  return 0;
433  }
434  /* duplicates? */
435  r->sections[r->rrset_count] = section;
436  r->rrsets[r->rrset_count] = rrset;
437  ++r->rrset_count;
438  return 1;
439 }
440 
441 
446 static int
447 response_encode_rr(query_type* q, ldns_rr* rr, ldns_pkt_section section)
448 {
449  uint8_t *data = NULL;
450  size_t size = 0;
451  ldns_status status = LDNS_STATUS_OK;
452  ods_log_assert(q);
453  ods_log_assert(rr);
454  ods_log_assert(section);
455  status = ldns_rr2wire(&data, rr, section, &size);
456  if (status != LDNS_STATUS_OK) {
457  ods_log_error("[%s] unable to send good response: ldns_rr2wire() "
458  "failed (%s)", query_str, ldns_get_errorstr_by_id(status));
459  return 0;
460  }
461  buffer_write(q->buffer, (const void*) data, size);
462  LDNS_FREE(data);
463  return 1;
464 }
465 
466 
471 static uint16_t
472 response_encode_rrset(query_type* q, rrset_type* rrset, ldns_pkt_section section)
473 {
474  uint16_t i = 0;
475  uint16_t added = 0;
476  ods_log_assert(q);
477  ods_log_assert(rrset);
478  ods_log_assert(section);
479 
480  for (i = 0; i < rrset->rr_count; i++) {
481  added += response_encode_rr(q, rrset->rrs[i].rr, section);
482  }
483  if (q->edns_rr && q->edns_rr->dnssec_ok) {
484  for (i = 0; i < rrset->rrsig_count; i++) {
485  added += response_encode_rr(q, rrset->rrsigs[i].rr, section);
486  }
487  }
488  /* truncation? */
489  return added;
490 }
491 
492 
497 static void
498 response_encode(query_type* q, response_type* r)
499 {
500  uint16_t counts[LDNS_SECTION_ANY];
501  ldns_pkt_section s = LDNS_SECTION_QUESTION;
502  size_t i = 0;
503  ods_log_assert(q);
504  ods_log_assert(r);
505  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
506  counts[s] = 0;
507  }
508  for (s = LDNS_SECTION_ANSWER; s < LDNS_SECTION_ANY; s++) {
509  for (i = 0; i < r->rrset_count; i++) {
510  if (r->sections[i] == s) {
511  counts[s] += response_encode_rrset(q, r->rrsets[i], s);
512  }
513  }
514  }
515  buffer_pkt_set_ancount(q->buffer, counts[LDNS_SECTION_ANSWER]);
516  buffer_pkt_set_nscount(q->buffer, counts[LDNS_SECTION_AUTHORITY]);
517  buffer_pkt_set_arcount(q->buffer, counts[LDNS_SECTION_ADDITIONAL]);
520  return;
521 }
522 
523 
528 static query_state
529 query_response(query_type* q, ldns_rr_type qtype)
530 {
531  rrset_type* rrset = NULL;
532  response_type r;
533  if (!q || !q->zone) {
534  return QUERY_DISCARDED;
535  }
536  r.rrset_count = 0;
538  rrset = zone_lookup_rrset(q->zone, q->zone->apex, qtype);
539  if (rrset) {
540  if (!response_add_rrset(&r, rrset, LDNS_SECTION_ANSWER)) {
542  return query_servfail(q);
543  }
544  /* NS RRset goes into Authority Section */
545  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_NS);
546  if (rrset) {
547  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
549  return query_servfail(q);
550  }
551  }
552  } else if (qtype != LDNS_RR_TYPE_SOA) {
553  rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_SOA);
554  if (rrset) {
555  if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
557  return query_servfail(q);
558  }
559  }
560  } else {
562  return query_servfail(q);
563  }
565 
566  response_encode(q, &r);
567  /* compression */
568  return QUERY_PROCESSED;
569 }
570 
571 
576 void
578 {
579  uint16_t limit = 0;
580  uint16_t flags = 0;
581  ods_log_assert(q);
583  limit = buffer_limit(q->buffer);
584  flags = buffer_pkt_flags(q->buffer);
585  flags &= 0x0100U; /* preserve the rd flag */
586  flags |= 0x8000U; /* set the qr flag */
587  buffer_pkt_set_flags(q->buffer, flags);
588  buffer_clear(q->buffer);
589  buffer_set_position(q->buffer, limit);
593  return;
594 }
595 
596 
601 static query_state
602 query_process_query(query_type* q, ldns_rr_type qtype, engine_type* engine)
603 {
604  dnsout_type* dnsout = NULL;
605  if (!q || !q->zone) {
606  return QUERY_DISCARDED;
607  }
608  ods_log_assert(q->zone->name);
609  ods_log_debug("[%s] incoming query qtype=%s for zone %s", query_str,
610  rrset_type2str(qtype), q->zone->name);
611  /* sanity checks */
612  if (buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_tc(q->buffer)) {
614  return query_formerr(q);
615  }
616  if (buffer_pkt_ancount(q->buffer) != 0 ||
617  (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) {
619  return query_formerr(q);
620  }
621  /* acl */
622  if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) {
623  ods_log_error("[%s] zone %s is not configured to have output dns "
624  "adapter", query_str, q->zone->name);
625  return query_refused(q);
626  }
628  dnsout = (dnsout_type*) q->zone->adoutbound->config;
629  /* acl also in use for soa and other queries */
630  if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) {
631  ods_log_debug("[%s] zone %s acl query refused", query_str,
632  q->zone->name);
633  return query_refused(q);
634  }
635  /* ixfr? */
636  if (qtype == LDNS_RR_TYPE_IXFR) {
637  if (query_process_ixfr(q) != QUERY_PROCESSED) {
639  return query_formerr(q);
640  }
641  query_prepare(q);
642  ods_log_assert(q->zone->name);
643  ods_log_debug("[%s] incoming ixfr request serial=%u for zone %s",
644  query_str, q->serial, q->zone->name);
645  return ixfr(q, engine);
646  }
647 
648  query_prepare(q);
649  /* axfr? */
650  if (qtype == LDNS_RR_TYPE_AXFR) {
651  ods_log_assert(q->zone->name);
652  ods_log_debug("[%s] incoming axfr request for zone %s",
653  query_str, q->zone->name);
654  return axfr(q, engine, 0);
655  }
656  /* (soa) query */
657  if (qtype == LDNS_RR_TYPE_SOA) {
658  ods_log_assert(q->zone->name);
659  ods_log_debug("[%s] incoming soa request for zone %s",
660  query_str, q->zone->name);
661  return soa_request(q, engine);
662  }
663  /* other qtypes */
664  return query_response(q, qtype);
665 }
666 
667 
672 static query_state
673 query_process_update(query_type* q)
674 {
675  if (!q || !q->zone) {
676  return QUERY_DISCARDED;
677  }
678  ods_log_debug("[%s] dynamic update not implemented", query_str);
679  return query_notimpl(q);
680 }
681 
682 
687 static ldns_pkt_rcode
688 query_process_tsig(query_type* q)
689 {
690  if (!q || !q->tsig_rr) {
691  return LDNS_RCODE_SERVFAIL;
692  }
693  if (q->tsig_rr->status == TSIG_ERROR) {
694  return LDNS_RCODE_FORMERR;
695  }
696  if (q->tsig_rr->status == TSIG_OK) {
697  if (!tsig_rr_lookup(q->tsig_rr)) {
698  ods_log_debug("[%s] tsig unknown key/algorithm", query_str);
699  return LDNS_RCODE_REFUSED;
700  }
705  if (!tsig_rr_verify(q->tsig_rr)) {
706  ods_log_debug("[%s] bad tsig signature", query_str);
707  return LDNS_RCODE_NOTAUTH;
708  }
709  }
710  return LDNS_RCODE_NOERROR;
711 }
712 
713 
718 static ldns_pkt_rcode
719 query_process_edns(query_type* q)
720 {
721  if (!q || !q->edns_rr) {
722  return LDNS_RCODE_SERVFAIL;
723  }
724  if (q->edns_rr->status == EDNS_ERROR) {
725  /* The only error is VERSION not implemented */
726  return LDNS_RCODE_FORMERR;
727  }
728  if (q->edns_rr->status == EDNS_OK) {
729  /* Only care about UDP size larger than normal... */
730  if (!q->tcp && q->edns_rr->maxlen > UDP_MAX_MESSAGE_LEN) {
731  if (q->edns_rr->maxlen < EDNS_MAX_MESSAGE_LEN) {
732  q->maxlen = q->edns_rr->maxlen;
733  } else {
735  }
736  }
737  /* Strip the OPT resource record off... */
741  }
742  return LDNS_RCODE_NOERROR;
743 }
744 
745 
750 static int
751 query_find_tsig(query_type* q)
752 {
753  size_t saved_pos = 0;
754  size_t rrcount = 0;
755  size_t i = 0;
756 
757  ods_log_assert(q);
760  if (buffer_pkt_arcount(q->buffer) == 0) {
762  return 1;
763  }
764  saved_pos = buffer_position(q->buffer);
765  rrcount = buffer_pkt_qdcount(q->buffer) + buffer_pkt_ancount(q->buffer) +
768  for (i=0; i < rrcount; i++) {
769  if (!buffer_skip_rr(q->buffer, i < buffer_pkt_qdcount(q->buffer))) {
770  buffer_set_position(q->buffer, saved_pos);
771  return 0;
772  }
773  }
774 
775  rrcount = buffer_pkt_arcount(q->buffer);
776  ods_log_assert(rrcount != 0);
777  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
778  ods_log_debug("[%s] got bad tsig", query_str);
779  return 0;
780  }
781  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
782  --rrcount;
783  }
784  if (rrcount) {
785  if (edns_rr_parse(q->edns_rr, q->buffer)) {
786  --rrcount;
787  }
788  }
789  if (rrcount && q->tsig_rr->status == TSIG_NOT_PRESENT) {
790  /* see if tsig is after the edns record */
791  if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
792  ods_log_debug("[%s] got bad tsig", query_str);
793  return 0;
794  }
795  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
796  --rrcount;
797  }
798  }
799  if (rrcount > 0) {
800  ods_log_debug("[%s] too many additional rrs", query_str);
801  return 0;
802  }
803  buffer_set_position(q->buffer, saved_pos);
804  return 1;
805 }
806 
807 
813 query_process(query_type* q, void* engine)
814 {
815  ldns_status status = LDNS_STATUS_OK;
816  ldns_pkt* pkt = NULL;
817  ldns_rr* rr = NULL;
818  ldns_pkt_rcode rcode = LDNS_RCODE_NOERROR;
819  ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
820  ldns_rr_type qtype = LDNS_RR_TYPE_SOA;
821  engine_type* e = (engine_type*) engine;
822  ods_log_assert(e);
823  ods_log_assert(q);
825  if (!e || !q || !q->buffer) {
826  ods_log_error("[%s] drop query: assertion error", query_str);
827  return QUERY_DISCARDED; /* should not happen */
828  }
830  ods_log_debug("[%s] drop query: packet too small", query_str);
831  return QUERY_DISCARDED; /* too small */
832  }
833  if (buffer_pkt_qr(q->buffer)) {
834  ods_log_debug("[%s] drop query: qr bit set", query_str);
835  return QUERY_DISCARDED; /* not a query */
836  }
837  /* parse packet */
838  status = ldns_wire2pkt(&pkt, buffer_current(q->buffer),
840  if (status != LDNS_STATUS_OK) {
841  ods_log_debug("[%s] got bad packet: %s", query_str,
842  ldns_get_errorstr_by_id(status));
843  return query_formerr(q);
844  }
845  rr = ldns_rr_list_rr(ldns_pkt_question(pkt), 0);
847  /* we can just lookup the zone, because we will only handle SOA queries,
848  zone transfers, updates and notifies */
849  q->zone = zonelist_lookup_zone_by_dname(e->zonelist, ldns_rr_owner(rr),
850  ldns_rr_get_class(rr));
851  /* don't answer for zones that are just added */
852  if (q->zone && q->zone->zl_status == ZONE_ZL_ADDED) {
853  ods_log_warning("[%s] zone %s just added, don't answer for now",
854  query_str, q->zone->name);
855  q->zone = NULL;
856  }
858  if (!q->zone) {
859  ods_log_debug("[%s] zone not found", query_str);
860  return query_servfail(q);
861  }
862  /* see if it is tsig signed */
863  if (!query_find_tsig(q)) {
864  return query_formerr(q);
865  }
866  /* else: valid tsig, or no tsig present */
867  ods_log_debug("[%s] tsig %s", query_str, tsig_status2str(q->tsig_rr->status));
868  rcode = query_process_tsig(q);
869  if (rcode != LDNS_RCODE_NOERROR) {
870  return query_error(q, rcode);
871  }
872  /* process edns */
873  rcode = query_process_edns(q);
874  if (rcode != LDNS_RCODE_NOERROR) {
875  /* We should not return FORMERR, but BADVERS (=16).
876  * BADVERS is created with Ext. RCODE, followed by RCODE.
877  * Ext. RCODE is set to 1, RCODE must be 0 (getting 0x10 = 16).
878  * Thus RCODE = NOERROR = NSD_RC_OK. */
879  return query_error(q, LDNS_RCODE_NOERROR);
880  }
881 
882  /* handle incoming request */
883  opcode = ldns_pkt_get_opcode(pkt);
884  qtype = ldns_rr_get_type(rr);
885  ldns_pkt_free(pkt);
886 
887  switch (opcode) {
888  case LDNS_PACKET_NOTIFY:
889  return query_process_notify(q, qtype, engine);
890  case LDNS_PACKET_QUERY:
891  return query_process_query(q, qtype, engine);
892  case LDNS_PACKET_UPDATE:
893  return query_process_update(q);
894  default:
895  break;
896  }
897  return query_notimpl(q);
898 }
899 
900 
905 static int
906 query_overflow(query_type* q)
907 {
908  ods_log_assert(q);
910  return buffer_position(q->buffer) > (q->maxlen - q->reserved_space);
911 }
912 
913 
918 void
920 {
921  engine_type* e = (engine_type*) engine;
922  edns_data_type* edns = NULL;
923  if (!q || !e) {
924  return;
925  }
927  if (q->edns_rr) {
928  edns = &e->edns;
929  switch (q->edns_rr->status) {
930  case EDNS_NOT_PRESENT:
931  break;
932  case EDNS_OK:
933  ods_log_debug("[%s] add edns opt ok", query_str);
934  if (q->edns_rr->dnssec_ok) {
935  edns->ok[7] = 0x80;
936  } else {
937  edns->ok[7] = 0x00;
938  }
939  buffer_write(q->buffer, edns->ok, OPT_LEN);
940  /* fill with NULLs */
943  buffer_pkt_arcount(q->buffer) + 1);
944  break;
945  case EDNS_ERROR:
946  ods_log_debug("[%s] add edns opt err", query_str);
947  if (q->edns_rr->dnssec_ok) {
948  edns->ok[7] = 0x80;
949  } else {
950  edns->ok[7] = 0x00;
951  }
952  buffer_write(q->buffer, edns->error, OPT_LEN);
955  buffer_pkt_arcount(q->buffer) + 1);
956  break;
957  default:
958  break;
959  }
960  }
961 
963  if (!q->tsig_rr) {
964  return;
965  }
966  if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
967 
968  if (q->tsig_rr->status == TSIG_ERROR ||
969  q->tsig_rr->error_code != LDNS_RCODE_NOERROR) {
970  ods_log_debug("[%s] add tsig err", query_str);
972  tsig_rr_append(q->tsig_rr, q->buffer);
974  buffer_pkt_arcount(q->buffer)+1);
975  } else if (q->tsig_rr->status == TSIG_OK &&
976  q->tsig_rr->error_code == LDNS_RCODE_NOERROR) {
977  ods_log_debug("[%s] add tsig ok", query_str);
978  if (q->tsig_prepare_it)
980  if (q->tsig_update_it)
982  buffer_position(q->buffer));
983  if (q->tsig_sign_it) {
984  tsig_rr_sign(q->tsig_rr);
985  tsig_rr_append(q->tsig_rr, q->buffer);
987  buffer_pkt_arcount(q->buffer)+1);
988  }
989  }
990  }
991  return;
992 }
993 
994 
999 int
1000 query_add_rr(query_type* q, ldns_rr* rr)
1001 {
1002  size_t i = 0;
1003  size_t tc_mark = 0;
1004  size_t rdlength_pos = 0;
1005  uint16_t rdlength = 0;
1006 
1007  ods_log_assert(q);
1008  ods_log_assert(q->buffer);
1009  ods_log_assert(rr);
1010 
1011  /* set truncation mark, in case rr does not fit */
1012  tc_mark = buffer_position(q->buffer);
1013  /* owner type class ttl */
1014  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_owner(rr)))) {
1015  goto query_add_rr_tc;
1016  }
1017  buffer_write_rdf(q->buffer, ldns_rr_owner(rr));
1018  if (!buffer_available(q->buffer, sizeof(uint16_t) + sizeof(uint16_t) +
1019  sizeof(uint32_t) + sizeof(rdlength))) {
1020  goto query_add_rr_tc;
1021  }
1022  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_type(rr));
1023  buffer_write_u16(q->buffer, (uint16_t) ldns_rr_get_class(rr));
1024  buffer_write_u32(q->buffer, (uint32_t) ldns_rr_ttl(rr));
1025  /* skip rdlength */
1026  rdlength_pos = buffer_position(q->buffer);
1027  buffer_skip(q->buffer, sizeof(rdlength));
1028  /* write rdata */
1029  for (i=0; i < ldns_rr_rd_count(rr); i++) {
1030  if (!buffer_available(q->buffer, ldns_rdf_size(ldns_rr_rdf(rr, i)))) {
1031  goto query_add_rr_tc;
1032  }
1033  buffer_write_rdf(q->buffer, ldns_rr_rdf(rr, i));
1034  }
1035 
1036  if (!query_overflow(q)) {
1037  /* write rdlength */
1038  rdlength = buffer_position(q->buffer) - rdlength_pos - sizeof(rdlength);
1039  buffer_write_u16_at(q->buffer, rdlength_pos, rdlength);
1040  /* position updated by buffer_write() */
1041  return 1;
1042  }
1043 
1044 query_add_rr_tc:
1045  buffer_set_position(q->buffer, tc_mark);
1046  ods_log_assert(!query_overflow(q));
1047  return 0;
1048 
1049 }
1050 
1051 
1056 void
1058 {
1059  allocator_type* allocator = NULL;
1060  if (!q) {
1061  return;
1062  }
1063  allocator = q->allocator;
1064  if (q->axfr_fd) {
1065  ods_fclose(q->axfr_fd);
1066  q->axfr_fd = NULL;
1067  }
1068  buffer_cleanup(q->buffer, allocator);
1070  allocator_deallocate(allocator, (void*)q);
1071  allocator_cleanup(allocator);
1072  return;
1073 }
edns_data_type edns
Definition: engine.h:68
ldns_pkt_opcode buffer_pkt_opcode(buffer_type *buffer)
Definition: buffer.c:912
query_type * query_create(void)
Definition: query.c:50
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition: tsig.c:606
size_t maxlen
Definition: query.h:68
zonelist_type * zonelist
Definition: engine.h:62
tsig_status status
Definition: tsig.h:128
size_t rr_count
Definition: rrset.h:81
int edns_rr_parse(edns_rr_type *err, buffer_type *buffer)
Definition: edns.c:120
int buffer_pkt_rd(buffer_type *buffer)
Definition: buffer.c:974
unsigned tsig_sign_it
Definition: query.h:92
const char * rrset_type2str(ldns_rr_type type)
Definition: rrset.c:162
int tcp
Definition: query.h:75
void query_cleanup(query_type *q)
Definition: query.c:1057
void * config
Definition: adapter.h:63
void ods_log_debug(const char *format,...)
Definition: log.c:272
tsig_rr_type * tsig_rr
Definition: query.h:71
#define UDP_MAX_MESSAGE_LEN
Definition: query.h:44
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:365
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition: buffer.c:1138
zone_type * zone
Definition: query.h:81
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:45
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:68
uint16_t error_code
Definition: tsig.h:146
void edns_rr_reset(edns_rr_type *err)
Definition: edns.c:102
const char * query_str
Definition: query.c:42
uint32_t serial_notify
Definition: xfrd.h:110
unsigned tsig_update_it
Definition: query.h:91
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition: buffer.c:1063
#define OPT_RDATA
Definition: edns.h:46
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition: buffer.c:188
void buffer_pkt_set_flags(buffer_type *buffer, uint16_t flags)
Definition: buffer.c:861
uint16_t buffer_read_u16(buffer_type *buffer)
Definition: buffer.c:783
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition: buffer.c:382
void buffer_pkt_set_qdcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1075
void buffer_clear(buffer_type *buffer)
Definition: buffer.c:121
void ods_log_info(const char *format,...)
Definition: log.c:304
time_t serial_notify_acquired
Definition: xfrd.h:113
size_t rrset_count
Definition: query.h:101
lock_basic_type zone_lock
Definition: zone.h:97
void ods_log_error(const char *format,...)
Definition: log.c:336
size_t position
Definition: edns.h:81
adapter_mode type
Definition: adapter.h:60
zone_zl_status zl_status
Definition: zone.h:81
size_t reserved_space
Definition: query.h:69
void query_reset(query_type *q, size_t maxlen, int is_tcp)
Definition: query.c:92
int buffer_pkt_qr(buffer_type *buffer)
Definition: buffer.c:874
edns_rr_type * edns_rr
Definition: query.h:73
int dnssec_ok
Definition: edns.h:83
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.c:334
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:722
unsigned tsig_prepare_it
Definition: query.h:90
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition: buffer.c:594
struct sockaddr_storage addr
Definition: query.h:65
rrset_type * rrsets[QUERY_RESPONSE_MAX_RRSET]
Definition: query.h:103
lock_basic_type serial_lock
Definition: xfrd.h:98
uint8_t * buffer_current(buffer_type *buffer)
Definition: buffer.c:491
adapter_type * adoutbound
Definition: zone.h:84
int util_serial_gt(uint32_t serial_new, uint32_t serial_old)
Definition: util.c:74
buffer_type * buffer_create(allocator_type *allocator, size_t capacity)
Definition: buffer.c:80
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1088
size_t buffer_limit(buffer_type *buffer)
Definition: buffer.c:413
edns_rr_type * edns_rr_create(allocator_type *allocator)
Definition: edns.c:52
void tsig_rr_prepare(tsig_rr_type *trr)
Definition: tsig.c:581
void buffer_pkt_set_ancount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1100
#define lock_basic_lock(lock)
Definition: locks.h:93
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:811
void buffer_pkt_set_nscount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1125
allocator_type * allocator
Definition: query.h:63
void buffer_set_limit(buffer_type *buffer, size_t limit)
Definition: buffer.c:425
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
Definition: allocator.c:49
zone_type * zonelist_lookup_zone_by_dname(zonelist_type *zonelist, ldns_rdf *dname, ldns_rr_class klass)
Definition: zonelist.c:188
acl_type * provide_xfr
Definition: addns.h:67
uint16_t buffer_pkt_flags(buffer_type *buffer)
Definition: buffer.c:849
query_state axfr(query_type *q, engine_type *engine, int fallback)
Definition: axfr.c:154
ldns_rr * rr
Definition: rrset.h:50
Definition: edns.h:68
Definition: tsig.h:60
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition: tsig.c:885
query_state query_process(query_type *q, void *engine)
Definition: query.c:813
adapter_type * adinbound
Definition: zone.h:83
size_t buffer_capacity(buffer_type *buffer)
Definition: buffer.c:442
int buffer_skip_dname(buffer_type *buffer)
Definition: buffer.c:350
acl_type * allow_notify
Definition: addns.h:55
uint32_t buffer_read_u32(buffer_type *buffer)
Definition: buffer.c:798
void buffer_pkt_set_opcode(buffer_type *buffer, ldns_pkt_opcode opcode)
Definition: buffer.c:924
uint32_t serial
Definition: query.h:86
enum query_enum query_state
Definition: query.h:54
buffer_type * buffer
Definition: query.h:77
#define PACKET_BUFFER_SIZE
Definition: buffer.h:51
#define EDNS_MAX_MESSAGE_LEN
Definition: edns.h:49
int tsig_rr_verify(tsig_rr_type *trr)
Definition: tsig.c:700
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition: buffer.c:623
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition: buffer.c:637
void buffer_pkt_set_aa(buffer_type *buffer)
Definition: buffer.c:949
tsig_rr_type * tsig_rr_create(allocator_type *allocator)
Definition: tsig.c:307
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:793
size_t startpos
Definition: query.h:87
unsigned axfr_is_done
Definition: query.h:89
int buffer_pkt_aa(buffer_type *buffer)
Definition: buffer.c:937
query_state ixfr(query_type *q, engine_type *engine)
Definition: axfr.c:389
ldns_rr * rr
Definition: rrset.h:62
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition: buffer.c:1113
acl_type * acl_find(acl_type *acl, struct sockaddr_storage *addr, tsig_rr_type *trr)
Definition: acl.c:447
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
Definition: zone.c:542
size_t position
Definition: tsig.h:129
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition: buffer.c:566
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:174
void ods_fclose(FILE *fd)
Definition: file.c:247
socklen_t addrlen
Definition: query.h:66
void xfrd_set_timer_now(xfrd_type *xfrd)
Definition: xfrd.c:241
int buffer_available(buffer_type *buffer, size_t count)
Definition: buffer.c:540
size_t maxlen
Definition: edns.h:82
int buffer_pkt_ad(buffer_type *buffer)
Definition: buffer.c:998
void allocator_cleanup(allocator_type *allocator)
Definition: allocator.c:153
const char * name
Definition: zone.h:78
int tsig_rr_lookup(tsig_rr_type *trr)
Definition: tsig.c:512
size_t buffer_remaining(buffer_type *buffer)
Definition: buffer.c:516
void buffer_pkt_set_rcode(buffer_type *buffer, ldns_pkt_rcode rcode)
Definition: buffer.c:1034
#define OPT_LEN
Definition: edns.h:45
query_state soa_request(query_type *q, engine_type *engine)
Definition: axfr.c:55
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition: buffer.c:651
size_t rrsig_count
Definition: rrset.h:82
int buffer_pkt_ra(buffer_type *buffer)
Definition: buffer.c:986
void tsig_rr_sign(tsig_rr_type *trr)
Definition: tsig.c:678
void query_prepare(query_type *q)
Definition: query.c:577
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:137
int query_add_rr(query_type *q, ldns_rr *rr)
Definition: query.c:1000
size_t edns_rr_reserved_space(edns_rr_type *err)
Definition: edns.c:173
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:162
FILE * axfr_fd
Definition: query.h:85
unsigned char error[OPT_LEN]
Definition: edns.h:58
void buffer_cleanup(buffer_type *buffer, allocator_type *allocator)
Definition: buffer.c:1263
unsigned char ok[OPT_LEN]
Definition: edns.h:57
void buffer_pkt_set_arcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1150
rrsig_type * rrsigs
Definition: rrset.h:80
#define ods_log_assert(x)
Definition: log.h:156
edns_status status
Definition: edns.h:80
int buffer_pkt_cd(buffer_type *buffer)
Definition: buffer.c:1010
xfrd_type * xfrd
Definition: zone.h:91
ldns_pkt_section sections[QUERY_RESPONSE_MAX_RRSET]
Definition: query.h:102
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
Definition: dnshandler.c:249
int addr2ip(struct sockaddr_storage addr, char *ip, size_t len)
Definition: acl.c:426
#define lock_basic_unlock(lock)
Definition: locks.h:94
void ods_log_warning(const char *format,...)
Definition: log.c:320
ldns_rdf * apex
Definition: zone.h:70
lock_basic_type zl_lock
Definition: zonelist.h:57
unsigned char rdata_none[OPT_RDATA]
Definition: edns.h:59
void buffer_pkt_set_qr(buffer_type *buffer)
Definition: buffer.c:886
uint8_t * buffer_begin(buffer_type *buffer)
Definition: buffer.c:467
time_t time_now(void)
Definition: duration.c:515
uint32_t serial_disk
Definition: xfrd.h:111
ldns_pkt_rcode buffer_pkt_rcode(buffer_type *buffer)
Definition: buffer.c:1022
dnshandler_type * dnshandler
Definition: engine.h:66
int buffer_pkt_tc(buffer_type *buffer)
Definition: buffer.c:962
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition: tsig.c:764
rr_type * rrs
Definition: rrset.h:79
void query_add_optional(query_type *q, void *engine)
Definition: query.c:919