From f750f758ff58cd5649afea0f5e9e8359bef3e29f Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 6 Feb 2014 11:07:04 -0500 Subject: [PATCH 1/5] Fix an issue with extension headers --- src/Makefile.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Makefile.in b/src/Makefile.in index 995ebfc4..c01f1443 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -21,6 +21,8 @@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ have_libevent = @have_libevent@ +have_libuv = @have_libuv@ +have_libev = @have_libev@ # datarootdir is here to please some checkers datarootdir=@datarootdir@ INSTALL = @INSTALL@ @@ -58,6 +60,7 @@ install: libgetdns.la $(INSTALL) -m 644 $(srcdir)/getdns/getdns.h $(DESTDIR)$(includedir)/getdns/getdns.h if test $(have_libevent) = 1 ; then $(INSTALL) -m 644 $(srcdir)/getdns/getdns_ext_libevent.h $(DESTDIR)$(includedir)/getdns/ ; fi if test $(have_libuv) = 1 ; then $(INSTALL) -m 644 $(srcdir)/getdns/getdns_ext_libuv.h $(DESTDIR)$(includedir)/getdns/ ; fi + if test $(have_libev) = 1 ; then $(INSTALL) -m 644 $(srcdir)/getdns/getdns_ext_libev.h $(DESTDIR)$(includedir)/getdns/ ; fi $(INSTALL) -m 755 -d $(DESTDIR)$(libdir) $(LIBTOOL) --mode=install cp libgetdns.la $(DESTDIR)$(libdir) $(LIBTOOL) --mode=finish $(DESTDIR)$(libdir) From 24e56217f8a293cbace87593a266443c6a911579 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 6 Feb 2014 11:10:09 -0500 Subject: [PATCH 2/5] Put hip server data in wire format --- src/rr-dict.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/rr-dict.c b/src/rr-dict.c index d61bec3e..b67d9c4f 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -630,14 +630,14 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, } hit_data.size = hit_size; key_data.size = key_size; - + r = getdns_dict_set_int(rdata, def->rdata[0].name, alg); r |= getdns_dict_set_bindata(rdata, def->rdata[1].name, &hit_data); r |= getdns_dict_set_bindata(rdata, def->rdata[2].name, &key_data); if (r != GETDNS_RETURN_GOOD) { return r; } - + if (ldns_rr_rd_count(rr) > 1) { /* servers */ size_t i; @@ -648,15 +648,9 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, } for (i = 1; i < ldns_rr_rd_count(rr) && r == GETDNS_RETURN_GOOD; ++i) { ldns_rdf* server_rdf = ldns_rr_rdf(rr, i); - char* name = ldns_rdf2str(server_rdf); - if (name == NULL) { - r = GETDNS_RETURN_MEMORY_ERROR; - break; - } - server_data.size = strlen(name) + 1; - server_data.data = (uint8_t*)name; + server_data.size = ldns_rdf_size(server_rdf); + server_data.data = ldns_rdf_data(server_rdf); r = getdns_list_set_bindata(servers, i - 1, &server_data); - free(name); } if (r != GETDNS_RETURN_GOOD) { getdns_list_destroy(servers); @@ -667,7 +661,7 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, } } } - + return r; } From d1a4c0e35be6555b2fa2fa3ec04435186470378e Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 6 Feb 2014 12:16:16 -0500 Subject: [PATCH 3/5] Remove ldns 1.6.17 function --- src/rr-dict.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/rr-dict.c b/src/rr-dict.c index b67d9c4f..e1308e0b 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -610,6 +610,31 @@ priv_getdns_equip_dict_with_txt_rdfs(struct getdns_dict* rdata, ldns_rr* rr, return r; } +/* heavily borrowed/copied from ldns 1.6.17 */ +static +getdns_return_t getdns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg, + struct getdns_bindata* hit, + struct getdns_bindata* pk) +{ + uint8_t *data; + size_t rdf_size; + + if ((rdf_size = ldns_rdf_size(rdf)) < 6) { + return GETDNS_RETURN_GENERIC_ERROR; + } + data = ldns_rdf_data(rdf); + hit->size = data[0]; + *alg = data[1]; + pk->size = ldns_read_uint16(data + 2); + hit->data = data + 4; + pk->data = data + 4 + hit->size; + if (hit->size == 0 || pk->size == 0 || + rdf_size < (size_t) hit->size + pk->size + 4) { + return GETDNS_RETURN_GENERIC_ERROR; + } + return GETDNS_RETURN_GOOD; +} + static getdns_return_t priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, const struct rr_def* def, @@ -623,9 +648,8 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, /* first rdf contains the key data */ ldns_rdf* rdf = ldns_rr_rdf(rr, 0); /* ask LDNS to parse it for us */ - ldns_status s = ldns_rdf_hip_get_alg_hit_pk(rdf, &alg, &hit_size, - &(hit_data.data), &key_size, &(key_data.data)); - if (s != LDNS_STATUS_OK) { + r = getdns_rdf_hip_get_alg_hit_pk(rdf, &alg, &hit_data, &key_data); + if (r != GETDNS_RETURN_GOOD) { return GETDNS_RETURN_GENERIC_ERROR; } hit_data.size = hit_size; @@ -665,6 +689,21 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, return r; } +static getdns_return_t +priv_getdns_equip_dict_with_apl_rdfs(struct getdns_dict* rdata, ldns_rr* rr, + const struct rr_def* def, + struct getdns_context* context) { + return GETDNS_RETURN_GOOD; +} + +static getdns_return_t +priv_getdns_equip_dict_with_spf_rdfs(struct getdns_dict* rdata, ldns_rr* rr, + const struct rr_def* def, + struct getdns_context* context) { + return GETDNS_RETURN_GOOD; +} + + static getdns_return_t priv_getdns_equip_dict_with_rdfs(struct getdns_dict *rdata, ldns_rr *rr, struct getdns_context* context) @@ -680,10 +719,16 @@ priv_getdns_equip_dict_with_rdfs(struct getdns_dict *rdata, ldns_rr *rr, def = rr_def_lookup(ldns_rr_get_type(rr)); /* specialty handlers */ + /* TODO: convert generic one into function w/ similar signature and store in the + * def? */ if (def->rdata == txt_rdata) { return priv_getdns_equip_dict_with_txt_rdfs(rdata, rr, def, context); } else if (def->rdata == hip_rdata) { return priv_getdns_equip_dict_with_hip_rdfs(rdata, rr, def, context); + } else if (def->rdata == apl_rdata) { + return priv_getdns_equip_dict_with_apl_rdfs(rdata, rr, def, context); + } else if (def->rdata == spf_rdata) { + return priv_getdns_equip_dict_with_spf_rdfs(rdata, rr, def, context); } /* generic */ for (i = 0; i < ldns_rr_rd_count(rr) && r == GETDNS_RETURN_GOOD; i++) { From 823bd664c578480dd7a3809efdf8ae0e21bb4c94 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 6 Feb 2014 12:27:42 -0500 Subject: [PATCH 4/5] Fix use of uninitialized var in hip parse --- src/rr-dict.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/rr-dict.c b/src/rr-dict.c index e1308e0b..984c8635 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -640,8 +640,6 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, const struct rr_def* def, struct getdns_context* context) { uint8_t alg; - uint8_t hit_size; - uint16_t key_size; getdns_return_t r; struct getdns_bindata hit_data; struct getdns_bindata key_data; @@ -652,8 +650,6 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, if (r != GETDNS_RETURN_GOOD) { return GETDNS_RETURN_GENERIC_ERROR; } - hit_data.size = hit_size; - key_data.size = key_size; r = getdns_dict_set_int(rdata, def->rdata[0].name, alg); r |= getdns_dict_set_bindata(rdata, def->rdata[1].name, &hit_data); From 0419c4673cc2993174ff0d74ec12f8ce134b620c Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 6 Feb 2014 14:12:49 -0500 Subject: [PATCH 5/5] Add APL and SPF type support. Fix some string terminator issues in TXT --- src/rr-dict.c | 151 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 135 insertions(+), 16 deletions(-) diff --git a/src/rr-dict.c b/src/rr-dict.c index 984c8635..ae458366 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -576,6 +576,7 @@ priv_getdns_equip_dict_with_txt_rdfs(struct getdns_dict* rdata, ldns_rr* rr, struct getdns_context* context) { size_t i; struct getdns_bindata bindata; + uint8_t buffer[LDNS_MAX_RDFLEN]; getdns_return_t r = GETDNS_RETURN_GOOD; struct getdns_list* records = getdns_list_create_with_context(context); if (!records) { @@ -589,24 +590,22 @@ priv_getdns_equip_dict_with_txt_rdfs(struct getdns_dict* rdata, ldns_rr* rr, r = GETDNS_RETURN_GENERIC_ERROR; continue; } - int txt_size = (int) rdf_data[0] + 1; + int txt_size = (int) rdf_data[0]; if (rdf_size < txt_size) { r = GETDNS_RETURN_GENERIC_ERROR; continue; } - bindata.size = txt_size; - bindata.data = rdf_data + 1; + bindata.size = txt_size + 1; + memcpy(buffer, rdf_data + 1, txt_size); + buffer[txt_size] = 0; + bindata.data = buffer; r = getdns_list_set_bindata(records, i, &bindata); } - if (r != GETDNS_RETURN_GOOD) { - getdns_list_destroy(records); - } else { + if (r == GETDNS_RETURN_GOOD) { r = getdns_dict_set_list(rdata, def->rdata[0].name, records); - if (r != GETDNS_RETURN_GOOD) { - getdns_list_destroy(records); - } } + getdns_list_destroy(records); return r; } @@ -672,23 +671,96 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, server_data.data = ldns_rdf_data(server_rdf); r = getdns_list_set_bindata(servers, i - 1, &server_data); } - if (r != GETDNS_RETURN_GOOD) { - getdns_list_destroy(servers); - } else { + if (r == GETDNS_RETURN_GOOD) { r = getdns_dict_set_list(rdata, def->rdata[3].name, servers); - if (r != GETDNS_RETURN_GOOD) { - getdns_list_destroy(servers); - } } + /* always clean up */ + getdns_list_destroy(servers); } return r; } +static getdns_return_t +priv_append_apl_record(struct getdns_list* records, ldns_rdf* rdf, + const struct rr_def* def, struct getdns_context* context) { + getdns_return_t r = GETDNS_RETURN_GOOD; + uint8_t* data; + size_t size; + uint16_t family; + uint8_t prefix; + uint8_t negation; + size_t addr_len; + size_t pos = 0; + size_t index = 0; + struct getdns_bindata addr_data; + + if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_APL) { + return GETDNS_RETURN_GENERIC_ERROR; + } + getdns_list_get_length(records, &index); + + data = ldns_rdf_data(rdf); + size = ldns_rdf_size(rdf); + if (size < 4) { + /* not enough for the fam, prefix, n, and data len */ + return GETDNS_RETURN_GENERIC_ERROR; + } + while (pos < size && r == GETDNS_RETURN_GOOD) { + struct getdns_dict* apl_dict; + family = ldns_read_uint16(data + pos); + prefix = data[pos + 2]; + negation = (data[pos + 3] & 0x80) > 1 ? 1 : 0; + addr_len = data[pos + 3] & 0x7F; + if (size < 4 + addr_len) { + /* not enough.. */ + return GETDNS_RETURN_GENERIC_ERROR; + } + addr_data.size = addr_len; + addr_data.data = data + 4 + pos; + + /* add to a dictionary */ + apl_dict = getdns_dict_create_with_context(context); + if (!apl_dict) { + /* memory fail */ + return GETDNS_RETURN_MEMORY_ERROR; + } + r |= getdns_dict_set_int(apl_dict, def->rdata[1].name, family); + r |= getdns_dict_set_int(apl_dict, def->rdata[2].name, prefix); + r |= getdns_dict_set_int(apl_dict, def->rdata[3].name, negation); + r |= getdns_dict_set_bindata(apl_dict, def->rdata[4].name, &addr_data); + + if (r == GETDNS_RETURN_GOOD) { + r = getdns_list_set_dict(records, index, apl_dict); + } + pos += addr_data.size + 4; + ++index; + /* always clean up */ + getdns_dict_destroy(apl_dict); + } + + return r; +} + static getdns_return_t priv_getdns_equip_dict_with_apl_rdfs(struct getdns_dict* rdata, ldns_rr* rr, const struct rr_def* def, struct getdns_context* context) { + size_t i; + getdns_return_t r = GETDNS_RETURN_GOOD; + struct getdns_list* records = getdns_list_create_with_context(context); + if (!records) { + return GETDNS_RETURN_MEMORY_ERROR; + } + for (i = 0; i < ldns_rr_rd_count(rr) && r == GETDNS_RETURN_GOOD; ++i) { + r = priv_append_apl_record(records, ldns_rr_rdf(rr, i), + def, context); + } + if (r == GETDNS_RETURN_GOOD) { + getdns_dict_set_list(rdata, def->rdata[0].name, records); + } + getdns_list_destroy(records); + return GETDNS_RETURN_GOOD; } @@ -696,7 +768,54 @@ static getdns_return_t priv_getdns_equip_dict_with_spf_rdfs(struct getdns_dict* rdata, ldns_rr* rr, const struct rr_def* def, struct getdns_context* context) { - return GETDNS_RETURN_GOOD; + size_t i; + struct getdns_bindata bindata; + getdns_return_t r = GETDNS_RETURN_GOOD; + int num_copied = 0; + bindata.size = 0; + /* one giant bindata */ + /* validate and calculate size */ + for (i = 0; i < ldns_rr_rd_count(rr) && r == GETDNS_RETURN_GOOD; ++i) { + ldns_rdf* rdf = ldns_rr_rdf(rr, i); + int rdf_size = (int) ldns_rdf_size(rdf); + uint8_t* rdf_data = ldns_rdf_data(rdf); + if (rdf_size < 1) { + r = GETDNS_RETURN_GENERIC_ERROR; + continue; + } + /* txt size without null byte */ + int txt_size = (int) rdf_data[0]; + if (rdf_size < txt_size) { + r = GETDNS_RETURN_GENERIC_ERROR; + continue; + } + bindata.size += txt_size; + } + /* add one for the null byte */ + bindata.size++; + + if (r != GETDNS_RETURN_GOOD) { + /* validations failed */ + return r; + } + bindata.data = GETDNS_XMALLOC(context->my_mf, uint8_t, + bindata.size); + if (!bindata.data) { + return GETDNS_RETURN_MEMORY_ERROR; + } + /* copy in */ + for (i = 0; i < ldns_rr_rd_count(rr) && r == GETDNS_RETURN_GOOD; ++i) { + ldns_rdf* rdf = ldns_rr_rdf(rr, i); + /* safe to trust these now */ + uint8_t* rdf_data = ldns_rdf_data(rdf); + int txt_size = (int) rdf_data[0]; + memcpy(bindata.data + num_copied, rdf_data + 1, txt_size); + num_copied += txt_size; + } + bindata.data[num_copied] = 0; + r = getdns_dict_set_bindata(rdata, def->rdata[0].name, &bindata); + GETDNS_FREE(context->my_mf, bindata.data); + return r; }