From 16799b52b197d7b2b9f45aa5c6681cb889912ef5 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 24 Jan 2025 14:28:12 +0100 Subject: [PATCH] - direct-rdata-storage, implement in xfrd-catalog-zones.c. --- rdata.c | 115 +++++++++++++++++++++++++++++++++++++++++++ rdata.h | 42 ++++++++++++++++ xfrd-catalog-zones.c | 31 ++++++------ 3 files changed, 172 insertions(+), 16 deletions(-) diff --git a/rdata.c b/rdata.c index 9d500cb8..439ae418 100644 --- a/rdata.c +++ b/rdata.c @@ -3800,3 +3800,118 @@ equal_rr_rdata(const nsd_type_descriptor_type *descriptor, } return 0; } + +/* + * Retrieve domain ref at an offset in the rdata. + * @param rr: the RR to retrieve it for. + * @param offset: where in the rdata the reference pointer is. + * @return domain ptr. + */ +static struct domain* +retrieve_rdata_ref_domain_offset(const struct rr* rr, uint16_t offset) +{ + struct domain *domain; + if(rr->rdlength < offset+sizeof(void*)) + return NULL; + memcpy(&domain, rr->rdata+offset, sizeof(void*)); + return domain; +} + +/* + * Retrieve domain ref from rdata. No offset, rdata starts with ref. + * @param rr: the RR to retrieve it for. + * @return domain ptr. + */ +static struct domain* +retrieve_rdata_ref_domain(const struct rr* rr) +{ + struct domain *domain; + if(rr->rdlength < sizeof(void*)) + return NULL; + memcpy(&domain, rr->rdata, sizeof(void*)); + return domain; +} + +struct domain* +retrieve_ns_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_NS); + return retrieve_rdata_ref_domain(rr); +} + +struct domain* +retrieve_cname_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_CNAME); + return retrieve_rdata_ref_domain(rr); +} + +struct domain* +retrieve_dname_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_DNAME); + return retrieve_rdata_ref_domain(rr); +} + +struct domain* +retrieve_mb_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_MB); + return retrieve_rdata_ref_domain(rr); +} + +struct domain* +retrieve_mx_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_MX); + return retrieve_rdata_ref_domain_offset(rr, 2); +} + +struct domain* +retrieve_kx_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_KX); + return retrieve_rdata_ref_domain_offset(rr, 2); +} + +struct domain* +retrieve_rt_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_RT); + return retrieve_rdata_ref_domain_offset(rr, 2); +} + +struct domain* +retrieve_srv_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_SRV); + return retrieve_rdata_ref_domain_offset(rr, 6); +} + +struct domain* +retrieve_ptr_ref_domain(const struct rr* rr) +{ + assert(rr->type == TYPE_PTR); + return retrieve_rdata_ref_domain(rr); +} + +int +retrieve_soa_rdata_serial(const struct rr* rr, uint32_t* serial) +{ + assert(rr->type == TYPE_SOA); + if(rr->rdlength < 20 + 2*sizeof(void*)) + return 0; + /* primary mailbox serial[4] refresh[4] retry[4] expire[4] minimum[4] */ + *serial = read_uint32(rr->rdata+2*sizeof(void*)); + return 1; +} + +int +retrieve_soa_rdata_minttl(const struct rr* rr, uint32_t* minttl) +{ + assert(rr->type == TYPE_SOA); + if(rr->rdlength < 20 + 2*sizeof(void*)) + return 0; + *minttl = read_uint32(rr->rdata+2*sizeof(void*)+16); + return 1; +} diff --git a/rdata.h b/rdata.h index e87d7415..825a5b28 100644 --- a/rdata.h +++ b/rdata.h @@ -558,4 +558,46 @@ int compare_rr_rdata(const nsd_type_descriptor_type *descriptor, int equal_rr_rdata(const nsd_type_descriptor_type *descriptor, const struct rr *rr1, const struct rr *rr2); +/* + * Accessor function to the domain in the rdata of the type. + * The RR must be of the type. The type must have references. + * @param rr: the rr with rdata + * @return domain pointer. + */ +typedef struct domain*(*nsd_rdata_ref_domain)( + const struct rr* rr); + +/* Access the domain reference for type NS */ +struct domain* retrieve_ns_ref_domain(const struct rr* rr); + +/* Access the domain reference for type CNAME */ +struct domain* retrieve_cname_ref_domain(const struct rr* rr); + +/* Access the domain reference for type DNAME */ +struct domain* retrieve_dname_ref_domain(const struct rr* rr); + +/* Access the domain reference for type MB */ +struct domain* retrieve_mb_ref_domain(const struct rr* rr); + +/* Access the domain reference for type MX */ +struct domain* retrieve_mx_ref_domain(const struct rr* rr); + +/* Access the domain reference for type KX */ +struct domain* retrieve_kx_ref_domain(const struct rr* rr); + +/* Access the domain reference for type RT */ +struct domain* retrieve_rt_ref_domain(const struct rr* rr); + +/* Access the domain reference for type SRV */ +struct domain* retrieve_srv_ref_domain(const struct rr* rr); + +/* Access the domain reference for type PTR */ +struct domain* retrieve_ptr_ref_domain(const struct rr* rr); + +/* Access the serial number for type SOA, false if malformed. */ +int retrieve_soa_rdata_serial(const struct rr* rr, uint32_t* serial); + +/* Access the minimum ttl for type SOA, false if malformed. */ +int retrieve_soa_rdata_minttl(const struct rr* rr, uint32_t* minttl); + #endif /* RDATA_H */ diff --git a/xfrd-catalog-zones.c b/xfrd-catalog-zones.c index 7aee82fc..1061eb5e 100644 --- a/xfrd-catalog-zones.c +++ b/xfrd-catalog-zones.c @@ -9,6 +9,7 @@ #include "difffile.h" #include "nsd.h" #include "packet.h" +#include "rdata.h" #include "xfrd-catalog-zones.h" #include "xfrd-notify.h" @@ -545,11 +546,11 @@ xfrd_process_catalog_consumer_zone( } version_2_found = 0; for (i = 0; i < rrset->rr_count; i++) { - if (rrset->rrs[i].rdata_count != 1) - continue; - if (rrset->rrs[i].rdatas[0].data[0] == 2 - && ((uint8_t*)(rrset->rrs[i].rdatas[0].data + 1))[0] == 1 - && ((uint8_t*)(rrset->rrs[i].rdatas[0].data + 1))[1] == '2') { + if(rrset->rrs[i]->rdlength > 1 && + rrset->rrs[i]->rdata[0] == 1 && + rrset->rrs[i]->rdlength == + ((uint16_t)rrset->rrs[i]->rdata[0]) + 1 && + rrset->rrs[i]->rdata[1] == '2') { version_2_found = 1; break; } @@ -602,9 +603,9 @@ xfrd_process_catalog_consumer_zone( return; } /* A PTR rr always has 1 rdata element which is a dname */ - if (rrset->rrs[0].rdata_count != 1) + member_domain = retrieve_ptr_ref_domain(rrset->rrs[0]); + if(!member_domain) continue; - member_domain = rrset->rrs[0].rdatas[0].domain; domain_to_string_buf(member_domain, member_domain_str); /* remove trailing dot */ member_domain_str[strlen(member_domain_str) - 1] = 0; @@ -622,22 +623,20 @@ xfrd_process_catalog_consumer_zone( char group_value[256]; /* Looking for a single TXT rdata field */ - if (rrset->rrs[i].rdata_count != 1 + if(rrset->rrs[i]->rdlength < 1 + || rrset->rrs[i]->rdlength != + ((uint16_t)rrset->rrs[i]->rdata[0])+1 /* rdata field should be at least 1 char */ - || rrset->rrs[i].rdatas[0].data[0] < 2 - - /* single rdata atom with single TXT rdata field */ - || (uint16_t)(((uint8_t*)(rrset->rrs[i].rdatas[0].data + 1))[0]) - != (uint16_t) (rrset->rrs[i].rdatas[0].data[0]-1)) + || rrset->rrs[i]->rdata[0] < 1) continue; memcpy( group_value - , (uint8_t*)(rrset->rrs[i].rdatas[0].data+1) + 1 - ,((uint8_t*)(rrset->rrs[i].rdatas[0].data+1))[0] + , rrset->rrs[i]->rdata+1 + , rrset->rrs[i]->rdata[0] ); group_value[ - ((uint8_t*)(rrset->rrs[i].rdatas[0].data+1))[0] + rrset->rrs[i]->rdata[0] ] = 0; if ((pattern = pattern_options_find( xfrd->nsd->options, group_value)))