mirror of https://github.com/getdnsapi/getdns.git
rm of superfluous ldns_rr to getdns_dict funcs
This commit is contained in:
parent
fd385454b4
commit
c28f6ee595
435
src/rr-dict.c
435
src/rr-dict.c
|
@ -737,441 +737,6 @@ priv_getdns_rr_type_name(int rr_type)
|
|||
return priv_getdns_rr_def_lookup(rr_type)->name;
|
||||
}
|
||||
|
||||
/* list of txt records */
|
||||
static getdns_return_t
|
||||
priv_getdns_equip_dict_with_txt_rdfs(struct getdns_dict* rdata, ldns_rr* rr,
|
||||
const priv_getdns_rr_def* def,
|
||||
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) {
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
}
|
||||
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;
|
||||
}
|
||||
int txt_size = (int) rdf_data[0];
|
||||
if (rdf_size < txt_size) {
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
r = getdns_dict_set_list(rdata, def->rdata[0].name, records);
|
||||
}
|
||||
getdns_list_destroy(records);
|
||||
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 priv_getdns_rr_def* def,
|
||||
struct getdns_context* context) {
|
||||
uint8_t alg;
|
||||
getdns_return_t r;
|
||||
struct getdns_bindata hit_data;
|
||||
struct getdns_bindata key_data;
|
||||
/* first rdf contains the key data */
|
||||
ldns_rdf* rdf = ldns_rr_rdf(rr, 0);
|
||||
/* ask LDNS to parse it for us */
|
||||
r = getdns_rdf_hip_get_alg_hit_pk(rdf, &alg, &hit_data, &key_data);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
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 GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
if (ldns_rr_rd_count(rr) > 1) {
|
||||
/* servers */
|
||||
size_t i;
|
||||
struct getdns_bindata server_data;
|
||||
struct getdns_list* servers = getdns_list_create_with_context(context);
|
||||
if (!servers) {
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
}
|
||||
for (i = 1; i < ldns_rr_rd_count(rr) && r == GETDNS_RETURN_GOOD; ++i) {
|
||||
ldns_rdf* server_rdf = ldns_rr_rdf(rr, i);
|
||||
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);
|
||||
}
|
||||
if (r == GETDNS_RETURN_GOOD) {
|
||||
r = getdns_dict_set_list(rdata, def->rdata[3].name, servers);
|
||||
}
|
||||
/* always clean up */
|
||||
getdns_list_destroy(servers);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
priv_append_apl_record(getdns_list* records, ldns_rdf* rdf,
|
||||
const priv_getdns_rr_def* def, 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 priv_getdns_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;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_equip_dict_with_spf_rdfs(struct getdns_dict* rdata, ldns_rr* rr,
|
||||
const priv_getdns_rr_def* def,
|
||||
struct getdns_context* context) {
|
||||
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 = context
|
||||
? GETDNS_XMALLOC(context->my_mf, uint8_t, bindata.size)
|
||||
: malloc(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);
|
||||
if (context)
|
||||
GETDNS_FREE(context->my_mf, bindata.data);
|
||||
else
|
||||
free(bindata.data);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_equip_dict_with_rdfs(struct getdns_dict *rdata, ldns_rr *rr,
|
||||
struct getdns_context* context)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
const priv_getdns_rr_def *def;
|
||||
struct getdns_bindata bindata;
|
||||
size_t i;
|
||||
|
||||
struct getdns_bindata *rdata_raw;
|
||||
const char *sptr;
|
||||
char *dptr, tmpbuf[100];
|
||||
|
||||
uint8_t *rdf_data;
|
||||
size_t rdf_size;
|
||||
|
||||
assert(rdata);
|
||||
assert(rr);
|
||||
|
||||
def = priv_getdns_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);
|
||||
} else if (def->name &&
|
||||
strlen(def->name) <= sizeof(tmpbuf) - 9 /* strlen("_unknown")+1 */ &&
|
||||
(def->rdata == UNKNOWN_RDATA ||
|
||||
ldns_rr_descriptor_field_type(
|
||||
ldns_rr_descript(ldns_rr_get_type(rr)), 0) == LDNS_RDF_TYPE_UNKNOWN)) {
|
||||
|
||||
r = getdns_dict_get_bindata(rdata, "rdata_raw", &rdata_raw);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
return r;
|
||||
|
||||
sptr = def->name;
|
||||
dptr = tmpbuf;
|
||||
do *dptr++ = tolower(*sptr);
|
||||
while (*sptr++); /* Including terminating '\0' */
|
||||
|
||||
return getdns_dict_set_bindata(
|
||||
rdata, strcat(tmpbuf, "_unknown"), rdata_raw);
|
||||
}
|
||||
/* generic */
|
||||
if (ldns_rr_rd_count(rr) != def->n_rdata_fields)
|
||||
return r;
|
||||
|
||||
for (i = 0; !r && i < ldns_rr_rd_count(rr)
|
||||
&& i < def->n_rdata_fields; i++) {
|
||||
|
||||
if (! (def->rdata[i].type & GETDNS_RDF_INTEGER)) {
|
||||
bindata.size = ldns_rdf_size(ldns_rr_rdf(rr, i));
|
||||
bindata.data = ldns_rdf_data(ldns_rr_rdf(rr, i));
|
||||
r = getdns_dict_set_bindata(
|
||||
rdata, (char*)def->rdata[i].name, &bindata);
|
||||
continue;
|
||||
}
|
||||
rdf_size = ldns_rdf_size(ldns_rr_rdf(rr, i));
|
||||
rdf_data = ldns_rdf_data(ldns_rr_rdf(rr, i));
|
||||
r = getdns_dict_set_int(rdata, (char *)def->rdata[i].name,
|
||||
rdf_size == 1 ? *rdf_data
|
||||
: rdf_size == 2 ? ldns_read_uint16(rdf_data)
|
||||
: rdf_size == 4 ? ldns_read_uint32(rdf_data) : -1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_create_dict_from_rdfs(
|
||||
struct getdns_context *context, ldns_rr *rr, struct getdns_dict** rdata)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
struct getdns_bindata rdata_raw;
|
||||
uint8_t *data_ptr;
|
||||
size_t i;
|
||||
|
||||
assert(rr);
|
||||
assert(rdata);
|
||||
|
||||
*rdata = getdns_dict_create_with_context(context);
|
||||
if (! *rdata)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
do { /* break on error (to cleanup *rdata) */
|
||||
|
||||
/* Count and reserve "raw" rdata space */
|
||||
rdata_raw.size = 0;
|
||||
for (i = 0; i < ldns_rr_rd_count(rr); i++)
|
||||
rdata_raw.size += ldns_rdf_size(ldns_rr_rdf(rr, i));
|
||||
rdata_raw.data = context
|
||||
? GETDNS_XMALLOC(context->mf, uint8_t, rdata_raw.size)
|
||||
: malloc(rdata_raw.size);
|
||||
if (! rdata_raw.data) {
|
||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
break;
|
||||
}
|
||||
/* Copy rdata fields to rdata space */
|
||||
data_ptr = rdata_raw.data;
|
||||
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
|
||||
(void) memcpy(data_ptr,
|
||||
ldns_rdf_data(ldns_rr_rdf(rr, i)),
|
||||
ldns_rdf_size(ldns_rr_rdf(rr, i)));
|
||||
data_ptr += ldns_rdf_size(ldns_rr_rdf(rr, i));
|
||||
}
|
||||
|
||||
/* Set "rdata_raw" attribute" */
|
||||
r = getdns_dict_set_bindata(*rdata, "rdata_raw", &rdata_raw);
|
||||
if (context)
|
||||
GETDNS_FREE(context->mf, rdata_raw.data);
|
||||
else
|
||||
free(rdata_raw.data);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
/* Now set the RR type specific attributes */
|
||||
r = priv_getdns_equip_dict_with_rdfs(*rdata, rr, context);
|
||||
if (r == GETDNS_RETURN_GOOD)
|
||||
return r;
|
||||
} while(0);
|
||||
getdns_dict_destroy(*rdata);
|
||||
return r;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
priv_getdns_create_dict_from_rr(
|
||||
struct getdns_context *context, ldns_rr *rr, struct getdns_dict** rr_dict)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
struct getdns_bindata name;
|
||||
struct getdns_dict *rdata;
|
||||
|
||||
assert(rr);
|
||||
assert(rr_dict);
|
||||
|
||||
*rr_dict = getdns_dict_create_with_context(context);
|
||||
if (! *rr_dict)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
do { /* break on error (to cleanup *rr_dict) */
|
||||
r = getdns_dict_set_int(*rr_dict,
|
||||
"type", ldns_rr_get_type(rr));
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
r = getdns_dict_set_int(*rr_dict,
|
||||
"class", ldns_rr_get_class(rr));
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
r = getdns_dict_set_int(*rr_dict, "ttl", ldns_rr_ttl(rr));
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
/* "name" attribute.
|
||||
* ldns_rr_owner(rr) is already uncompressed!
|
||||
*/
|
||||
name.size = ldns_rdf_size(ldns_rr_owner(rr));
|
||||
name.data = ldns_rdf_data(ldns_rr_owner(rr));
|
||||
r = getdns_dict_set_bindata(*rr_dict, "name", &name);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
/* The "rdata" dict... copies of copies of copies :( */
|
||||
r = priv_getdns_create_dict_from_rdfs(context, rr, &rdata);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
r = getdns_dict_set_dict(*rr_dict, "rdata", rdata);
|
||||
getdns_dict_destroy(rdata);
|
||||
if (r == GETDNS_RETURN_GOOD)
|
||||
return r;
|
||||
} while (0);
|
||||
getdns_dict_destroy(*rr_dict);
|
||||
return r;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -131,9 +131,6 @@ 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_dict_from_rr(
|
||||
struct getdns_context *context, ldns_rr *rr, struct getdns_dict** rr_dict);
|
||||
|
||||
getdns_return_t priv_getdns_create_rr_from_dict(
|
||||
struct getdns_dict *rr_dict, ldns_rr **rr);
|
||||
|
||||
|
|
Loading…
Reference in New Issue