Deleted Added
full compact
msgreply.c (307729) msgreply.c (356345)
1/*
2 * util/data/msgreply.c - store message and reply data.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 38 unchanged lines hidden (view full) ---

47#include "util/netevent.h"
48#include "util/net_help.h"
49#include "util/data/dname.h"
50#include "util/regional.h"
51#include "util/data/msgparse.h"
52#include "util/data/msgencode.h"
53#include "sldns/sbuffer.h"
54#include "sldns/wire2str.h"
1/*
2 * util/data/msgreply.c - store message and reply data.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 38 unchanged lines hidden (view full) ---

47#include "util/netevent.h"
48#include "util/net_help.h"
49#include "util/data/dname.h"
50#include "util/regional.h"
51#include "util/data/msgparse.h"
52#include "util/data/msgencode.h"
53#include "sldns/sbuffer.h"
54#include "sldns/wire2str.h"
55#include "util/module.h"
56#include "util/fptr_wlist.h"
55
56/** MAX TTL default for messages and rrsets */
57time_t MAX_TTL = 3600 * 24 * 10; /* ten days */
58/** MIN TTL default for messages and rrsets */
59time_t MIN_TTL = 0;
60/** MAX Negative TTL, for SOA records in authority section */
61time_t MAX_NEG_TTL = 3600; /* one hour */
57
58/** MAX TTL default for messages and rrsets */
59time_t MAX_TTL = 3600 * 24 * 10; /* ten days */
60/** MIN TTL default for messages and rrsets */
61time_t MIN_TTL = 0;
62/** MAX Negative TTL, for SOA records in authority section */
63time_t MAX_NEG_TTL = 3600; /* one hour */
64/** Time to serve records after expiration */
65time_t SERVE_EXPIRED_TTL = 0;
62
63/** allocate qinfo, return 0 on error */
64static int
65parse_create_qinfo(sldns_buffer* pkt, struct msg_parse* msg,
66 struct query_info* qinf, struct regional* region)
67{
68 if(msg->qname) {
69 if(region)
70 qinf->qname = (uint8_t*)regional_alloc(region,
71 msg->qname_len);
72 else qinf->qname = (uint8_t*)malloc(msg->qname_len);
73 if(!qinf->qname) return 0;
74 dname_pkt_copy(pkt, qinf->qname, msg->qname);
75 } else qinf->qname = 0;
76 qinf->qname_len = msg->qname_len;
77 qinf->qtype = msg->qtype;
78 qinf->qclass = msg->qclass;
66
67/** allocate qinfo, return 0 on error */
68static int
69parse_create_qinfo(sldns_buffer* pkt, struct msg_parse* msg,
70 struct query_info* qinf, struct regional* region)
71{
72 if(msg->qname) {
73 if(region)
74 qinf->qname = (uint8_t*)regional_alloc(region,
75 msg->qname_len);
76 else qinf->qname = (uint8_t*)malloc(msg->qname_len);
77 if(!qinf->qname) return 0;
78 dname_pkt_copy(pkt, qinf->qname, msg->qname);
79 } else qinf->qname = 0;
80 qinf->qname_len = msg->qname_len;
81 qinf->qtype = msg->qtype;
82 qinf->qclass = msg->qclass;
83 qinf->local_alias = NULL;
79 return 1;
80}
81
82/** constructor for replyinfo */
83struct reply_info*
84construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
84 return 1;
85}
86
87/** constructor for replyinfo */
88struct reply_info*
89construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
85 time_t ttl, time_t prettl, size_t an, size_t ns, size_t ar,
86 size_t total, enum sec_status sec)
90 time_t ttl, time_t prettl, time_t expttl, size_t an, size_t ns,
91 size_t ar, size_t total, enum sec_status sec)
87{
88 struct reply_info* rep;
89 /* rrset_count-1 because the first ref is part of the struct. */
90 size_t s = sizeof(struct reply_info) - sizeof(struct rrset_ref) +
91 sizeof(struct ub_packed_rrset_key*) * total;
92 if(total >= RR_COUNT_MAX) return NULL; /* sanity check on numRRS*/
93 if(region)
94 rep = (struct reply_info*)regional_alloc(region, s);
95 else rep = (struct reply_info*)malloc(s +
96 sizeof(struct rrset_ref) * (total));
97 if(!rep)
98 return NULL;
99 rep->flags = flags;
100 rep->qdcount = qd;
101 rep->ttl = ttl;
102 rep->prefetch_ttl = prettl;
92{
93 struct reply_info* rep;
94 /* rrset_count-1 because the first ref is part of the struct. */
95 size_t s = sizeof(struct reply_info) - sizeof(struct rrset_ref) +
96 sizeof(struct ub_packed_rrset_key*) * total;
97 if(total >= RR_COUNT_MAX) return NULL; /* sanity check on numRRS*/
98 if(region)
99 rep = (struct reply_info*)regional_alloc(region, s);
100 else rep = (struct reply_info*)malloc(s +
101 sizeof(struct rrset_ref) * (total));
102 if(!rep)
103 return NULL;
104 rep->flags = flags;
105 rep->qdcount = qd;
106 rep->ttl = ttl;
107 rep->prefetch_ttl = prettl;
108 rep->serve_expired_ttl = expttl;
103 rep->an_numrrsets = an;
104 rep->ns_numrrsets = ns;
105 rep->ar_numrrsets = ar;
106 rep->rrset_count = total;
107 rep->security = sec;
108 rep->authoritative = 0;
109 /* array starts after the refs */
110 if(region)

--- 7 unchanged lines hidden (view full) ---

118}
119
120/** allocate replyinfo, return 0 on error */
121static int
122parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep,
123 struct regional* region)
124{
125 *rep = construct_reply_info_base(region, msg->flags, msg->qdcount, 0,
109 rep->an_numrrsets = an;
110 rep->ns_numrrsets = ns;
111 rep->ar_numrrsets = ar;
112 rep->rrset_count = total;
113 rep->security = sec;
114 rep->authoritative = 0;
115 /* array starts after the refs */
116 if(region)

--- 7 unchanged lines hidden (view full) ---

124}
125
126/** allocate replyinfo, return 0 on error */
127static int
128parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep,
129 struct regional* region)
130{
131 *rep = construct_reply_info_base(region, msg->flags, msg->qdcount, 0,
126 0, msg->an_rrsets, msg->ns_rrsets, msg->ar_rrsets,
132 0, 0, msg->an_rrsets, msg->ns_rrsets, msg->ar_rrsets,
127 msg->rrset_count, sec_status_unchecked);
128 if(!*rep)
129 return 0;
130 return 1;
131}
132
133 msg->rrset_count, sec_status_unchecked);
134 if(!*rep)
135 return 0;
136 return 1;
137}
138
133/** allocate (special) rrset keys, return 0 on error */
134static int
135repinfo_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
139int
140reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
136 struct regional* region)
137{
138 size_t i;
139 for(i=0; i<rep->rrset_count; i++) {
140 if(region) {
141 rep->rrsets[i] = (struct ub_packed_rrset_key*)
142 regional_alloc(region,
143 sizeof(struct ub_packed_rrset_key));

--- 41 unchanged lines hidden (view full) ---

185 * minimum-ttl in the rdata of the SOA record */
186 if(*rr_ttl > soa_find_minttl(rr))
187 *rr_ttl = soa_find_minttl(rr);
188 if(*rr_ttl > MAX_NEG_TTL)
189 *rr_ttl = MAX_NEG_TTL;
190 }
191 if(*rr_ttl < MIN_TTL)
192 *rr_ttl = MIN_TTL;
141 struct regional* region)
142{
143 size_t i;
144 for(i=0; i<rep->rrset_count; i++) {
145 if(region) {
146 rep->rrsets[i] = (struct ub_packed_rrset_key*)
147 regional_alloc(region,
148 sizeof(struct ub_packed_rrset_key));

--- 41 unchanged lines hidden (view full) ---

190 * minimum-ttl in the rdata of the SOA record */
191 if(*rr_ttl > soa_find_minttl(rr))
192 *rr_ttl = soa_find_minttl(rr);
193 if(*rr_ttl > MAX_NEG_TTL)
194 *rr_ttl = MAX_NEG_TTL;
195 }
196 if(*rr_ttl < MIN_TTL)
197 *rr_ttl = MIN_TTL;
198 if(*rr_ttl > MAX_TTL)
199 *rr_ttl = MAX_TTL;
193 if(*rr_ttl < data->ttl)
194 data->ttl = *rr_ttl;
195
196 if(rr->outside_packet) {
197 /* uncompressed already, only needs copy */
198 memmove(to, rr->ttl_data+sizeof(uint32_t), rr->size);
199 return 1;
200 }

--- 30 unchanged lines hidden (view full) ---

231 case LDNS_RDF_TYPE_STR:
232 len = sldns_buffer_current(pkt)[0] + 1;
233 break;
234 default:
235 len = get_rdf_size(desc->_wireformat[rdf]);
236 break;
237 }
238 if(len) {
200 if(*rr_ttl < data->ttl)
201 data->ttl = *rr_ttl;
202
203 if(rr->outside_packet) {
204 /* uncompressed already, only needs copy */
205 memmove(to, rr->ttl_data+sizeof(uint32_t), rr->size);
206 return 1;
207 }

--- 30 unchanged lines hidden (view full) ---

238 case LDNS_RDF_TYPE_STR:
239 len = sldns_buffer_current(pkt)[0] + 1;
240 break;
241 default:
242 len = get_rdf_size(desc->_wireformat[rdf]);
243 break;
244 }
245 if(len) {
246 log_assert(len <= pkt_len);
239 memmove(to, sldns_buffer_current(pkt), len);
240 to += len;
241 sldns_buffer_skip(pkt, (ssize_t)len);
247 memmove(to, sldns_buffer_current(pkt), len);
248 to += len;
249 sldns_buffer_skip(pkt, (ssize_t)len);
242 log_assert(len <= pkt_len);
243 pkt_len -= len;
244 }
245 rdf++;
246 }
247 }
248 /* copy remaining rdata */
249 if(pkt_len > 0)
250 memmove(to, sldns_buffer_current(pkt), pkt_len);

