Skip to content

Commit

Permalink
- direct-rdata-storage, implement in xfrd-catalog-zones.c.
Browse files Browse the repository at this point in the history
  • Loading branch information
wcawijngaards committed Jan 24, 2025
1 parent 1809ba8 commit 16799b5
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 16 deletions.
115 changes: 115 additions & 0 deletions rdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
42 changes: 42 additions & 0 deletions rdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
31 changes: 15 additions & 16 deletions xfrd-catalog-zones.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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)))
Expand Down

0 comments on commit 16799b5

Please sign in to comment.