Merge branch 'amialkow-develop4' into release/v1.7.0

This commit is contained in:
Willem Toorop 2021-05-27 22:08:05 +02:00
commit 2b348b046d
4 changed files with 94 additions and 36 deletions

View File

@ -823,6 +823,7 @@ _getdns_reply_dict2wire(
getdns_list *section;
getdns_dict *rr_dict;
getdns_bindata *qname;
name_cache_t name_cache = {0};
int remove_dnssec;
pkt_start = gldns_buffer_position(buf);
@ -852,7 +853,7 @@ _getdns_reply_dict2wire(
if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) &&
!getdns_dict_get_int(reply, "/question/qtype", &qtype)) {
(void)getdns_dict_get_int(reply, "/question/qclass", &qclass);
gldns_buffer_write(buf, qname->data, qname->size);
_getdns_rr_buffer_write_cached_name(buf, qname, &name_cache);
gldns_buffer_write_u16(buf, (uint16_t)qtype);
gldns_buffer_write_u16(buf, (uint16_t)qclass);
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
@ -875,7 +876,7 @@ _getdns_reply_dict2wire(
!getdns_dict_get_int(rr_dict, "type", &rr_type) &&
rr_type == GETDNS_RRTYPE_RRSIG)
continue;
if (!_getdns_rr_dict2wire(rr_dict, buf))
if (!_getdns_rr_dict2wire_cache(rr_dict, buf, &name_cache))
n++;
}
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, n);

View File

@ -1293,8 +1293,39 @@ write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start,
return r != GETDNS_RETURN_NO_SUCH_LIST_ITEM ? r : GETDNS_RETURN_GOOD;
}
void
_getdns_rr_buffer_write_cached_name(gldns_buffer *buf, getdns_bindata *name, name_cache_t *name_cache)
{
size_t name_size = name->size;
uint8_t *name_data = name->data;
if((NULL != name_cache) && (name_size > 2)) {
unsigned count = name_cache->count;
name_cache_entry_t *entry_ptr = &name_cache->entry[(count < NAME_CACHE_ENTRIES)?count:NAME_CACHE_ENTRIES];
name_cache_entry_t *table_start = &name_cache->entry[0];
/* Search backward if name is already in cache */
while(entry_ptr-- > table_start) {
if((entry_ptr->name->size == name_size) &&
!memcmp(entry_ptr->name->data, name_data, name_size)) {
gldns_buffer_write_u16(buf, (uint16_t)(0xc000 | entry_ptr->name_offset));
return;
}
}
unsigned name_offset = gldns_buffer_position(buf);
if (name_offset < 0xc000) {
/* Cache name */
entry_ptr = &name_cache->entry[count % NAME_CACHE_ENTRIES];
entry_ptr->name = name;
entry_ptr->name_offset = name_offset;
name_cache->count = count + 1;
}
}
gldns_buffer_write(buf, name_data, name_size);
return;
}
getdns_return_t
_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
_getdns_rr_dict2wire_cache(const getdns_dict *rr_dict, gldns_buffer *buf,
name_cache_t *name_cache)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
getdns_bindata root = { 1, (void *)"" };
@ -1325,7 +1356,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
} else
return r;
}
gldns_buffer_write(buf, name->data, name->size);
_getdns_rr_buffer_write_cached_name(buf, name, name_cache);
gldns_buffer_write_u16(buf, (uint16_t)rr_type);
(void) getdns_dict_get_int(rr_dict, "class", &rr_class);
@ -1378,6 +1409,14 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
gldns_buffer_skip(buf, 2);
rdata_start = gldns_buffer_current(buf);
/* Special case CNAME payload */
if((rr_type == GETDNS_RRTYPE_CNAME) && (n_rdata_fields == 1) &&
(rd_def->type & GETDNS_RDF_BINDATA) && !(rd_def->type & GETDNS_RDF_REPEAT) &&
(GETDNS_RETURN_GOOD == (r = getdns_dict_get_bindata(rdata, rd_def->name, &rdata_raw)))) {
_getdns_rr_buffer_write_cached_name(buf, rdata_raw, name_cache);
} else {
for ( rd_def = rr_def->rdata
, n_rdata_fields = rr_def->n_rdata_fields
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
@ -1415,6 +1454,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
break;
}
}
}
gldns_buffer_write_u16_at(buf, rdata_size_mark,
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2));
}

View File

@ -143,8 +143,25 @@ typedef struct _getdns_rr_def {
const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type);
getdns_return_t _getdns_rr_dict2wire(
const getdns_dict *rr_dict, gldns_buffer *buf);
#define NAME_CACHE_ENTRIES 4
typedef struct __name_cache_entry {
getdns_bindata *name;
unsigned name_offset;
} name_cache_entry_t;
typedef struct __name_cache {
unsigned count;
name_cache_entry_t entry[NAME_CACHE_ENTRIES];
} name_cache_t;
void _getdns_rr_buffer_write_cached_name(
gldns_buffer *buf, getdns_bindata *name, name_cache_t *name_cache);
getdns_return_t _getdns_rr_dict2wire_cache(
const getdns_dict *rr_dict, gldns_buffer *buf, name_cache_t *name_cache);
#define _getdns_rr_dict2wire(d, b) _getdns_rr_dict2wire_cache((d),(b), NULL)
const char *_getdns_rr_type_name(int rr_type);

View File

@ -11,5 +11,5 @@ elif ! ( "./${TPKG_NAME}" "${TPKG_NAME}.net-dns.org" | tee out )
then
exit 1
else
diff out "${TPKG_NAME}.good"
diff out "${TPKG_NAME}.good" --ignore-matching-lines=";; MSG SIZE rcvd: "
fi