--- 166 unchanged lines hidden (view full) ---

417 return 0;
418 data = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
419 if(data->ttl < rep->ttl)
420 rep->ttl = data->ttl;
421
422 pset = pset->rrset_all_next;
423 }
424 rep->prefetch_ttl = PREFETCH_TTL_CALC(rep->ttl);
250 pkt_len -= len;
251 }
252 rdf++;
253 }
254 }
255 /* copy remaining rdata */
256 if(pkt_len > 0)
257 memmove(to, sldns_buffer_current(pkt), pkt_len);

--- 166 unchanged lines hidden (view full) ---

424 return 0;
425 data = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
426 if(data->ttl < rep->ttl)
427 rep->ttl = data->ttl;
428
429 pset = pset->rrset_all_next;
430 }
431 rep->prefetch_ttl = PREFETCH_TTL_CALC(rep->ttl);
432 rep->serve_expired_ttl = rep->ttl + SERVE_EXPIRED_TTL;
425 return 1;
426}
427
428int
429parse_create_msg(sldns_buffer* pkt, struct msg_parse* msg,
430 struct alloc_cache* alloc, struct query_info* qinf,
431 struct reply_info** rep, struct regional* region)
432{
433 log_assert(pkt && msg);
434 if(!parse_create_qinfo(pkt, msg, qinf, region))
435 return 0;
436 if(!parse_create_repinfo(msg, rep, region))
437 return 0;
433 return 1;
434}
435
436int
437parse_create_msg(sldns_buffer* pkt, struct msg_parse* msg,
438 struct alloc_cache* alloc, struct query_info* qinf,
439 struct reply_info** rep, struct regional* region)
440{
441 log_assert(pkt && msg);
442 if(!parse_create_qinfo(pkt, msg, qinf, region))
443 return 0;
444 if(!parse_create_repinfo(msg, rep, region))
445 return 0;
438 if(!repinfo_alloc_rrset_keys(*rep, alloc, region))
446 if(!reply_info_alloc_rrset_keys(*rep, alloc, region)) {
447 if(!region) reply_info_parsedelete(*rep, alloc);
439 return 0;
448 return 0;
440 if(!parse_copy_decompress(pkt, msg, *rep, region))
449 }
450 if(!parse_copy_decompress(pkt, msg, *rep, region)) {
451 if(!region) reply_info_parsedelete(*rep, alloc);
441 return 0;
452 return 0;
453 }
442 return 1;
443}
444
445int reply_info_parse(sldns_buffer* pkt, struct alloc_cache* alloc,
446 struct query_info* qinf, struct reply_info** rep,
447 struct regional* region, struct edns_data* edns)
448{
449 /* use scratch pad region-allocator during parsing. */
450 struct msg_parse* msg;
451 int ret;
452
453 qinf->qname = NULL;
454 return 1;
455}
456
457int reply_info_parse(sldns_buffer* pkt, struct alloc_cache* alloc,
458 struct query_info* qinf, struct reply_info** rep,
459 struct regional* region, struct edns_data* edns)
460{
461 /* use scratch pad region-allocator during parsing. */
462 struct msg_parse* msg;
463 int ret;
464
465 qinf->qname = NULL;
466 qinf->local_alias = NULL;
454 *rep = NULL;
455 if(!(msg = regional_alloc(region, sizeof(*msg)))) {
456 return LDNS_RCODE_SERVFAIL;
457 }
458 memset(msg, 0, sizeof(*msg));
459
460 sldns_buffer_set_position(pkt, 0);
461 if((ret = parse_packet(pkt, msg, region)) != 0) {

--- 32 unchanged lines hidden (view full) ---

494}
495
496void
497reply_info_set_ttls(struct reply_info* rep, time_t timenow)
498{
499 size_t i, j;
500 rep->ttl += timenow;
501 rep->prefetch_ttl += timenow;
467 *rep = NULL;
468 if(!(msg = regional_alloc(region, sizeof(*msg)))) {
469 return LDNS_RCODE_SERVFAIL;
470 }
471 memset(msg, 0, sizeof(*msg));
472
473 sldns_buffer_set_position(pkt, 0);
474 if((ret = parse_packet(pkt, msg, region)) != 0) {

--- 32 unchanged lines hidden (view full) ---

507}
508
509void
510reply_info_set_ttls(struct reply_info* rep, time_t timenow)
511{
512 size_t i, j;
513 rep->ttl += timenow;
514 rep->prefetch_ttl += timenow;
515 rep->serve_expired_ttl += timenow;
502 for(i=0; i<rep->rrset_count; i++) {
503 struct packed_rrset_data* data = (struct packed_rrset_data*)
504 rep->ref[i].key->entry.data;
505 if(i>0 && rep->ref[i].key == rep->ref[i-1].key)
506 continue;
507 data->ttl += timenow;
508 for(j=0; j<data->count + data->rrsig_count; j++) {
509 data->rr_ttl[j] += timenow;

--- 16 unchanged lines hidden (view full) ---

526
527int
528query_info_parse(struct query_info* m, sldns_buffer* query)
529{
530 uint8_t* q = sldns_buffer_begin(query);
531 /* minimum size: header + \0 + qtype + qclass */
532 if(sldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5)
533 return 0;
516 for(i=0; i<rep->rrset_count; i++) {
517 struct packed_rrset_data* data = (struct packed_rrset_data*)
518 rep->ref[i].key->entry.data;
519 if(i>0 && rep->ref[i].key == rep->ref[i-1].key)
520 continue;
521 data->ttl += timenow;
522 for(j=0; j<data->count + data->rrsig_count; j++) {
523 data->rr_ttl[j] += timenow;

--- 16 unchanged lines hidden (view full) ---

540
541int
542query_info_parse(struct query_info* m, sldns_buffer* query)
543{
544 uint8_t* q = sldns_buffer_begin(query);
545 /* minimum size: header + \0 + qtype + qclass */
546 if(sldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5)
547 return 0;
534 if(LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY ||
535 LDNS_QDCOUNT(q) != 1 || sldns_buffer_position(query) != 0)
548 if((LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY && LDNS_OPCODE_WIRE(q) !=
549 LDNS_PACKET_NOTIFY) || LDNS_QDCOUNT(q) != 1 ||
550 sldns_buffer_position(query) != 0)
536 return 0;
537 sldns_buffer_skip(query, LDNS_HEADER_SIZE);
538 m->qname = sldns_buffer_current(query);
539 if((m->qname_len = query_dname_len(query)) == 0)
540 return 0; /* parse error */
541 if(sldns_buffer_remaining(query) < 4)
542 return 0; /* need qtype, qclass */
543 m->qtype = sldns_buffer_read_u16(query);
544 m->qclass = sldns_buffer_read_u16(query);
551 return 0;
552 sldns_buffer_skip(query, LDNS_HEADER_SIZE);
553 m->qname = sldns_buffer_current(query);
554 if((m->qname_len = query_dname_len(query)) == 0)
555 return 0; /* parse error */
556 if(sldns_buffer_remaining(query) < 4)
557 return 0; /* need qtype, qclass */
558 m->qtype = sldns_buffer_read_u16(query);
559 m->qclass = sldns_buffer_read_u16(query);
560 m->local_alias = NULL;
545 return 1;
546}
547
548/** tiny subroutine for msgreply_compare */
549#define COMPARE_IT(x, y) \
550 if( (x) < (y) ) return -1; \
551 else if( (x) > (y) ) return +1; \
552 log_assert( (x) == (y) );

--- 45 unchanged lines hidden (view full) ---

598
599void
600reply_info_delete(void* d, void* ATTR_UNUSED(arg))
601{
602 struct reply_info* r = (struct reply_info*)d;
603 free(r);
604}
605
561 return 1;
562}
563
564/** tiny subroutine for msgreply_compare */
565#define COMPARE_IT(x, y) \
566 if( (x) < (y) ) return -1; \
567 else if( (x) > (y) ) return +1; \
568 log_assert( (x) == (y) );

--- 45 unchanged lines hidden (view full) ---

614
615void
616reply_info_delete(void* d, void* ATTR_UNUSED(arg))
617{
618 struct reply_info* r = (struct reply_info*)d;
619 free(r);
620}
621
606hashvalue_t
622hashvalue_type
607query_info_hash(struct query_info *q, uint16_t flags)
608{
623query_info_hash(struct query_info *q, uint16_t flags)
624{
609 hashvalue_t h = 0xab;
625 hashvalue_type h = 0xab;
610 h = hashlittle(&q->qtype, sizeof(q->qtype), h);
611 if(q->qtype == LDNS_RR_TYPE_AAAA && (flags&BIT_CD))
612 h++;
613 h = hashlittle(&q->qclass, sizeof(q->qclass), h);
614 h = dname_query_hash(q->qname, h);
615 return h;
616}
617
618struct msgreply_entry*
619query_info_entrysetup(struct query_info* q, struct reply_info* r,
626 h = hashlittle(&q->qtype, sizeof(q->qtype), h);
627 if(q->qtype == LDNS_RR_TYPE_AAAA && (flags&BIT_CD))
628 h++;
629 h = hashlittle(&q->qclass, sizeof(q->qclass), h);
630 h = dname_query_hash(q->qname, h);
631 return h;
632}
633
634struct msgreply_entry*
635query_info_entrysetup(struct query_info* q, struct reply_info* r,
620 hashvalue_t h)
636 hashvalue_type h)
621{
622 struct msgreply_entry* e = (struct msgreply_entry*)malloc(
623 sizeof(struct msgreply_entry));
624 if(!e) return NULL;
625 memcpy(&e->key, q, sizeof(*q));
626 e->entry.hash = h;
627 e->entry.key = e;
628 e->entry.data = r;
629 lock_rw_init(&e->entry.lock);
637{
638 struct msgreply_entry* e = (struct msgreply_entry*)malloc(
639 sizeof(struct msgreply_entry));
640 if(!e) return NULL;
641 memcpy(&e->key, q, sizeof(*q));
642 e->entry.hash = h;
643 e->entry.key = e;
644 e->entry.data = r;
645 lock_rw_init(&e->entry.lock);
630 lock_protect(&e->entry.lock, &e->key, sizeof(e->key));
631 lock_protect(&e->entry.lock, &e->entry.hash, sizeof(e->entry.hash) +
632 sizeof(e->entry.key) + sizeof(e->entry.data));
646 lock_protect(&e->entry.lock, &e->key.qname, sizeof(e->key.qname));
647 lock_protect(&e->entry.lock, &e->key.qname_len, sizeof(e->key.qname_len));
648 lock_protect(&e->entry.lock, &e->key.qtype, sizeof(e->key.qtype));
649 lock_protect(&e->entry.lock, &e->key.qclass, sizeof(e->key.qclass));
650 lock_protect(&e->entry.lock, &e->key.local_alias, sizeof(e->key.local_alias));
651 lock_protect(&e->entry.lock, &e->entry.hash, sizeof(e->entry.hash));
652 lock_protect(&e->entry.lock, &e->entry.key, sizeof(e->entry.key));
653 lock_protect(&e->entry.lock, &e->entry.data, sizeof(e->entry.data));
633 lock_protect(&e->entry.lock, e->key.qname, e->key.qname_len);
634 q->qname = NULL;
635 return e;
636}
637
638/** copy rrsets from replyinfo to dest replyinfo */
639static int
640repinfo_copy_rrsets(struct reply_info* dest, struct reply_info* from,

--- 31 unchanged lines hidden (view full) ---

672}
673
674struct reply_info*
675reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc,
676 struct regional* region)
677{
678 struct reply_info* cp;
679 cp = construct_reply_info_base(region, rep->flags, rep->qdcount,
654 lock_protect(&e->entry.lock, e->key.qname, e->key.qname_len);
655 q->qname = NULL;
656 return e;
657}
658
659/** copy rrsets from replyinfo to dest replyinfo */
660static int
661repinfo_copy_rrsets(struct reply_info* dest, struct reply_info* from,

--- 31 unchanged lines hidden (view full) ---

693}
694
695struct reply_info*
696reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc,
697 struct regional* region)
698{
699 struct reply_info* cp;
700 cp = construct_reply_info_base(region, rep->flags, rep->qdcount,
680 rep->ttl, rep->prefetch_ttl, rep->an_numrrsets,
681 rep->ns_numrrsets, rep->ar_numrrsets, rep->rrset_count,
682 rep->security);
701 rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
702 rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
703 rep->rrset_count, rep->security);
683 if(!cp)
684 return NULL;
685 /* allocate ub_key structures special or not */
704 if(!cp)
705 return NULL;
706 /* allocate ub_key structures special or not */
686 if(!repinfo_alloc_rrset_keys(cp, alloc, region)) {
707 if(!reply_info_alloc_rrset_keys(cp, alloc, region)) {
687 if(!region)
688 reply_info_parsedelete(cp, alloc);
689 return NULL;
690 }
691 if(!repinfo_copy_rrsets(cp, rep, region)) {
692 if(!region)
693 reply_info_parsedelete(cp, alloc);
694 return NULL;

--- 98 unchanged lines hidden (view full) ---

793
794void
795log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
796{
797 /* not particularly fast but flexible, make wireformat and print */
798 sldns_buffer* buf = sldns_buffer_new(65535);
799 struct regional* region = regional_create();
800 if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0,
708 if(!region)
709 reply_info_parsedelete(cp, alloc);
710 return NULL;
711 }
712 if(!repinfo_copy_rrsets(cp, rep, region)) {
713 if(!region)
714 reply_info_parsedelete(cp, alloc);
715 return NULL;

--- 98 unchanged lines hidden (view full) ---

814
815void
816log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
817{
818 /* not particularly fast but flexible, make wireformat and print */
819 sldns_buffer* buf = sldns_buffer_new(65535);
820 struct regional* region = regional_create();
821 if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0,
801 region, 65535, 1)) {
822 region, 65535, 1, 0)) {
802 log_info("%s: log_dns_msg: out of memory", str);
803 } else {
804 char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf),
805 sldns_buffer_limit(buf));
806 if(!s) {
807 log_info("%s: log_dns_msg: ldns tostr failed", str);
808 } else {
809 log_info("%s %s", str, s);
810 }
811 free(s);
812 }
813 sldns_buffer_free(buf);
814 regional_destroy(region);
815}
816
823 log_info("%s: log_dns_msg: out of memory", str);
824 } else {
825 char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf),
826 sldns_buffer_limit(buf));
827 if(!s) {
828 log_info("%s: log_dns_msg: ldns tostr failed", str);
829 } else {
830 log_info("%s %s", str, s);
831 }
832 free(s);
833 }
834 sldns_buffer_free(buf);
835 regional_destroy(region);
836}
837
817void
838void
839log_reply_info(enum verbosity_value v, struct query_info *qinf,
840 struct sockaddr_storage *addr, socklen_t addrlen, struct timeval dur,
841 int cached, struct sldns_buffer *rmsg)
842{
843 char qname_buf[LDNS_MAX_DOMAINLEN+1];
844 char clientip_buf[128];
845 char rcode_buf[16];
846 char type_buf[16];
847 char class_buf[16];
848 size_t pktlen;
849 uint16_t rcode = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(rmsg, 2));
850
851 if(verbosity < v)
852 return;
853
854 sldns_wire2str_rcode_buf((int)rcode, rcode_buf, sizeof(rcode_buf));
855 addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf));
856 if(rcode == LDNS_RCODE_FORMERR)
857 {
858 if(LOG_TAG_QUERYREPLY)
859 log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf);
860 else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
861 } else {
862 if(qinf->qname)
863 dname_str(qinf->qname, qname_buf);
864 else snprintf(qname_buf, sizeof(qname_buf), "null");
865 pktlen = sldns_buffer_limit(rmsg);
866 sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf));
867 sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf));
868 if(LOG_TAG_QUERYREPLY)
869 log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
870 clientip_buf, qname_buf, type_buf, class_buf,
871 rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
872 else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
873 clientip_buf, qname_buf, type_buf, class_buf,
874 rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
875 }
876}
877
878void
818log_query_info(enum verbosity_value v, const char* str,
819 struct query_info* qinf)
820{
821 log_nametypeclass(v, str, qinf->qname, qinf->qtype, qinf->qclass);
822}
823
824int
825reply_check_cname_chain(struct query_info* qinfo, struct reply_info* rep)

--- 27 unchanged lines hidden (view full) ---

853 for(i=0; i<rep->rrset_count; i++) {
854 if( ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
855 ->security != sec_status_secure )
856 return 0;
857 }
858 return 1;
859}
860
879log_query_info(enum verbosity_value v, const char* str,
880 struct query_info* qinf)
881{
882 log_nametypeclass(v, str, qinf->qname, qinf->qtype, qinf->qclass);
883}
884
885int
886reply_check_cname_chain(struct query_info* qinfo, struct reply_info* rep)

--- 27 unchanged lines hidden (view full) ---

914 for(i=0; i<rep->rrset_count; i++) {
915 if( ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
916 ->security != sec_status_secure )
917 return 0;
918 }
919 return 1;
920}
921
922struct reply_info*
923parse_reply_in_temp_region(sldns_buffer* pkt, struct regional* region,
924 struct query_info* qi)
925{
926 struct reply_info* rep;
927 struct msg_parse* msg;
928 if(!(msg = regional_alloc(region, sizeof(*msg)))) {
929 return NULL;
930 }
931 memset(msg, 0, sizeof(*msg));
932 sldns_buffer_set_position(pkt, 0);
933 if(parse_packet(pkt, msg, region) != 0){
934 return 0;
935 }
936 if(!parse_create_msg(pkt, msg, NULL, qi, &rep, region)) {
937 return 0;
938 }
939 return rep;
940}
941
861int edns_opt_append(struct edns_data* edns, struct regional* region,
862 uint16_t code, size_t len, uint8_t* data)
863{
864 struct edns_option** prevp;
865 struct edns_option* opt;
866
867 /* allocate new element */
868 opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
869 if(!opt)
870 return 0;
871 opt->next = NULL;
872 opt->opt_code = code;
873 opt->opt_len = len;
942int edns_opt_append(struct edns_data* edns, struct regional* region,
943 uint16_t code, size_t len, uint8_t* data)
944{
945 struct edns_option** prevp;
946 struct edns_option* opt;
947
948 /* allocate new element */
949 opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
950 if(!opt)
951 return 0;
952 opt->next = NULL;
953 opt->opt_code = code;
954 opt->opt_len = len;
874 opt->opt_data = regional_alloc_init(region, data, len);
875 if(!opt->opt_data)
876 return 0;
955 opt->opt_data = NULL;
956 if(len > 0) {
957 opt->opt_data = regional_alloc_init(region, data, len);
958 if(!opt->opt_data)
959 return 0;
960 }
877
878 /* append at end of list */
879 prevp = &edns->opt_list;
880 while(*prevp != NULL)
881 prevp = &((*prevp)->next);
882 *prevp = opt;
883 return 1;
884}
885
961
962 /* append at end of list */
963 prevp = &edns->opt_list;
964 while(*prevp != NULL)
965 prevp = &((*prevp)->next);
966 *prevp = opt;
967 return 1;
968}
969
886int edns_opt_inplace_reply(struct edns_data* edns, struct regional* region)
970int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
971 uint8_t* data, struct regional* region)
887{
972{
888 (void)region;
889 /* remove all edns options from the reply, because only the
890 * options that we understand should be in the reply
891 * (sec 6.1.2 RFC 6891) */
892 edns->opt_list = NULL;
973 struct edns_option** prevp;
974 struct edns_option* opt;
975
976 /* allocate new element */
977 opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
978 if(!opt)
979 return 0;
980 opt->next = NULL;
981 opt->opt_code = code;
982 opt->opt_len = len;
983 opt->opt_data = NULL;
984 if(len > 0) {
985 opt->opt_data = regional_alloc_init(region, data, len);
986 if(!opt->opt_data)
987 return 0;
988 }
989
990 /* append at end of list */
991 prevp = list;
992 while(*prevp != NULL) {
993 prevp = &((*prevp)->next);
994 }
995 *prevp = opt;
893 return 1;
894}
895
996 return 1;
997}
998
999int edns_opt_list_remove(struct edns_option** list, uint16_t code)
1000{
1001 /* The list should already be allocated in a region. Freeing the
1002 * allocated space in a region is not possible. We just unlink the
1003 * required elements and they will be freed together with the region. */
1004
1005 struct edns_option* prev;
1006 struct edns_option* curr;
1007 if(!list || !(*list)) return 0;
1008
1009 /* Unlink and repoint if the element(s) are first in list */
1010 while(list && *list && (*list)->opt_code == code) {
1011 *list = (*list)->next;
1012 }
1013
1014 if(!list || !(*list)) return 1;
1015 /* Unlink elements and reattach the list */
1016 prev = *list;
1017 curr = (*list)->next;
1018 while(curr != NULL) {
1019 if(curr->opt_code == code) {
1020 prev->next = curr->next;
1021 curr = curr->next;
1022 } else {
1023 prev = curr;
1024 curr = curr->next;
1025 }
1026 }
1027 return 1;
1028}
1029
1030static int inplace_cb_reply_call_generic(
1031 struct inplace_cb* callback_list, enum inplace_cb_list_type type,
1032 struct query_info* qinfo, struct module_qstate* qstate,
1033 struct reply_info* rep, int rcode, struct edns_data* edns,
1034 struct comm_reply* repinfo, struct regional* region)
1035{
1036 struct inplace_cb* cb;
1037 struct edns_option* opt_list_out = NULL;
1038#if defined(EXPORT_ALL_SYMBOLS)
1039 (void)type; /* param not used when fptr_ok disabled */
1040#endif
1041 if(qstate)
1042 opt_list_out = qstate->edns_opts_front_out;
1043 for(cb=callback_list; cb; cb=cb->next) {
1044 fptr_ok(fptr_whitelist_inplace_cb_reply_generic(
1045 (inplace_cb_reply_func_type*)cb->cb, type));
1046 (void)(*(inplace_cb_reply_func_type*)cb->cb)(qinfo, qstate, rep,
1047 rcode, edns, &opt_list_out, repinfo, region, cb->id, cb->cb_arg);
1048 }
1049 edns->opt_list = opt_list_out;
1050 return 1;
1051}
1052
1053int inplace_cb_reply_call(struct module_env* env, struct query_info* qinfo,
1054 struct module_qstate* qstate, struct reply_info* rep, int rcode,
1055 struct edns_data* edns, struct comm_reply* repinfo, struct regional* region)
1056{
1057 return inplace_cb_reply_call_generic(
1058 env->inplace_cb_lists[inplace_cb_reply], inplace_cb_reply, qinfo,
1059 qstate, rep, rcode, edns, repinfo, region);
1060}
1061
1062int inplace_cb_reply_cache_call(struct module_env* env,
1063 struct query_info* qinfo, struct module_qstate* qstate,
1064 struct reply_info* rep, int rcode, struct edns_data* edns,
1065 struct comm_reply* repinfo, struct regional* region)
1066{
1067 return inplace_cb_reply_call_generic(
1068 env->inplace_cb_lists[inplace_cb_reply_cache], inplace_cb_reply_cache,
1069 qinfo, qstate, rep, rcode, edns, repinfo, region);
1070}
1071
1072int inplace_cb_reply_local_call(struct module_env* env,
1073 struct query_info* qinfo, struct module_qstate* qstate,
1074 struct reply_info* rep, int rcode, struct edns_data* edns,
1075 struct comm_reply* repinfo, struct regional* region)
1076{
1077 return inplace_cb_reply_call_generic(
1078 env->inplace_cb_lists[inplace_cb_reply_local], inplace_cb_reply_local,
1079 qinfo, qstate, rep, rcode, edns, repinfo, region);
1080}
1081
1082int inplace_cb_reply_servfail_call(struct module_env* env,
1083 struct query_info* qinfo, struct module_qstate* qstate,
1084 struct reply_info* rep, int rcode, struct edns_data* edns,
1085 struct comm_reply* repinfo, struct regional* region)
1086{
1087 /* We are going to servfail. Remove any potential edns options. */
1088 if(qstate)
1089 qstate->edns_opts_front_out = NULL;
1090 return inplace_cb_reply_call_generic(
1091 env->inplace_cb_lists[inplace_cb_reply_servfail],
1092 inplace_cb_reply_servfail, qinfo, qstate, rep, rcode, edns, repinfo,
1093 region);
1094}
1095
1096int inplace_cb_query_call(struct module_env* env, struct query_info* qinfo,
1097 uint16_t flags, struct sockaddr_storage* addr, socklen_t addrlen,
1098 uint8_t* zone, size_t zonelen, struct module_qstate* qstate,
1099 struct regional* region)
1100{
1101 struct inplace_cb* cb = env->inplace_cb_lists[inplace_cb_query];
1102 for(; cb; cb=cb->next) {
1103 fptr_ok(fptr_whitelist_inplace_cb_query(
1104 (inplace_cb_query_func_type*)cb->cb));
1105 (void)(*(inplace_cb_query_func_type*)cb->cb)(qinfo, flags,
1106 qstate, addr, addrlen, zone, zonelen, region,
1107 cb->id, cb->cb_arg);
1108 }
1109 return 1;
1110}
1111
1112int inplace_cb_edns_back_parsed_call(struct module_env* env,
1113 struct module_qstate* qstate)
1114{
1115 struct inplace_cb* cb =
1116 env->inplace_cb_lists[inplace_cb_edns_back_parsed];
1117 for(; cb; cb=cb->next) {
1118 fptr_ok(fptr_whitelist_inplace_cb_edns_back_parsed(
1119 (inplace_cb_edns_back_parsed_func_type*)cb->cb));
1120 (void)(*(inplace_cb_edns_back_parsed_func_type*)cb->cb)(qstate,
1121 cb->id, cb->cb_arg);
1122 }
1123 return 1;
1124}
1125
1126int inplace_cb_query_response_call(struct module_env* env,
1127 struct module_qstate* qstate, struct dns_msg* response) {
1128 struct inplace_cb* cb =
1129 env->inplace_cb_lists[inplace_cb_query_response];
1130 for(; cb; cb=cb->next) {
1131 fptr_ok(fptr_whitelist_inplace_cb_query_response(
1132 (inplace_cb_query_response_func_type*)cb->cb));
1133 (void)(*(inplace_cb_query_response_func_type*)cb->cb)(qstate,
1134 response, cb->id, cb->cb_arg);
1135 }
1136 return 1;
1137}
1138
896struct edns_option* edns_opt_copy_region(struct edns_option* list,
897 struct regional* region)
898{
899 struct edns_option* result = NULL, *cur = NULL, *s;
900 while(list) {
901 /* copy edns option structure */
902 s = regional_alloc_init(region, list, sizeof(*list));
903 if(!s) return NULL;

--- 74 unchanged lines hidden (view full) ---

978 return NULL;
979 }
980 s->next = NULL;
981
982 /* copy option data */
983 if(s->opt_data) {
984 s->opt_data = memdup(s->opt_data, s->opt_len);
985 if(!s->opt_data) {
1139struct edns_option* edns_opt_copy_region(struct edns_option* list,
1140 struct regional* region)
1141{
1142 struct edns_option* result = NULL, *cur = NULL, *s;
1143 while(list) {
1144 /* copy edns option structure */
1145 s = regional_alloc_init(region, list, sizeof(*list));
1146 if(!s) return NULL;

--- 74 unchanged lines hidden (view full) ---

1221 return NULL;
1222 }
1223 s->next = NULL;
1224
1225 /* copy option data */
1226 if(s->opt_data) {
1227 s->opt_data = memdup(s->opt_data, s->opt_len);
1228 if(!s->opt_data) {
1229 free(s);
986 edns_opt_list_free(result);
987 return NULL;
988 }
989 }
990
991 /* link into list */
992 if(cur)
993 cur->next = s;
994 else result = s;
995 cur = s;
996
997 /* examine next element */
998 list = list->next;
999 }
1000 return result;
1001}
1002
1230 edns_opt_list_free(result);
1231 return NULL;
1232 }
1233 }
1234
1235 /* link into list */
1236 if(cur)
1237 cur->next = s;
1238 else result = s;
1239 cur = s;
1240
1241 /* examine next element */
1242 list = list->next;
1243 }
1244 return result;
1245}
1246
1003struct edns_option* edns_opt_find(struct edns_option* list, uint16_t code)
1247struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code)
1004{
1005 struct edns_option* p;
1006 for(p=list; p; p=p->next) {
1007 if(p->opt_code == code)
1008 return p;
1009 }
1010 return NULL;
1011}
1248{
1249 struct edns_option* p;
1250 for(p=list; p; p=p->next) {
1251 if(p->opt_code == code)
1252 return p;
1253 }
1254 return NULL;
1255}