diff --git a/src/context.c b/src/context.c index 3558e13d..034f3ca6 100644 --- a/src/context.c +++ b/src/context.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "config.h" #include "gldns/str2wire.h" diff --git a/src/dnssec.c b/src/dnssec.c index 486cf27a..bfeee146 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -50,6 +50,7 @@ #include "gldns/str2wire.h" #include "gldns/wire2str.h" #include "general.h" +#include "dict.h" void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *); @@ -444,7 +445,37 @@ void priv_getdns_get_validation_chain(getdns_dns_req *dns_req) /********************** functions for validate_dnssec *************************/ static getdns_return_t -priv_getdns_rr_list_from_list(struct getdns_list *list, ldns_rr_list **rr_list) +priv_getdns_create_rr_from_dict(getdns_dict *rr_dict, ldns_rr **rr) +{ + gldns_buffer buf; + uint8_t space[8192], *xspace = NULL; + size_t xsize, pos = 0; + ldns_status s; + getdns_return_t r; + + gldns_buffer_init_frm_data(&buf, space, sizeof(space)); + if ((r = priv_getdns_rr_dict2wire(rr_dict, &buf))) + return r; + + if ((xsize = gldns_buffer_position(&buf)) > sizeof(space)) { + if (!(xspace = GETDNS_XMALLOC(rr_dict->mf, uint8_t, xsize))) + return GETDNS_RETURN_MEMORY_ERROR; + + gldns_buffer_init_frm_data(&buf, xspace, xsize); + if ((r = priv_getdns_rr_dict2wire(rr_dict, &buf))) { + GETDNS_FREE(rr_dict->mf, xspace); + return r; + } + } + s = ldns_wire2rr(rr, gldns_buffer_begin(&buf), + gldns_buffer_position(&buf), &pos, GLDNS_SECTION_ANSWER); + if (xspace) + GETDNS_FREE(rr_dict->mf, xspace); + return s ? GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD; +} + +static getdns_return_t +priv_getdns_rr_list_from_list(getdns_list *list, ldns_rr_list **rr_list) { getdns_return_t r; size_t i, l; diff --git a/src/rr-dict.c b/src/rr-dict.c index 85d779d8..105c550c 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -737,158 +737,90 @@ priv_getdns_rr_type_name(int rr_type) return priv_getdns_rr_def_lookup(rr_type)->name; } -static getdns_return_t priv_getdns_construct_wire_rdata_from_rdata( - struct getdns_dict *rdata, uint32_t rr_type, - uint8_t **wire, size_t *wire_size) -{ - getdns_return_t r = GETDNS_RETURN_GOOD; - const priv_getdns_rr_def *def; - size_t i, j, size; - struct getdns_bindata *bindata; - uint32_t value; - uint8_t *ptr; - - assert(rdata); - assert(wire); - assert(wire_size); - - def = priv_getdns_rr_def_lookup(rr_type); - - /* First calculate needed size */ - size = 0; - for (i = 0; !r && i < def->n_rdata_fields; i++) { - if (def->rdata[i].type & GETDNS_RDF_BINDATA) - if ((r = getdns_dict_get_bindata(rdata, - def->rdata[i].name, &bindata))) - break; - else { - size += bindata->size; - continue; - } - else if (!(def->rdata[i].type & GETDNS_RDF_INTEGER)) { - r = GETDNS_RETURN_GENERIC_ERROR; - break; - } - size += def->rdata[i].type & GETDNS_RDF_FIXEDSZ; - } - *wire_size = size + 2; - *wire = ptr = GETDNS_XMALLOC(rdata->mf, uint8_t, size + 2); - if (! ptr) - return GETDNS_RETURN_MEMORY_ERROR; - - ptr[0] = (uint8_t) (size >> 8) & 0xff; - ptr[1] = (uint8_t) size & 0xff; - ptr += 2; - for (i = 0; !r && i < def->n_rdata_fields; i++) { - if (def->rdata[i].type & GETDNS_RDF_BINDATA) - if ((r = getdns_dict_get_bindata(rdata, - def->rdata[i].name, &bindata))) - break; - else { - (void) memcpy(ptr, bindata->data, - bindata->size); - ptr += bindata->size; - continue; - } - else if (!(def->rdata[i].type & GETDNS_RDF_INTEGER)) { - r = GETDNS_RETURN_GENERIC_ERROR; - break; - } - if ((r = getdns_dict_get_int( - rdata, def->rdata[i].name, &value))) - break; - - for (j = def->rdata[i].type & GETDNS_RDF_FIXEDSZ; j; j--) - *ptr++ = (uint8_t)(value >> (8 * (j - 1))) & 0xff; - } - if (r) - GETDNS_FREE(rdata->mf, ptr); - return r; -} - getdns_return_t -priv_getdns_create_rr_from_dict(struct getdns_dict *rr_dict, ldns_rr **rr) +priv_getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf) { getdns_return_t r = GETDNS_RETURN_GOOD; struct getdns_bindata *name; struct getdns_bindata *rdata_raw; + struct getdns_bindata *bindata; struct getdns_dict *rdata; uint32_t rr_type; - ldns_rdf *owner; - ldns_status s; - size_t pos; - uint8_t *wire; - size_t wire_size; + uint32_t rr_class = GETDNS_RRCLASS_IN; + uint32_t rr_ttl = 0; + uint32_t value; + const priv_getdns_rr_def *rr_def; + const priv_getdns_rdata_def *rd_def; + int n_rdata_fields; + size_t j; assert(rr_dict); - assert(rr); - - *rr = ldns_rr_new(); - if (! *rr) - return GETDNS_RETURN_MEMORY_ERROR; + assert(buf); if ((r = getdns_dict_get_bindata(rr_dict, "name", &name))) goto error; - - owner = ldns_rdf_new_frm_data( - LDNS_RDF_TYPE_DNAME, name->size, name->data); - if (! owner) { - r = GETDNS_RETURN_MEMORY_ERROR; - goto error; - } - ldns_rr_set_owner(*rr, owner); + gldns_buffer_write(buf, name->data, name->size); if ((r = getdns_dict_get_int(rr_dict, "type", &rr_type))) goto error; - ldns_rr_set_type(*rr, rr_type); + gldns_buffer_write_u16(buf, (uint16_t)rr_type); - if ((r = getdns_dict_get_dict(rr_dict, "rdata", &rdata))) - goto error; + (void) getdns_dict_get_int(rr_dict, "class", &rr_class); + gldns_buffer_write_u16(buf, (uint16_t)rr_class); - const priv_getdns_rr_def *rr_def = priv_getdns_rr_def_lookup(rr_type); - const priv_getdns_rdata_def *rd_def; - int n_rdata_fields; + (void) getdns_dict_get_int(rr_dict, "ttl", &rr_ttl); + gldns_buffer_write_u32(buf, rr_ttl); + /* Does rdata contain compressed names? + * Because rdata_raw is unusable then. + */ + rr_def = priv_getdns_rr_def_lookup(rr_type); for ( rd_def = rr_def->rdata , n_rdata_fields = rr_def->n_rdata_fields - ; n_rdata_fields - ; n_rdata_fields-- - , rd_def++ ) { + ; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) { if (rd_def->type & GETDNS_RDF_COMPRESSED) break; } + if ((r = getdns_dict_get_dict(rr_dict, "rdata", &rdata))) + goto error; + if (n_rdata_fields == 0 && GETDNS_RETURN_GOOD == (r = getdns_dict_get_bindata(rdata, "rdata_raw", &rdata_raw))) { - wire_size = rdata_raw->size + 2; - wire = GETDNS_XMALLOC(rdata->mf, uint8_t, wire_size); - if (! wire) { - r = GETDNS_RETURN_MEMORY_ERROR; - goto error; - } - - wire[0] = (uint8_t) (rdata_raw->size >> 8) & 0xff; - wire[1] = (uint8_t) rdata_raw->size & 0xff; - - (void) memcpy(wire + 2, rdata_raw->data, rdata_raw->size); + gldns_buffer_write_u16(buf, (uint16_t)rdata_raw->size); + gldns_buffer_write(buf, rdata_raw->data, rdata_raw->size); } else if (n_rdata_fields || r == GETDNS_RETURN_NO_SUCH_DICT_NAME) { - r = priv_getdns_construct_wire_rdata_from_rdata(rdata, rr_type, - &wire, &wire_size); + for ( rd_def = rr_def->rdata + , n_rdata_fields = rr_def->n_rdata_fields + ; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) { + + if (rd_def->type & GETDNS_RDF_BINDATA) { + if ((r = getdns_dict_get_bindata(rdata, + rd_def->name, &bindata))) + break; + + gldns_buffer_write(buf, bindata->data + , bindata->size ); + continue; + } + if (!(rd_def->type & GETDNS_RDF_INTEGER)) { + r = GETDNS_RETURN_GENERIC_ERROR; + break; + } + if ((r = getdns_dict_get_int( + rdata, rd_def->name, &value))) + break; + + for (j = rd_def->type & GETDNS_RDF_FIXEDSZ; j; j--) + gldns_buffer_write_u8(buf, + (uint8_t)(value >> (8 * (j - 1))) & 0xff); + } } - - pos = 0; - s = ldns_wire2rdf(*rr, wire, wire_size, &pos); - GETDNS_FREE(rr_dict->mf, wire); - if (s == LDNS_STATUS_OK) - return r; - - r = GETDNS_RETURN_GENERIC_ERROR; error: - ldns_rr_free(*rr); return r; } diff --git a/src/rr-dict.h b/src/rr-dict.h index cff4215a..9228105e 100644 --- a/src/rr-dict.h +++ b/src/rr-dict.h @@ -32,8 +32,9 @@ #ifndef RR_DICT_H_ #define RR_DICT_H_ -#include +#include "config.h" #include "getdns/getdns.h" +#include "gldns/gbuffer.h" typedef uint8_t *(*priv_getdns_rdf_end_t)( uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf); @@ -132,8 +133,8 @@ typedef struct priv_getdns_rr_def { const priv_getdns_rr_def *priv_getdns_rr_def_lookup(uint16_t rr_type); -getdns_return_t priv_getdns_create_rr_from_dict( - struct getdns_dict *rr_dict, ldns_rr **rr); +getdns_return_t priv_getdns_rr_dict2wire( + getdns_dict *rr_dict, gldns_buffer *buf); const char *priv_getdns_rr_type_name(int rr_type); diff --git a/src/stub.c b/src/stub.c index c671b81d..63712387 100644 --- a/src/stub.c +++ b/src/stub.c @@ -31,6 +31,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include "config.h" #include #include "stub.h" @@ -40,7 +41,6 @@ #include "gldns/str2wire.h" #include "rr-iter.h" #include "context.h" -#include #include "util-internal.h" #include "general.h" diff --git a/src/util-internal.c b/src/util-internal.c index 9a6f35c7..f125090f 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -37,6 +37,7 @@ #include #include +#include #include #include "getdns/getdns.h" #include "dict.h"