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} |