Merge branch 'develop4' of https://github.com/amialkow/getdns into amialkow-develop4

This commit is contained in:
Willem Toorop 2021-05-27 21:56:38 +02:00
commit 50463c7480
4 changed files with 94 additions and 36 deletions

View File

@ -823,6 +823,7 @@ _getdns_reply_dict2wire(
getdns_list *section; getdns_list *section;
getdns_dict *rr_dict; getdns_dict *rr_dict;
getdns_bindata *qname; getdns_bindata *qname;
name_cache_t name_cache = {0};
int remove_dnssec; int remove_dnssec;
pkt_start = gldns_buffer_position(buf); pkt_start = gldns_buffer_position(buf);
@ -852,7 +853,7 @@ _getdns_reply_dict2wire(
if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) && if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) &&
!getdns_dict_get_int(reply, "/question/qtype", &qtype)) { !getdns_dict_get_int(reply, "/question/qtype", &qtype)) {
(void)getdns_dict_get_int(reply, "/question/qclass", &qclass); (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)qtype);
gldns_buffer_write_u16(buf, (uint16_t)qclass); gldns_buffer_write_u16(buf, (uint16_t)qclass);
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1); 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) && !getdns_dict_get_int(rr_dict, "type", &rr_type) &&
rr_type == GETDNS_RRTYPE_RRSIG) rr_type == GETDNS_RRTYPE_RRSIG)
continue; continue;
if (!_getdns_rr_dict2wire(rr_dict, buf)) if (!_getdns_rr_dict2wire_cache(rr_dict, buf, &name_cache))
n++; n++;
} }
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, 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; 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_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_return_t r = GETDNS_RETURN_GOOD;
getdns_bindata root = { 1, (void *)"" }; getdns_bindata root = { 1, (void *)"" };
@ -1325,7 +1356,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
} else } else
return r; 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); gldns_buffer_write_u16(buf, (uint16_t)rr_type);
(void) getdns_dict_get_int(rr_dict, "class", &rr_class); (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); gldns_buffer_skip(buf, 2);
rdata_start = gldns_buffer_current(buf); 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 for ( rd_def = rr_def->rdata
, n_rdata_fields = rr_def->n_rdata_fields , n_rdata_fields = rr_def->n_rdata_fields
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) { ; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
@ -1415,6 +1454,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
break; break;
} }
} }
}
gldns_buffer_write_u16_at(buf, rdata_size_mark, gldns_buffer_write_u16_at(buf, rdata_size_mark,
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2)); (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); const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type);
getdns_return_t _getdns_rr_dict2wire( #define NAME_CACHE_ENTRIES 4
const getdns_dict *rr_dict, gldns_buffer *buf);
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); 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 then
exit 1 exit 1
else else
diff out "${TPKG_NAME}.good" diff out "${TPKG_NAME}.good" --ignore-matching-lines=";; MSG SIZE rcvd: "
fi fi