Skip to content

Commit

Permalink
- direct-rdata-storage, implement dname_make_from_packet_buffered, an…
Browse files Browse the repository at this point in the history
…d in

  rdata.c.
  • Loading branch information
wcawijngaards committed Jan 22, 2025
1 parent 1d92910 commit cf9562b
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 133 deletions.
74 changes: 74 additions & 0 deletions dname.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,3 +642,77 @@ buf_dname_length(const uint8_t* buf, size_t len)
l += 1; /* for the end root label */
return l;
}

int
dname_make_buffered(struct dname_buffer* dname, uint8_t *name, int normalize)
{
size_t name_size = 0;
uint8_t label_offsets[MAXDOMAINLEN];
uint8_t label_count = 0;
const uint8_t *label = name;
ssize_t i;

assert(name);

while (1) {
if (label_is_pointer(label))
return 0;

label_offsets[label_count] = (uint8_t) (label - name);
++label_count;
name_size += label_length(label) + 1;

if (label_is_root(label))
break;

label = label_next(label);
}

if (name_size > MAXDOMAINLEN)
return 0;

assert(label_count <= MAXDOMAINLEN / 2 + 1);

/* Reverse label offsets. */
for (i = 0; i < label_count / 2; ++i) {
uint8_t tmp = label_offsets[i];
label_offsets[i] = label_offsets[label_count - i - 1];
label_offsets[label_count - i - 1] = tmp;
}

/* Move the name to the correct part of the result */
memmove( ((char*)dname)+sizeof(struct dname)+
label_count*sizeof(uint8_t), name, name_size);
dname->dname.name_size = name_size;
dname->dname.label_count = label_count;
memcpy((uint8_t *) dname_label_offsets((void*)dname),
label_offsets, label_count * sizeof(uint8_t));
if (normalize) {
uint8_t *src = (uint8_t *) dname_name((void*)dname);
while (!label_is_root(src)) {
ssize_t len = label_length(src);
src++;
for (i = 0; i < len; ++i) {
*src = DNAME_NORMALIZE((unsigned char)*src);
src++;
}
}
}
return 1;
}

int
dname_make_from_packet_buffered(struct dname_buffer* dname,
buffer_type *packet, int allow_pointers, int normalize)
{
int wirelen = dname_make_wire_from_packet(dname->storage,
packet, allow_pointers);
if(wirelen == 0)
return 0;
if(!dname_make_buffered(dname, dname->storage, normalize))
return 0;
/* This could be an assertion. */
if(wirelen != dname->dname.name_size)
return 0;
return wirelen;
}
36 changes: 36 additions & 0 deletions dname.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,4 +406,40 @@ int is_dname_subdomain_of_case(const uint8_t* d, unsigned int len,
/* calculate length of dname in uncompressed wireformat in buffer */
size_t buf_dname_length(const uint8_t* buf, size_t len);

/* This structure is sufficient in size for a struct dname. It can
* be cast to a struct dname*, since it has the same data. */
struct dname_buffer {
struct dname dname;
/* storage for labelcount, and for the wireformat name.
* The labelcount can be 1 byte per label, maxlen/2 + 1(root label).
* The wireformat name, MAXDOMAINLEN+1.
* This allocates storage for it, due to alignment, the struct
* dname may have padding. The content is stored after the
* sizeof(struct dname), with label_offsets and name. */
uint8_t storage[MAXDOMAINLEN/2 + 1 + MAXDOMAINLEN+1 ];
};

/*
* Make the dname and label offsets.
* @param dname: the buffer with size. The result is in here, at the
* start of the allocated size. The input is also buffered temporarily
* in here.
* @param name: input name, points into the buffer space of dname.
* @param normalize: if the dname has to be normalized.
* @return 0 on failure.
*/
int dname_make_buffered(struct dname_buffer* dname, uint8_t *name,
int normalize);

/*
* Parse a domain name from packet and store it in the buffer.
* @param dname: the buffer with sufficient size for the dname.
* @param packet: packet, at the position of the dname. The position is moved.
* @param allow_pointers: set to true if compression pointers are allowed.
* @param normalize: set to true if the domain name has to be normalized.
* @return 0 on failure, or name_length when done.
*/
int dname_make_from_packet_buffered(struct dname_buffer* dname,
buffer_type *packet, int allow_pointers, int normalize);

#endif /* DNAME_H */
Loading

0 comments on commit cf9562b

Please sign in to comment.