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