1b7579f77SDag-Erling Smørgrav /* 2b7579f77SDag-Erling Smørgrav * util/data/packed_rrset.c - data storage for a set of resource records. 3b7579f77SDag-Erling Smørgrav * 4b7579f77SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5b7579f77SDag-Erling Smørgrav * 6b7579f77SDag-Erling Smørgrav * This software is open source. 7b7579f77SDag-Erling Smørgrav * 8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10b7579f77SDag-Erling Smørgrav * are met: 11b7579f77SDag-Erling Smørgrav * 12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14b7579f77SDag-Erling Smørgrav * 15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18b7579f77SDag-Erling Smørgrav * 19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21b7579f77SDag-Erling Smørgrav * specific prior written permission. 22b7579f77SDag-Erling Smørgrav * 23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34b7579f77SDag-Erling Smørgrav */ 35b7579f77SDag-Erling Smørgrav 36b7579f77SDag-Erling Smørgrav /** 37b7579f77SDag-Erling Smørgrav * \file 38b7579f77SDag-Erling Smørgrav * 39b7579f77SDag-Erling Smørgrav * This file contains the data storage for RRsets. 40b7579f77SDag-Erling Smørgrav */ 41b7579f77SDag-Erling Smørgrav 42b7579f77SDag-Erling Smørgrav #include "config.h" 43091e9e46SCy Schubert #include "util/data/msgparse.h" 44b7579f77SDag-Erling Smørgrav #include "util/data/packed_rrset.h" 45b7579f77SDag-Erling Smørgrav #include "util/data/dname.h" 46b7579f77SDag-Erling Smørgrav #include "util/storage/lookup3.h" 47b7579f77SDag-Erling Smørgrav #include "util/log.h" 48b7579f77SDag-Erling Smørgrav #include "util/alloc.h" 49b7579f77SDag-Erling Smørgrav #include "util/regional.h" 50b7579f77SDag-Erling Smørgrav #include "util/net_help.h" 5109a3aaf3SDag-Erling Smørgrav #include "sldns/rrdef.h" 5209a3aaf3SDag-Erling Smørgrav #include "sldns/sbuffer.h" 5309a3aaf3SDag-Erling Smørgrav #include "sldns/wire2str.h" 54b7579f77SDag-Erling Smørgrav 55b7579f77SDag-Erling Smørgrav void 56b7579f77SDag-Erling Smørgrav ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey, 57b7579f77SDag-Erling Smørgrav struct alloc_cache* alloc) 58b7579f77SDag-Erling Smørgrav { 59b7579f77SDag-Erling Smørgrav if(!pkey) 60b7579f77SDag-Erling Smørgrav return; 61b7579f77SDag-Erling Smørgrav free(pkey->entry.data); 62b7579f77SDag-Erling Smørgrav pkey->entry.data = NULL; 63b7579f77SDag-Erling Smørgrav free(pkey->rk.dname); 64b7579f77SDag-Erling Smørgrav pkey->rk.dname = NULL; 65b7579f77SDag-Erling Smørgrav pkey->id = 0; 66b7579f77SDag-Erling Smørgrav alloc_special_release(alloc, pkey); 67b7579f77SDag-Erling Smørgrav } 68b7579f77SDag-Erling Smørgrav 69b7579f77SDag-Erling Smørgrav size_t 70b7579f77SDag-Erling Smørgrav ub_rrset_sizefunc(void* key, void* data) 71b7579f77SDag-Erling Smørgrav { 72b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)key; 73b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d = (struct packed_rrset_data*)data; 74b7579f77SDag-Erling Smørgrav size_t s = sizeof(struct ub_packed_rrset_key) + k->rk.dname_len; 75b7579f77SDag-Erling Smørgrav s += packed_rrset_sizeof(d) + lock_get_mem(&k->entry.lock); 76b7579f77SDag-Erling Smørgrav return s; 77b7579f77SDag-Erling Smørgrav } 78b7579f77SDag-Erling Smørgrav 79b7579f77SDag-Erling Smørgrav size_t 80b7579f77SDag-Erling Smørgrav packed_rrset_sizeof(struct packed_rrset_data* d) 81b7579f77SDag-Erling Smørgrav { 82b7579f77SDag-Erling Smørgrav size_t s; 83b7579f77SDag-Erling Smørgrav if(d->rrsig_count > 0) { 84b7579f77SDag-Erling Smørgrav s = ((uint8_t*)d->rr_data[d->count+d->rrsig_count-1] - 85b7579f77SDag-Erling Smørgrav (uint8_t*)d) + d->rr_len[d->count+d->rrsig_count-1]; 86b7579f77SDag-Erling Smørgrav } else { 87b7579f77SDag-Erling Smørgrav log_assert(d->count > 0); 88b7579f77SDag-Erling Smørgrav s = ((uint8_t*)d->rr_data[d->count-1] - (uint8_t*)d) + 89b7579f77SDag-Erling Smørgrav d->rr_len[d->count-1]; 90b7579f77SDag-Erling Smørgrav } 91b7579f77SDag-Erling Smørgrav return s; 92b7579f77SDag-Erling Smørgrav } 93b7579f77SDag-Erling Smørgrav 94b7579f77SDag-Erling Smørgrav int 95b7579f77SDag-Erling Smørgrav ub_rrset_compare(void* k1, void* k2) 96b7579f77SDag-Erling Smørgrav { 97b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* key1 = (struct ub_packed_rrset_key*)k1; 98b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* key2 = (struct ub_packed_rrset_key*)k2; 99b7579f77SDag-Erling Smørgrav int c; 100b7579f77SDag-Erling Smørgrav if(key1 == key2) 101b7579f77SDag-Erling Smørgrav return 0; 102b7579f77SDag-Erling Smørgrav if(key1->rk.type != key2->rk.type) { 103b7579f77SDag-Erling Smørgrav if(key1->rk.type < key2->rk.type) 104b7579f77SDag-Erling Smørgrav return -1; 105b7579f77SDag-Erling Smørgrav return 1; 106b7579f77SDag-Erling Smørgrav } 107b7579f77SDag-Erling Smørgrav if(key1->rk.dname_len != key2->rk.dname_len) { 108b7579f77SDag-Erling Smørgrav if(key1->rk.dname_len < key2->rk.dname_len) 109b7579f77SDag-Erling Smørgrav return -1; 110b7579f77SDag-Erling Smørgrav return 1; 111b7579f77SDag-Erling Smørgrav } 112b7579f77SDag-Erling Smørgrav if((c=query_dname_compare(key1->rk.dname, key2->rk.dname)) != 0) 113b7579f77SDag-Erling Smørgrav return c; 114b7579f77SDag-Erling Smørgrav if(key1->rk.rrset_class != key2->rk.rrset_class) { 115b7579f77SDag-Erling Smørgrav if(key1->rk.rrset_class < key2->rk.rrset_class) 116b7579f77SDag-Erling Smørgrav return -1; 117b7579f77SDag-Erling Smørgrav return 1; 118b7579f77SDag-Erling Smørgrav } 119b7579f77SDag-Erling Smørgrav if(key1->rk.flags != key2->rk.flags) { 120b7579f77SDag-Erling Smørgrav if(key1->rk.flags < key2->rk.flags) 121b7579f77SDag-Erling Smørgrav return -1; 122b7579f77SDag-Erling Smørgrav return 1; 123b7579f77SDag-Erling Smørgrav } 124b7579f77SDag-Erling Smørgrav return 0; 125b7579f77SDag-Erling Smørgrav } 126b7579f77SDag-Erling Smørgrav 127b7579f77SDag-Erling Smørgrav void 128b7579f77SDag-Erling Smørgrav ub_rrset_key_delete(void* key, void* userdata) 129b7579f77SDag-Erling Smørgrav { 130b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)key; 131b7579f77SDag-Erling Smørgrav struct alloc_cache* a = (struct alloc_cache*)userdata; 132b7579f77SDag-Erling Smørgrav k->id = 0; 133b7579f77SDag-Erling Smørgrav free(k->rk.dname); 134b7579f77SDag-Erling Smørgrav k->rk.dname = NULL; 135b7579f77SDag-Erling Smørgrav alloc_special_release(a, k); 136b7579f77SDag-Erling Smørgrav } 137b7579f77SDag-Erling Smørgrav 138b7579f77SDag-Erling Smørgrav void 139b7579f77SDag-Erling Smørgrav rrset_data_delete(void* data, void* ATTR_UNUSED(userdata)) 140b7579f77SDag-Erling Smørgrav { 141b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d = (struct packed_rrset_data*)data; 142b7579f77SDag-Erling Smørgrav free(d); 143b7579f77SDag-Erling Smørgrav } 144b7579f77SDag-Erling Smørgrav 145b7579f77SDag-Erling Smørgrav int 146b7579f77SDag-Erling Smørgrav rrsetdata_equal(struct packed_rrset_data* d1, struct packed_rrset_data* d2) 147b7579f77SDag-Erling Smørgrav { 148b7579f77SDag-Erling Smørgrav size_t i; 149b7579f77SDag-Erling Smørgrav size_t total; 150b7579f77SDag-Erling Smørgrav if(d1->count != d2->count || d1->rrsig_count != d2->rrsig_count) 151b7579f77SDag-Erling Smørgrav return 0; 152b7579f77SDag-Erling Smørgrav total = d1->count + d1->rrsig_count; 153b7579f77SDag-Erling Smørgrav for(i=0; i<total; i++) { 154b7579f77SDag-Erling Smørgrav if(d1->rr_len[i] != d2->rr_len[i]) 155b7579f77SDag-Erling Smørgrav return 0; 156b7579f77SDag-Erling Smørgrav if(memcmp(d1->rr_data[i], d2->rr_data[i], d1->rr_len[i]) != 0) 157b7579f77SDag-Erling Smørgrav return 0; 158b7579f77SDag-Erling Smørgrav } 159b7579f77SDag-Erling Smørgrav return 1; 160b7579f77SDag-Erling Smørgrav } 161b7579f77SDag-Erling Smørgrav 1623005e0a3SDag-Erling Smørgrav hashvalue_type 163b7579f77SDag-Erling Smørgrav rrset_key_hash(struct packed_rrset_key* key) 164b7579f77SDag-Erling Smørgrav { 165b7579f77SDag-Erling Smørgrav /* type is hashed in host order */ 166b7579f77SDag-Erling Smørgrav uint16_t t = ntohs(key->type); 167b7579f77SDag-Erling Smørgrav /* Note this MUST be identical to pkt_hash_rrset in msgparse.c */ 168b7579f77SDag-Erling Smørgrav /* this routine does not have a compressed name */ 1693005e0a3SDag-Erling Smørgrav hashvalue_type h = 0xab; 170b7579f77SDag-Erling Smørgrav h = dname_query_hash(key->dname, h); 171b7579f77SDag-Erling Smørgrav h = hashlittle(&t, sizeof(t), h); 172b7579f77SDag-Erling Smørgrav h = hashlittle(&key->rrset_class, sizeof(uint16_t), h); 173b7579f77SDag-Erling Smørgrav h = hashlittle(&key->flags, sizeof(uint32_t), h); 174b7579f77SDag-Erling Smørgrav return h; 175b7579f77SDag-Erling Smørgrav } 176b7579f77SDag-Erling Smørgrav 177b7579f77SDag-Erling Smørgrav void 178b7579f77SDag-Erling Smørgrav packed_rrset_ptr_fixup(struct packed_rrset_data* data) 179b7579f77SDag-Erling Smørgrav { 180b7579f77SDag-Erling Smørgrav size_t i; 181b7579f77SDag-Erling Smørgrav size_t total = data->count + data->rrsig_count; 182b7579f77SDag-Erling Smørgrav uint8_t* nextrdata; 183b7579f77SDag-Erling Smørgrav /* fixup pointers in packed rrset data */ 184b7579f77SDag-Erling Smørgrav data->rr_len = (size_t*)((uint8_t*)data + 185b7579f77SDag-Erling Smørgrav sizeof(struct packed_rrset_data)); 186b7579f77SDag-Erling Smørgrav data->rr_data = (uint8_t**)&(data->rr_len[total]); 18717d15b25SDag-Erling Smørgrav data->rr_ttl = (time_t*)&(data->rr_data[total]); 188b7579f77SDag-Erling Smørgrav nextrdata = (uint8_t*)&(data->rr_ttl[total]); 189b7579f77SDag-Erling Smørgrav for(i=0; i<total; i++) { 190b7579f77SDag-Erling Smørgrav data->rr_data[i] = nextrdata; 191b7579f77SDag-Erling Smørgrav nextrdata += data->rr_len[i]; 192b7579f77SDag-Erling Smørgrav } 193b7579f77SDag-Erling Smørgrav } 194b7579f77SDag-Erling Smørgrav 195b7579f77SDag-Erling Smørgrav void 196b7579f77SDag-Erling Smørgrav get_cname_target(struct ub_packed_rrset_key* rrset, uint8_t** dname, 197b7579f77SDag-Erling Smørgrav size_t* dname_len) 198b7579f77SDag-Erling Smørgrav { 199b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d; 200b7579f77SDag-Erling Smørgrav size_t len; 201b7579f77SDag-Erling Smørgrav if(ntohs(rrset->rk.type) != LDNS_RR_TYPE_CNAME && 202b7579f77SDag-Erling Smørgrav ntohs(rrset->rk.type) != LDNS_RR_TYPE_DNAME) 203b7579f77SDag-Erling Smørgrav return; 204b7579f77SDag-Erling Smørgrav d = (struct packed_rrset_data*)rrset->entry.data; 205b7579f77SDag-Erling Smørgrav if(d->count < 1) 206b7579f77SDag-Erling Smørgrav return; 207b7579f77SDag-Erling Smørgrav if(d->rr_len[0] < 3) /* at least rdatalen + 0byte root label */ 208b7579f77SDag-Erling Smørgrav return; 20917d15b25SDag-Erling Smørgrav len = sldns_read_uint16(d->rr_data[0]); 210b7579f77SDag-Erling Smørgrav if(len != d->rr_len[0] - sizeof(uint16_t)) 211b7579f77SDag-Erling Smørgrav return; 212b7579f77SDag-Erling Smørgrav if(dname_valid(d->rr_data[0]+sizeof(uint16_t), len) != len) 213b7579f77SDag-Erling Smørgrav return; 214b7579f77SDag-Erling Smørgrav *dname = d->rr_data[0]+sizeof(uint16_t); 215b7579f77SDag-Erling Smørgrav *dname_len = len; 216b7579f77SDag-Erling Smørgrav } 217b7579f77SDag-Erling Smørgrav 218b7579f77SDag-Erling Smørgrav void 21917d15b25SDag-Erling Smørgrav packed_rrset_ttl_add(struct packed_rrset_data* data, time_t add) 220b7579f77SDag-Erling Smørgrav { 221b7579f77SDag-Erling Smørgrav size_t i; 222b7579f77SDag-Erling Smørgrav size_t total = data->count + data->rrsig_count; 223*f44e67d1SCy Schubert data->ttl_add = add; 224b7579f77SDag-Erling Smørgrav data->ttl += add; 225b7579f77SDag-Erling Smørgrav for(i=0; i<total; i++) 226b7579f77SDag-Erling Smørgrav data->rr_ttl[i] += add; 227b7579f77SDag-Erling Smørgrav } 228b7579f77SDag-Erling Smørgrav 229b7579f77SDag-Erling Smørgrav const char* 230b7579f77SDag-Erling Smørgrav rrset_trust_to_string(enum rrset_trust s) 231b7579f77SDag-Erling Smørgrav { 232b7579f77SDag-Erling Smørgrav switch(s) { 233b7579f77SDag-Erling Smørgrav case rrset_trust_none: return "rrset_trust_none"; 234b7579f77SDag-Erling Smørgrav case rrset_trust_add_noAA: return "rrset_trust_add_noAA"; 235b7579f77SDag-Erling Smørgrav case rrset_trust_auth_noAA: return "rrset_trust_auth_noAA"; 236b7579f77SDag-Erling Smørgrav case rrset_trust_add_AA: return "rrset_trust_add_AA"; 237b7579f77SDag-Erling Smørgrav case rrset_trust_nonauth_ans_AA:return "rrset_trust_nonauth_ans_AA"; 238b7579f77SDag-Erling Smørgrav case rrset_trust_ans_noAA: return "rrset_trust_ans_noAA"; 239b7579f77SDag-Erling Smørgrav case rrset_trust_glue: return "rrset_trust_glue"; 240b7579f77SDag-Erling Smørgrav case rrset_trust_auth_AA: return "rrset_trust_auth_AA"; 241b7579f77SDag-Erling Smørgrav case rrset_trust_ans_AA: return "rrset_trust_ans_AA"; 242b7579f77SDag-Erling Smørgrav case rrset_trust_sec_noglue: return "rrset_trust_sec_noglue"; 243b7579f77SDag-Erling Smørgrav case rrset_trust_prim_noglue: return "rrset_trust_prim_noglue"; 244b7579f77SDag-Erling Smørgrav case rrset_trust_validated: return "rrset_trust_validated"; 245b7579f77SDag-Erling Smørgrav case rrset_trust_ultimate: return "rrset_trust_ultimate"; 246b7579f77SDag-Erling Smørgrav } 247b7579f77SDag-Erling Smørgrav return "unknown_rrset_trust_value"; 248b7579f77SDag-Erling Smørgrav } 249b7579f77SDag-Erling Smørgrav 250b7579f77SDag-Erling Smørgrav const char* 251b7579f77SDag-Erling Smørgrav sec_status_to_string(enum sec_status s) 252b7579f77SDag-Erling Smørgrav { 253b7579f77SDag-Erling Smørgrav switch(s) { 254b7579f77SDag-Erling Smørgrav case sec_status_unchecked: return "sec_status_unchecked"; 255b7579f77SDag-Erling Smørgrav case sec_status_bogus: return "sec_status_bogus"; 256b7579f77SDag-Erling Smørgrav case sec_status_indeterminate: return "sec_status_indeterminate"; 257b7579f77SDag-Erling Smørgrav case sec_status_insecure: return "sec_status_insecure"; 2580fb34990SDag-Erling Smørgrav case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail"; 259b7579f77SDag-Erling Smørgrav case sec_status_secure: return "sec_status_secure"; 260b7579f77SDag-Erling Smørgrav } 261b7579f77SDag-Erling Smørgrav return "unknown_sec_status_value"; 262b7579f77SDag-Erling Smørgrav } 263b7579f77SDag-Erling Smørgrav 264b7579f77SDag-Erling Smørgrav void log_rrset_key(enum verbosity_value v, const char* str, 265b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset) 266b7579f77SDag-Erling Smørgrav { 267b7579f77SDag-Erling Smørgrav if(verbosity >= v) 268b7579f77SDag-Erling Smørgrav log_nametypeclass(v, str, rrset->rk.dname, 269b7579f77SDag-Erling Smørgrav ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); 270b7579f77SDag-Erling Smørgrav } 271b7579f77SDag-Erling Smørgrav 27217d15b25SDag-Erling Smørgrav int packed_rr_to_string(struct ub_packed_rrset_key* rrset, size_t i, 27317d15b25SDag-Erling Smørgrav time_t now, char* dest, size_t dest_len) 27417d15b25SDag-Erling Smørgrav { 27517d15b25SDag-Erling Smørgrav struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> 27617d15b25SDag-Erling Smørgrav entry.data; 27717d15b25SDag-Erling Smørgrav uint8_t rr[65535]; 27817d15b25SDag-Erling Smørgrav size_t rlen = rrset->rk.dname_len + 2 + 2 + 4 + d->rr_len[i]; 279*f44e67d1SCy Schubert time_t adjust = 0; 28017d15b25SDag-Erling Smørgrav log_assert(dest_len > 0 && dest); 28117d15b25SDag-Erling Smørgrav if(rlen > dest_len) { 28217d15b25SDag-Erling Smørgrav dest[0] = 0; 28317d15b25SDag-Erling Smørgrav return 0; 28417d15b25SDag-Erling Smørgrav } 28517d15b25SDag-Erling Smørgrav memmove(rr, rrset->rk.dname, rrset->rk.dname_len); 28617d15b25SDag-Erling Smørgrav if(i < d->count) 28717d15b25SDag-Erling Smørgrav memmove(rr+rrset->rk.dname_len, &rrset->rk.type, 2); 28817d15b25SDag-Erling Smørgrav else sldns_write_uint16(rr+rrset->rk.dname_len, LDNS_RR_TYPE_RRSIG); 28917d15b25SDag-Erling Smørgrav memmove(rr+rrset->rk.dname_len+2, &rrset->rk.rrset_class, 2); 290*f44e67d1SCy Schubert adjust = SERVE_ORIGINAL_TTL ? d->ttl_add : now; 291*f44e67d1SCy Schubert if (d->rr_ttl[i] < adjust) adjust = d->rr_ttl[i]; /* Prevent negative TTL overflow */ 29217d15b25SDag-Erling Smørgrav sldns_write_uint32(rr+rrset->rk.dname_len+4, 293*f44e67d1SCy Schubert (uint32_t)(d->rr_ttl[i]-adjust)); 29417d15b25SDag-Erling Smørgrav memmove(rr+rrset->rk.dname_len+8, d->rr_data[i], d->rr_len[i]); 29517d15b25SDag-Erling Smørgrav if(sldns_wire2str_rr_buf(rr, rlen, dest, dest_len) == -1) { 29617d15b25SDag-Erling Smørgrav log_info("rrbuf failure %d %s", (int)d->rr_len[i], dest); 29717d15b25SDag-Erling Smørgrav dest[0] = 0; 29817d15b25SDag-Erling Smørgrav return 0; 29917d15b25SDag-Erling Smørgrav } 30017d15b25SDag-Erling Smørgrav return 1; 30117d15b25SDag-Erling Smørgrav } 30217d15b25SDag-Erling Smørgrav 30317d15b25SDag-Erling Smørgrav void log_packed_rrset(enum verbosity_value v, const char* str, 30417d15b25SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset) 30517d15b25SDag-Erling Smørgrav { 30617d15b25SDag-Erling Smørgrav struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> 30717d15b25SDag-Erling Smørgrav entry.data; 30817d15b25SDag-Erling Smørgrav char buf[65535]; 30917d15b25SDag-Erling Smørgrav size_t i; 31017d15b25SDag-Erling Smørgrav if(verbosity < v) 31117d15b25SDag-Erling Smørgrav return; 31217d15b25SDag-Erling Smørgrav for(i=0; i<d->count+d->rrsig_count; i++) { 31317d15b25SDag-Erling Smørgrav if(!packed_rr_to_string(rrset, i, 0, buf, sizeof(buf))) { 31417d15b25SDag-Erling Smørgrav log_info("%s: rr %d wire2str-error", str, (int)i); 31517d15b25SDag-Erling Smørgrav } else { 31617d15b25SDag-Erling Smørgrav log_info("%s: %s", str, buf); 31717d15b25SDag-Erling Smørgrav } 31817d15b25SDag-Erling Smørgrav } 31917d15b25SDag-Erling Smørgrav } 32017d15b25SDag-Erling Smørgrav 32117d15b25SDag-Erling Smørgrav time_t 322b7579f77SDag-Erling Smørgrav ub_packed_rrset_ttl(struct ub_packed_rrset_key* key) 323b7579f77SDag-Erling Smørgrav { 324b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d = (struct packed_rrset_data*)key-> 325b7579f77SDag-Erling Smørgrav entry.data; 326b7579f77SDag-Erling Smørgrav return d->ttl; 327b7579f77SDag-Erling Smørgrav } 328b7579f77SDag-Erling Smørgrav 329b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* 330b7579f77SDag-Erling Smørgrav packed_rrset_copy_region(struct ub_packed_rrset_key* key, 33117d15b25SDag-Erling Smørgrav struct regional* region, time_t now) 332b7579f77SDag-Erling Smørgrav { 333b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* ck = regional_alloc(region, 334b7579f77SDag-Erling Smørgrav sizeof(struct ub_packed_rrset_key)); 335b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d; 336b7579f77SDag-Erling Smørgrav struct packed_rrset_data* data = (struct packed_rrset_data*) 337b7579f77SDag-Erling Smørgrav key->entry.data; 338b7579f77SDag-Erling Smørgrav size_t dsize, i; 339*f44e67d1SCy Schubert time_t adjust = 0; 340b7579f77SDag-Erling Smørgrav if(!ck) 341b7579f77SDag-Erling Smørgrav return NULL; 342b7579f77SDag-Erling Smørgrav ck->id = key->id; 343b7579f77SDag-Erling Smørgrav memset(&ck->entry, 0, sizeof(ck->entry)); 344b7579f77SDag-Erling Smørgrav ck->entry.hash = key->entry.hash; 345b7579f77SDag-Erling Smørgrav ck->entry.key = ck; 346b7579f77SDag-Erling Smørgrav ck->rk = key->rk; 347b7579f77SDag-Erling Smørgrav ck->rk.dname = regional_alloc_init(region, key->rk.dname, 348b7579f77SDag-Erling Smørgrav key->rk.dname_len); 349b7579f77SDag-Erling Smørgrav if(!ck->rk.dname) 350b7579f77SDag-Erling Smørgrav return NULL; 351b7579f77SDag-Erling Smørgrav dsize = packed_rrset_sizeof(data); 352b7579f77SDag-Erling Smørgrav d = (struct packed_rrset_data*)regional_alloc_init(region, data, dsize); 353b7579f77SDag-Erling Smørgrav if(!d) 354b7579f77SDag-Erling Smørgrav return NULL; 355b7579f77SDag-Erling Smørgrav ck->entry.data = d; 356b7579f77SDag-Erling Smørgrav packed_rrset_ptr_fixup(d); 357b7579f77SDag-Erling Smørgrav /* make TTLs relative - once per rrset */ 358*f44e67d1SCy Schubert adjust = SERVE_ORIGINAL_TTL ? data->ttl_add : now; 359b7579f77SDag-Erling Smørgrav for(i=0; i<d->count + d->rrsig_count; i++) { 360*f44e67d1SCy Schubert if(d->rr_ttl[i] < adjust) 361091e9e46SCy Schubert d->rr_ttl[i] = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0; 362*f44e67d1SCy Schubert else d->rr_ttl[i] -= adjust; 363b7579f77SDag-Erling Smørgrav } 364*f44e67d1SCy Schubert if(d->ttl < adjust) 365091e9e46SCy Schubert d->ttl = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0; 366*f44e67d1SCy Schubert else d->ttl -= adjust; 367*f44e67d1SCy Schubert d->ttl_add = 0; /* TTLs have been made relative */ 368b7579f77SDag-Erling Smørgrav return ck; 369b7579f77SDag-Erling Smørgrav } 370b7579f77SDag-Erling Smørgrav 371b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* 372b7579f77SDag-Erling Smørgrav packed_rrset_copy_alloc(struct ub_packed_rrset_key* key, 37317d15b25SDag-Erling Smørgrav struct alloc_cache* alloc, time_t now) 374b7579f77SDag-Erling Smørgrav { 375b7579f77SDag-Erling Smørgrav struct packed_rrset_data* fd, *dd; 376b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* dk = alloc_special_obtain(alloc); 377b7579f77SDag-Erling Smørgrav if(!dk) return NULL; 378b7579f77SDag-Erling Smørgrav fd = (struct packed_rrset_data*)key->entry.data; 379b7579f77SDag-Erling Smørgrav dk->entry.hash = key->entry.hash; 380b7579f77SDag-Erling Smørgrav dk->rk = key->rk; 381b7579f77SDag-Erling Smørgrav dk->rk.dname = (uint8_t*)memdup(key->rk.dname, key->rk.dname_len); 382b7579f77SDag-Erling Smørgrav if(!dk->rk.dname) { 383b7579f77SDag-Erling Smørgrav alloc_special_release(alloc, dk); 384b7579f77SDag-Erling Smørgrav return NULL; 385b7579f77SDag-Erling Smørgrav } 386b7579f77SDag-Erling Smørgrav dd = (struct packed_rrset_data*)memdup(fd, packed_rrset_sizeof(fd)); 387b7579f77SDag-Erling Smørgrav if(!dd) { 388b7579f77SDag-Erling Smørgrav free(dk->rk.dname); 389b7579f77SDag-Erling Smørgrav alloc_special_release(alloc, dk); 390b7579f77SDag-Erling Smørgrav return NULL; 391b7579f77SDag-Erling Smørgrav } 392b7579f77SDag-Erling Smørgrav packed_rrset_ptr_fixup(dd); 393b7579f77SDag-Erling Smørgrav dk->entry.data = (void*)dd; 394b7579f77SDag-Erling Smørgrav packed_rrset_ttl_add(dd, now); 395b7579f77SDag-Erling Smørgrav return dk; 396b7579f77SDag-Erling Smørgrav } 397091e9e46SCy Schubert 398091e9e46SCy Schubert int 399091e9e46SCy Schubert packed_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len, 400091e9e46SCy Schubert size_t* index) 401091e9e46SCy Schubert { 402091e9e46SCy Schubert size_t i; 403091e9e46SCy Schubert for(i=0; i<d->count; i++) { 404091e9e46SCy Schubert if(d->rr_len[i] != len) 405091e9e46SCy Schubert continue; 406091e9e46SCy Schubert if(memcmp(d->rr_data[i], rdata, len) == 0) { 407091e9e46SCy Schubert *index = i; 408091e9e46SCy Schubert return 1; 409091e9e46SCy Schubert } 410091e9e46SCy Schubert } 411091e9e46SCy Schubert return 0; 412091e9e46SCy Schubert } 413