Commit cb81bb71 authored by Jan Kadlec's avatar Jan Kadlec

Simple AXFR-in, cleanup, leak fixes.

parent 89dead74
......@@ -243,7 +243,7 @@ static int remove_expired_rrsigs(const knot_rrset_t *covered,
}
}
result = knot_rrset_add_rr_from_rrset(to_remove, rrsigs, i);
result = knot_rrset_add_rr_from_rrset(to_remove, rrsigs, i, NULL);
if (result != KNOT_EOK) {
break;
}
......@@ -709,7 +709,7 @@ static int remove_invalid_dnskeys(const knot_rrset_t *soa,
}
}
result = knot_rrset_add_rr_from_rrset(to_remove, dnskeys, i);
result = knot_rrset_add_rr_from_rrset(to_remove, dnskeys, i, NULL);
if (result != KNOT_EOK) {
break;
}
......@@ -858,7 +858,7 @@ static int update_dnskeys_rrsigs(const knot_rrset_t *dnskeys,
continue;
}
result = knot_rrset_add_rr_from_rrset(new_dnskeys, dnskeys, i);
result = knot_rrset_add_rr_from_rrset(new_dnskeys, dnskeys, i, NULL);
if (result != KNOT_EOK) {
goto fail;
}
......
......@@ -41,6 +41,9 @@ static int put_rrsets(knot_pkt_t *pkt, knot_node_t *node, struct axfr_proc *stat
/* Append all RRs. */
for (;i < rrset_count; ++i) {
if (rrset[i]->type == KNOT_RRTYPE_SOA) {
continue;
}
ret = knot_pkt_put(pkt, 0, rrset[i], NULL, flags);
/* If something failed, remember the current RR for later. */
......
......@@ -176,7 +176,7 @@ static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
return KNOT_EOK;
}
for (unsigned i = 0; i < knot_node_rrset_count(qdata->node); ++i) {
ret = put_rr(pkt, rrsets[i], rrsigs, compr_hint, 0, qdata);
ret = put_rr(pkt, rrsets[i], NULL, compr_hint, 0, qdata);
if (ret != KNOT_EOK) {
break;
}
......@@ -391,7 +391,6 @@ static int name_found(knot_pkt_t *pkt, struct query_data *qdata)
if (knot_node_rrset(qdata->node, KNOT_RRTYPE_CNAME) != NULL
&& qtype != KNOT_RRTYPE_CNAME
&& qtype != KNOT_RRTYPE_RRSIG
&& qtype != KNOT_RRTYPE_ANY) {
dbg_ns("%s: solving CNAME\n", __func__);
return follow_cname(pkt, KNOT_RRTYPE_CNAME, qdata);
......
......@@ -156,7 +156,8 @@ int knot_ns_process_axfrin(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr)
dbg_ns("ns_process_axfrin: incoming packet, wire size: %zu\n",
xfr->wire_size);
int ret = xfrin_process_axfr_packet(xfr);
knot_zone_contents_t **zp = (knot_zone_contents_t **)&xfr->data;
int ret = xfrin_process_axfr_packet(xfr, zp);
if (ret > 0) { // transfer finished
dbg_ns("ns_process_axfrin: AXFR finished, zone created.\n");
......@@ -167,9 +168,7 @@ int knot_ns_process_axfrin(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr)
* Adjust zone so that node count is set properly and nodes are
* marked authoritative / delegation point.
*/
xfrin_constructed_zone_t *constr_zone =
(xfrin_constructed_zone_t *)xfr->data;
knot_zone_contents_t *zone = constr_zone->contents;
knot_zone_contents_t *zone = *zp;
assert(zone != NULL);
log_zone_info("%s Serial %u -> %u\n", xfr->msg,
knot_zone_serial(knot_zone_contents(xfr->zone)),
......@@ -187,10 +186,6 @@ int knot_ns_process_axfrin(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr)
assert(zone->nsec3_nodes != NULL);
// free the structure used for processing XFR
assert(constr_zone->rrsigs == NULL);
free(constr_zone);
// check zone integrity
dbg_ns_exec_verb(
int errs = knot_zone_contents_integrity_check(zone);
......
......@@ -231,10 +231,10 @@ static void xfr_task_cleanup(knot_ns_xfr_t *rq)
if (rq->flags & XFR_FLAG_AXFR_FINISHED) {
knot_zone_contents_deep_free(&rq->new_contents);
} else if (rq->data) {
xfrin_constructed_zone_t *constr_zone = rq->data;
knot_zone_contents_deep_free(&(constr_zone->contents));
free(rq->data);
rq->data = NULL;
// xfrin_constructed_zone_t *constr_zone = rq->data;
// knot_zone_contents_deep_free(&(constr_zone->contents));
// free(rq->data);
// rq->data = NULL;
}
} else if (rq->type == XFR_TYPE_IIN) {
knot_changesets_t *chs = (knot_changesets_t *)rq->data;
......
This diff is collapsed.
......@@ -38,16 +38,6 @@
/*----------------------------------------------------------------------------*/
typedef struct xfrin_orphan_rrsig {
knot_rrset_t *rrsig;
struct xfrin_orphan_rrsig *next;
} xfrin_orphan_rrsig_t;
typedef struct xfrin_constructed_zone {
knot_zone_contents_t *contents;
xfrin_orphan_rrsig_t *rrsigs;
} xfrin_constructed_zone_t;
typedef enum xfrin_transfer_result {
XFRIN_RES_COMPLETE = 1,
XFRIN_RES_SOA_ONLY = 2,
......@@ -135,11 +125,7 @@ int xfrin_zone_transferred(knot_nameserver_t *nameserver,
*
* \todo Refactor!!!
*/
int xfrin_process_axfr_packet(/*const uint8_t *pkt, size_t size,
xfrin_constructed_zone_t **zone*/
knot_ns_xfr_t *xfr);
void xfrin_free_orphan_rrsigs(xfrin_orphan_rrsig_t **rrsigs);
int xfrin_process_axfr_packet(knot_ns_xfr_t *xfr, knot_zone_contents_t **zone);
/*!
* \brief Destroys the whole changesets structure.
......
......@@ -748,8 +748,8 @@ static int sem_check_node_mandatory(const knot_node_t *node,
if (cname_rrset) {
if (knot_node_rrset_count(node) != 1) {
/* With DNSSEC node can contain RRSIGs or NSEC */
if (!knot_node_rrset(node, KNOT_RRTYPE_NSEC) ||
knot_node_rrset_count(node) > 2) {
if (!(knot_node_rrset(node, KNOT_RRTYPE_NSEC) || knot_node_rrset(node, KNOT_RRTYPE_RRSIG)) ||
knot_node_rrset_count(node) > 3) {
*fatal_error = true;
err_handler_handle_error(handler, node,
ZC_ERR_CNAME_EXTRA_RECORDS_DNSSEC, NULL);
......
......@@ -324,7 +324,7 @@ static int knot_zone_diff_rdata_return_changes(const knot_rrset_t *rrset1,
knot_rrset_type(rrset1),
knot_dname_to_str(rrset1->owner));
/* We'll copy index 'i' into 'changes' RRSet. */
ret = knot_rrset_add_rr_from_rrset(*changes, rrset1, i);
ret = knot_rrset_add_rr_from_rrset(*changes, rrset1, i, NULL);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: diff_rdata: Could not"
" add RR to RRSet (%s).\n",
......
......@@ -75,23 +75,58 @@ static int add_rdata_to_rr(knot_rrset_t *rrset, const scanner_t *scanner)
return KNOT_EOK;
}
static int zone_loader_step(zone_loader_t *zl, knot_rrset_t *rr)
static bool handle_err(zone_loader_t *zl,
const knot_rrset_t *rr,
int ret)
{
char *zname = zl->z ? knot_dname_to_str(zl->z->apex->owner) : NULL;
char *rrname = rr ? knot_dname_to_str(rr->owner) : NULL;
if (ret == KNOT_EOUTOFZONE) {
log_zone_warning("Zone %s: Ignoring out-of-zone data for %s\n",
zname ? zname : "unknown", rrname ? rrname : "unknown");
return true;
} else {
log_zone_error("Zone %s: Cannot process record %s, stopping.\n",
zname ? zname : "unknown", rrname ? rrname : "unknown");
return false;
}
free(zname);
free(rrname);
}
int zone_loader_step(zone_loader_t *zl, knot_rrset_t *rr)
{
assert(zl && rr);
knot_node_t *n = NULL;
if (rr->type == KNOT_RRTYPE_SOA &&
knot_node_rrset(zl->z->apex, KNOT_RRTYPE_SOA)) {
// Ignore extra SOA
knot_rrset_deep_free(&rr, true, NULL);
return KNOT_EOK;
}
int ret = knot_zone_contents_add_rr(zl->z, rr, &n);
if (ret < 0) {
return ret;
if (!handle_err(zl, rr, ret)) {
// Fatal error
return ret;
}
// Recoverable error, returning KNOT_EOK to caller
knot_rrset_deep_free(&rr, true, NULL);
} else if (ret > 0) {
knot_rrset_deep_free(&rr, true, NULL);
}
assert(n);
ret = KNOT_EOK;
bool sem_fatal_error = false;
// ret = sem_check_node_plain(zl->z, n,
// zl->err_handler, true,
// &sem_fatal_error);
err_handler_t err_handler;
err_handler_init(&err_handler);
ret = sem_check_node_plain(zl->z, n,
&err_handler, true,
&sem_fatal_error);
if (ret != KNOT_EOK) {
return ret;
}
......@@ -142,6 +177,49 @@ static void loader_process(const scanner_t *scanner)
}
}
knot_zone_contents_t *create_zone_from_dname(const knot_dname_t *origin,
knot_zone_t *zone)
{
knot_dname_t *owner = knot_dname_copy(origin);
if (owner == NULL) {
return NULL;
}
knot_dname_to_lower(owner);
knot_node_t *apex = knot_node_new(owner, NULL, 0);
if (apex == NULL) {
knot_dname_free(&owner);
return NULL;
}
knot_zone_contents_t *ret = knot_zone_contents_new(apex, zone);
if (ret == NULL) {
knot_node_free(&apex);
}
return ret;
}
knot_zone_t *create_zone_from_name(const char *origin)
{
knot_dname_t *owner = knot_dname_from_str(origin);
if (owner == NULL) {
return NULL;
}
knot_dname_to_lower(owner);
knot_node_t *apex = knot_node_new(owner, NULL, 0);
if (apex == NULL) {
knot_dname_free(&owner);
return NULL;
}
knot_zone_t *ret = knot_zone_new(apex);
if (ret == NULL) {
knot_node_free(&apex);
}
return ret;
}
int knot_zload_open(zloader_t **dst, const char *source, const char *origin_str,
int semantic_checks)
{
......@@ -168,11 +246,11 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin_str,
return KNOT_ENOMEM;
}
/* As it's a first node, no need for compression yet. */
knot_dname_t *origin = knot_dname_from_str(origin_str);
knot_dname_to_lower(origin);
knot_node_t *apex = knot_node_new(origin, NULL, 0);
knot_zone_t *zone = knot_zone_new(apex);
knot_zone_t *zone = create_zone_from_name(origin_str);
if (zone == NULL) {
free(zl);
return KNOT_ENOMEM;
}
zl->z = zone->contents;
zl->ret = KNOT_EOK;
......@@ -198,7 +276,6 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin_str,
zld->semantic_checks = semantic_checks;
*dst = zld;
zld->err_handler = zl->err_handler;
return KNOT_EOK;
}
......@@ -273,8 +350,10 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
} else if (knot_zone_contents_is_signed(loader->context->z) && nsec3param_rr) {
check_level = 3;
}
err_handler_t err_handler;
err_handler_init(&err_handler);
zone_do_sem_checks(c->z, check_level,
loader->err_handler, first_nsec3_node,
&err_handler, first_nsec3_node,
last_nsec3_node);
char *zname = knot_dname_to_str(knot_rrset_owner(soa_rr));
log_zone_info("Semantic checks completed for zone=%s\n", zname);
......@@ -297,6 +376,5 @@ void knot_zload_close(zloader_t *loader)
free(loader->source);
free(loader->origin);
free(loader->context);
free(loader->err_handler);
free(loader);
}
......@@ -47,8 +47,8 @@ typedef struct parser_context parser_context_t;
typedef struct zone_loader {
knot_zone_contents_t *z;
err_handler_t *err_handler;
hattrie_t *lookup_tree;
knot_node_t *last_node;
int ret;
} zone_loader_t;
......@@ -95,6 +95,12 @@ knot_zone_t *knot_zload_load(zloader_t *loader);
*/
void knot_zload_close(zloader_t *loader);
knot_zone_contents_t *create_zone_from_dname(const knot_dname_t *origin,
knot_zone_t *zone);
knot_zone_t *create_zone_from_name(const char *origin);
int zone_loader_step(zone_loader_t *zl, knot_rrset_t *rr);
void process_error(const scanner_t *scanner);
#endif /* _KNOTD_ZONELOAD_H_ */
......
......@@ -504,7 +504,7 @@ int knot_pkt_put(knot_pkt_t *pkt, uint16_t compr_hint, const knot_rrset_t *rr, c
rrinfo->pos = pkt->size;
rrinfo->flags = flags;
rrinfo->compress_ptr[0] = compr_hint;
rrinfo->rrsigs = rrsigs;
rrinfo->rrsigs = rr->type != KNOT_RRTYPE_RRSIG ? rrsigs : NULL;
pkt->rr[pkt->rrset_count] = rr;
/* Check for double insertion. */
......
......@@ -1842,7 +1842,7 @@ static int knot_rrset_rdata_reset(knot_rrset_t *rrset)
}
int knot_rrset_add_rr_from_rrset(knot_rrset_t *dest, const knot_rrset_t *source,
size_t rdata_pos)
size_t rdata_pos, mm_ctx_t *mm)
{
if (dest == NULL || source == NULL ||
rdata_pos >= source->rdata_count) {
......@@ -1852,7 +1852,7 @@ int knot_rrset_add_rr_from_rrset(knot_rrset_t *dest, const knot_rrset_t *source,
/* Get size of RDATA to be copied. */
uint16_t item_size = rrset_rdata_item_size(source, rdata_pos);
/* Reserve space in dest RRSet. */
uint8_t *rdata = knot_rrset_create_rdata(dest, item_size, NULL);
uint8_t *rdata = knot_rrset_create_rdata(dest, item_size, mm);
if (rdata == NULL) {
dbg_rrset("rr: add_rr_from_rrset: Could not create RDATA.\n");
return KNOT_ERROR;
......@@ -1886,7 +1886,7 @@ int knot_rrset_remove_rr_using_rrset(knot_rrset_t *from,
ret = knot_rrset_remove_rr(from, what, i);
if (ret == KNOT_EOK) {
/* RR was removed, can be added to 'return' RRSet. */
ret = knot_rrset_add_rr_from_rrset(return_rr, what, i);
ret = knot_rrset_add_rr_from_rrset(return_rr, what, i, NULL);
if (ret != KNOT_EOK) {
knot_rrset_deep_free(&return_rr, 0, NULL);
dbg_xfrin("xfr: Could not add RR (%s).\n",
......@@ -1957,14 +1957,14 @@ int rrset_additional_needed(uint16_t rrtype)
}
static int add_rdata_to_rrsig(knot_rrset_t *new_sig, uint16_t type,
const knot_rrset_t *rrsigs)
const knot_rrset_t *rrsigs, mm_ctx_t *mm)
{
for (size_t i = 0; i < rrsigs->rdata_count; ++i) {
const uint16_t type_covered =
knot_rdata_rrsig_type_covered(rrsigs, i);
if (type_covered == type) {
int ret = knot_rrset_add_rr_from_rrset(new_sig,
rrsigs, i);
rrsigs, i, mm);
if (ret != KNOT_EOK) {
return ret;
}
......@@ -1991,7 +1991,7 @@ int knot_rrset_synth_rrsig(const knot_rrset_t *covered, const knot_rrset_t *rrsi
}
(*out_sig)->type = KNOT_RRTYPE_RRSIG;
int ret = add_rdata_to_rrsig(*out_sig, covered->type, rrsigs);
int ret = add_rdata_to_rrsig(*out_sig, covered->type, rrsigs, mm);
if (ret != KNOT_EOK) {
knot_rrset_deep_free(out_sig, 1, mm);
return ret;
......
......@@ -410,7 +410,7 @@ int rrset_deserialize(uint8_t *stream, size_t *stream_size,
/* \brief Adds RR on 'pos' position from 'source' to 'dest' */
int knot_rrset_add_rr_from_rrset(knot_rrset_t *dest, const knot_rrset_t *source,
size_t rdata_pos);
size_t rdata_pos, mm_ctx_t *mm);
/* \brief Removes RRs contained in 'what' RRSet from 'from' RRSet.
* Deleted RRs are returned in 'rr_deleted' */
int knot_rrset_remove_rr_using_rrset(knot_rrset_t *from,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment