Skip to content
Snippets Groups Projects
Commit f82d5839 authored by Jan Kadlec's avatar Jan Kadlec
Browse files

Added support for closest enclosers in dnames, which are not in the zone.

parent e53440c8
No related branches found
No related tags found
No related merge requests found
......@@ -27,10 +27,18 @@ void dnslib_rdata_dump(dnslib_rdata_t *rdata, uint32_t type)
name = dnslib_dname_to_str(rdata->items[i].dname);
printf(" DNAME: %d: %s\n",
i, name);
free(name);
if (rdata->items[i].dname->node) {
name =
dnslib_dname_to_str(rdata->items[i].dname->node->owner);
printf(" Has node owner: %s\n", name);
free(name);
} else {
printf(" No node set\n");
}
printf(" labels: ");
hex_print((char *)rdata->items[i].dname->labels,
rdata->items[i].dname->label_count);
free(name);
} else {
assert(rdata->items[i].raw_data != NULL);
......
......@@ -4,6 +4,140 @@
#include "zone-dump.h"
#include "dnslib.h"
#include "skip-list.h"
struct arg {
void *arg1; /* FILE *f / zone */
void *arg2; /* skip_list_t */
};
typedef struct arg arg_t;
/* we only need ordering for search purposes, therefore it is OK to compare
* pointers directly */
static int compare_pointers(void *p1, void *p2)
{
return ((uint)p1 == (uint)p2 ? 0 : (uint)p1 < (uint)p2 ? -1 : 1);
}
/* Functions for zone traversal are taken from dnslib/zone.c */
static void dnslib_zone_save_encloser_rdata_item(dnslib_rdata_t *rdata,
dnslib_zone_t *zone, uint pos,
skip_list_t *list)
{
const dnslib_rdata_item_t *dname_item
= dnslib_rdata_item(rdata, pos);
if (dname_item != NULL) {
dnslib_dname_t *dname = dname_item->dname;
const dnslib_node_t *n = NULL;
const dnslib_node_t *closest_encloser = NULL;
int exact = dnslib_zone_find_dname(zone, dname, &n,
&closest_encloser);
// n = dnslib_zone_find_node(zone, dname);
assert(!exact || n == closest_encloser);
if (!exact && (closest_encloser != NULL)) {
debug_dnslib_zone("Saving closest encloser to RDATA.\n");
// save pointer to the closest encloser
dnslib_rdata_item_t *item =
dnslib_rdata_get_item(rdata, pos);
assert(item->dname != NULL);
skip_insert(list, (void *)item->dname,
(void *)closest_encloser->owner, NULL);
}
}
}
static void dnslib_zone_save_enclosers_node(dnslib_node_t *node,
dnslib_rr_type_t type,
dnslib_zone_t *zone,
skip_list_t *list)
{
dnslib_rrset_t *rrset = dnslib_node_get_rrset(node, type);
if (!rrset) {
return;
}
dnslib_rrtype_descriptor_t *desc =
dnslib_rrtype_descriptor_by_type(type);
dnslib_rdata_t *rdata_first = dnslib_rrset_get_rdata(rrset);
dnslib_rdata_t *rdata = rdata_first;
if (rdata == NULL) {
return;
}
while (rdata->next != rdata_first) {
for (int i = 0; i < rdata->count; ++i) {
if (desc->wireformat[i]
== DNSLIB_RDATA_WF_COMPRESSED_DNAME
|| desc->wireformat[i]
== DNSLIB_RDATA_WF_UNCOMPRESSED_DNAME
|| desc->wireformat[i]
== DNSLIB_RDATA_WF_LITERAL_DNAME) {
debug_dnslib_zone("Adjusting domain name at "
"position %d of RDATA of record with owner "
"%s and type %s.\n",
i, rrset->owner->name,
dnslib_rrtype_to_string(type));
dnslib_zone_save_encloser_rdata_item(rdata,
zone,
i,
list);
}
}
rdata = rdata->next;
}
for (int i = 0; i < rdata->count; ++i) {
if (desc->wireformat[i]
== DNSLIB_RDATA_WF_COMPRESSED_DNAME
|| desc->wireformat[i]
== DNSLIB_RDATA_WF_UNCOMPRESSED_DNAME
|| desc->wireformat[i]
== DNSLIB_RDATA_WF_LITERAL_DNAME) {
debug_dnslib_zone("Adjusting domain name at "
"position %d of RDATA of record with owner "
"%s and type %s.\n",
i, rrset->owner->name,
dnslib_rrtype_to_string(type));
dnslib_zone_save_encloser_rdata_item(rdata,
zone,
i,
list);
}
}
}
static void dnslib_zone_save_enclosers_in_tree(dnslib_node_t *node, void *data)
{
assert(data != NULL);
arg_t *args = (arg_t *)data;
for (int i = 0; i < DNSLIB_COMPRESSIBLE_TYPES; ++i) {
dnslib_zone_save_enclosers_node(node, dnslib_compressible_types[i],
(dnslib_zone_t *)args->arg1,
(skip_list_t *)args->arg2);
}
}
void dnslib_zone_save_enclosers(dnslib_zone_t *zone, skip_list_t *list)
{
arg_t arguments;
arguments.arg1 = zone;
arguments.arg2 = list;
TREE_FORWARD_APPLY(zone->tree, dnslib_node, avl,
dnslib_zone_save_enclosers_in_tree,
(void *)&arguments);
}
enum { MAGIC_LENGTH = 4 };
......@@ -29,15 +163,16 @@ static void dnslib_dname_dump_binary(dnslib_dname_t *dname, FILE *f)
dnslib_labels_dump_binary(dname, f);
}
static dnslib_dname_t *dnslib_find_wildcard(dnslib_zone_t *zone,
dnslib_dname_t *dname)
static dnslib_dname_t *dnslib_find_wildcard(dnslib_dname_t *dname, skip_list_t *list)
{
return NULL;
return (dnslib_dname_t *)skip_find(list, (void *)dname);
}
static void dnslib_rdata_dump_binary(dnslib_rdata_t *rdata,
uint32_t type, FILE *f)
uint32_t type, void *data)
{
FILE *f = (FILE *)((arg_t *)data)->arg1;
skip_list_t *list = (skip_list_t *)((arg_t *)data)->arg2;
dnslib_rrtype_descriptor_t *desc =
dnslib_rrtype_descriptor_by_type(type);
assert(desc != NULL);
......@@ -55,7 +190,7 @@ static void dnslib_rdata_dump_binary(dnslib_rdata_t *rdata,
if (rdata->items[i].dname->node == NULL ||
(wildcard =
/* just a skeleton */ dnslib_find_wildcard(NULL, NULL)) ) {
dnslib_find_wildcard(rdata->items[i].dname, list)) ) {
debug_zp("not in zone: %s\n",
dnslib_dname_to_str((rdata->items[i].dname)));
fwrite((uint8_t *)"\0", sizeof(uint8_t), 1, f);
......@@ -86,8 +221,9 @@ static void dnslib_rdata_dump_binary(dnslib_rdata_t *rdata,
}
}
static void dnslib_rrsig_set_dump_binary(dnslib_rrsig_set_t *rrsig, FILE *f)
static void dnslib_rrsig_set_dump_binary(dnslib_rrsig_set_t *rrsig, arg_t *data)
{
FILE *f = (FILE *)((arg_t *)data)->arg1;
fwrite(&rrsig->type, sizeof(rrsig->type), 1, f);
fwrite(&rrsig->rclass, sizeof(rrsig->rclass), 1, f);
fwrite(&rrsig->ttl, sizeof(rrsig->ttl), 1, f);
......@@ -123,8 +259,9 @@ static void dnslib_rrsig_set_dump_binary(dnslib_rrsig_set_t *rrsig, FILE *f)
fsetpos(f, &tmp_pos);
}
static void dnslib_rrset_dump_binary(dnslib_rrset_t *rrset, FILE *f)
static void dnslib_rrset_dump_binary(dnslib_rrset_t *rrset, void *data)
{
FILE *f = (FILE *)((arg_t *)data)->arg1;
fwrite(&rrset->type, sizeof(rrset->type), 1, f);
fwrite(&rrset->rclass, sizeof(rrset->rclass), 1, f);
fwrite(&rrset->ttl, sizeof(rrset->ttl), 1, f);
......@@ -142,15 +279,15 @@ static void dnslib_rrset_dump_binary(dnslib_rrset_t *rrset, FILE *f)
dnslib_rdata_t *tmp_rdata = rrset->rdata;
while (tmp_rdata->next != rrset->rdata) {
dnslib_rdata_dump_binary(tmp_rdata, rrset->type, f);
dnslib_rdata_dump_binary(tmp_rdata, rrset->type, data);
tmp_rdata = tmp_rdata->next;
rdata_count++;
}
dnslib_rdata_dump_binary(tmp_rdata, rrset->type, f);
dnslib_rdata_dump_binary(tmp_rdata, rrset->type, data);
rdata_count++;
if (rrset->rrsigs != NULL) {
dnslib_rrsig_set_dump_binary(rrset->rrsigs, f);
dnslib_rrsig_set_dump_binary(rrset->rrsigs, data);
rrsig_count = 1;
}
......@@ -166,9 +303,11 @@ static void dnslib_rrset_dump_binary(dnslib_rrset_t *rrset, FILE *f)
fsetpos(f, &tmp_pos);
}
static void dnslib_node_dump_binary(dnslib_node_t *node, void *fp)
static void dnslib_node_dump_binary(dnslib_node_t *node, void *data)
{
FILE *f = (FILE *)fp;
arg_t *args = (arg_t *)data;
FILE *f = (FILE *)args->arg1;
node_count++;
/* first write dname */
......@@ -217,7 +356,7 @@ static void dnslib_node_dump_binary(dnslib_node_t *node, void *fp)
do {
tmp = (dnslib_rrset_t *)skip_node->value;
rrset_count++;
dnslib_rrset_dump_binary(tmp, f);
dnslib_rrset_dump_binary(tmp, data);
} while ((skip_node = skip_next(skip_node)) != NULL);
fpos_t tmp_pos;
......@@ -248,6 +387,10 @@ int dnslib_zone_dump_binary(dnslib_zone_t *zone, const char *filename)
return -1;
}
skip_list_t *encloser_list = skip_create_list(compare_pointers);
dnslib_zone_save_enclosers(zone, encloser_list);
static const uint8_t MAGIC[MAGIC_LENGTH] = {99, 117, 116, 101};
/*c u t e */
......@@ -257,14 +400,21 @@ int dnslib_zone_dump_binary(dnslib_zone_t *zone, const char *filename)
fwrite(&node_count, sizeof(node_count), 1, f);
dnslib_dname_dump_binary(zone->apex->owner, f);
arg_t arguments;
arguments.arg1 = f;
arguments.arg2 = encloser_list;
/* TODO is there a way how to stop the traversal upon error? */
dnslib_zone_tree_apply_inorder(zone, dnslib_node_dump_binary, f);
dnslib_zone_tree_apply_inorder(zone, dnslib_node_dump_binary,
(void *)&arguments);
uint tmp_count = node_count;
node_count = 0;
dnslib_zone_nsec3_apply_inorder(zone, dnslib_node_dump_binary, f);
dnslib_zone_nsec3_apply_inorder(zone, dnslib_node_dump_binary,
(void *)&arguments);
fseek(f, MAGIC_LENGTH, SEEK_SET);
......
......@@ -71,12 +71,6 @@ dnslib_rdata_t *dnslib_load_rdata(uint16_t type, FILE *f)
fread(&has_wildcard, sizeof(uint8_t), 1, f);
if (has_wildcard) {
fread(&tmp_id, sizeof(void *), 1, f);
} else {
tmp_id = NULL;
}
items[i].dname = malloc(sizeof(dnslib_dname_t));
items[i].dname->name = dname_wire;
......@@ -84,7 +78,14 @@ dnslib_rdata_t *dnslib_load_rdata(uint16_t type, FILE *f)
items[i].dname->labels = labels;
items[i].dname->label_count = label_count;
items[i].dname->node = tmp_id;
if (has_wildcard) {
fread(&tmp_id, sizeof(void *), 1, f);
printf("read ID: %d\n", (uint)tmp_id);
getchar();
items[i].dname->node = id_array[(uint)tmp_id]->node;
} else {
items[i].dname->node = NULL;
}
}
assert(items[i].dname);
......@@ -242,13 +243,15 @@ dnslib_node_t *dnslib_load_node(FILE *f)
debug_zp("Number of RRSets in a node: %d\n", rrset_count);
if ((node = dnslib_node_new(owner, NULL)) == NULL) {
node = owner->node;
node->owner = owner;
if (node == NULL) {
fprintf(stderr, "Error: could not create node\n");
return NULL;
}
owner->node = node;
node->flags = flags;
//XXX will have to be set already...canonical order should do it
......@@ -376,6 +379,7 @@ dnslib_zone_t *dnslib_zone_load(const char *filename)
for (uint i = 1; i < (node_count + nsec3_node_count + 1); i++) {
id_array[i] = malloc(sizeof(dnslib_dname_t));
id_array[i]->node = dnslib_node_new(NULL, NULL);
}
for (uint i = 0; i < node_count; i++) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment