Commit 3b0faffd authored by Vitezslav Kriz's avatar Vitezslav Kriz

zone-size-limit: change ixfr limit, move measure function

parent 06318a8c
...@@ -328,7 +328,7 @@ static int axfr_answer_finalize(struct answer_data *adata) ...@@ -328,7 +328,7 @@ static int axfr_answer_finalize(struct answer_data *adata)
int64_t size_limit = conf_int(&val); int64_t size_limit = conf_int(&val);
if (proc->contents->size > size_limit) { if (proc->contents->size > size_limit) {
AXFRIN_LOG(LOG_WARNING, "zone size exceeded, limit %ld", size_limit); AXFRIN_LOG(LOG_WARNING, "zone size exceeded");
return KNOT_STATE_FAIL; return KNOT_STATE_FAIL;
} }
...@@ -393,9 +393,7 @@ static int axfr_answer_packet(knot_pkt_t *pkt, struct answer_data *adata) ...@@ -393,9 +393,7 @@ static int axfr_answer_packet(knot_pkt_t *pkt, struct answer_data *adata)
} }
proc->contents->size += knot_rrset_size(&answer_rr[i]); proc->contents->size += knot_rrset_size(&answer_rr[i]);
if (proc->contents->size > size_limit) { if (proc->contents->size > size_limit) {
log_zone_warning(proc->contents->apex->owner, AXFRIN_LOG(LOG_WARNING, "zone size exceeded");
"AXFR, incoming, zone size exceeded, "
"limit %ld", size_limit);
return KNOT_STATE_FAIL; return KNOT_STATE_FAIL;
} }
} }
......
...@@ -50,8 +50,7 @@ struct ixfr_proc { ...@@ -50,8 +50,7 @@ struct ixfr_proc {
knot_rrset_t *final_soa; /* First SOA received via IXFR. */ knot_rrset_t *final_soa; /* First SOA received via IXFR. */
list_t changesets; /* Processed changesets. */ list_t changesets; /* Processed changesets. */
size_t change_count; /* Count of changesets received. */ size_t change_count; /* Count of changesets received. */
size_t add_size; /* Size of records to add */ size_t change_size; /* Size of records to add and remove */
size_t del_size; /* Size of records to remove */
zone_t *zone; /* Modified zone - for journal access. */ zone_t *zone; /* Modified zone - for journal access. */
knot_mm_t *mm; /* Memory context for RR allocations. */ knot_mm_t *mm; /* Memory context for RR allocations. */
struct query_data *qdata; struct query_data *qdata;
...@@ -364,10 +363,6 @@ static int ixfrin_answer_init(struct answer_data *data) ...@@ -364,10 +363,6 @@ static int ixfrin_answer_init(struct answer_data *data)
data->ext = proc; data->ext = proc;
data->ext_cleanup = &ixfrin_cleanup; data->ext_cleanup = &ixfrin_cleanup;
/// \TODO Temporary solution, because not every zone input is checked by
/// semantic checks. And zone size is not set properly.
zone_contents_measure_size(proc->zone->contents);
return KNOT_EOK; return KNOT_EOK;
} }
...@@ -404,8 +399,8 @@ static int ixfrin_finalize(struct answer_data *adata) ...@@ -404,8 +399,8 @@ static int ixfrin_finalize(struct answer_data *adata)
ixfr->zone->name); ixfr->zone->name);
const int64_t size_limit = conf_int(&val); const int64_t size_limit = conf_int(&val);
if (new_contents->size > size_limit) { // secondary check if (new_contents->size > size_limit) {
IXFRIN_LOG(LOG_WARNING, "zone size exceeded, limit %ld", size_limit); IXFRIN_LOG(LOG_WARNING, "zone size exceeded");
update_rollback(&a_ctx); update_rollback(&a_ctx);
update_free_zone(&new_contents); update_free_zone(&new_contents);
return KNOT_STATE_FAIL; return KNOT_STATE_FAIL;
...@@ -566,33 +561,25 @@ static int ixfrin_step(const knot_rrset_t *rr, struct ixfr_proc *proc) ...@@ -566,33 +561,25 @@ static int ixfrin_step(const knot_rrset_t *rr, struct ixfr_proc *proc)
return solve_start(rr, proc); return solve_start(rr, proc);
case IXFR_SOA_DEL: case IXFR_SOA_DEL:
ret = solve_soa_del(rr, proc); ret = solve_soa_del(rr, proc);
if (ret == KNOT_EOK) { break;
proc->del_size += knot_rrset_size(rr);
}
return ret;
case IXFR_DEL: case IXFR_DEL:
ret = solve_del(rr, change, proc->mm); ret = solve_del(rr, change, proc->mm);
if (ret == KNOT_EOK) { break;
proc->del_size += knot_rrset_size(rr);
}
return ret;
case IXFR_SOA_ADD: case IXFR_SOA_ADD:
ret = solve_soa_add(rr, change, proc->mm); ret = solve_soa_add(rr, change, proc->mm);
if (ret == KNOT_EOK) { break;
proc->add_size += knot_rrset_size(rr);
}
return ret;
case IXFR_ADD: case IXFR_ADD:
ret = solve_add(rr, change, proc->mm); ret = solve_add(rr, change, proc->mm);
if (ret == KNOT_EOK) { break;
proc->add_size += knot_rrset_size(rr);
}
return ret;
case IXFR_DONE: case IXFR_DONE:
return KNOT_EOK; return KNOT_EOK;
default: default:
return KNOT_ERROR; return KNOT_ERROR;
} }
if (ret == KNOT_EOK) {
proc->change_size += knot_rrset_size(rr);
}
return ret;
} }
/*! \brief Checks whether journal node limit has not been exceeded. */ /*! \brief Checks whether journal node limit has not been exceeded. */
...@@ -626,7 +613,6 @@ static int process_ixfrin_packet(knot_pkt_t *pkt, struct answer_data *adata) ...@@ -626,7 +613,6 @@ static int process_ixfrin_packet(knot_pkt_t *pkt, struct answer_data *adata)
conf_val_t val = conf_zone_get(adata->param->conf, C_MAX_ZONE_SIZE, conf_val_t val = conf_zone_get(adata->param->conf, C_MAX_ZONE_SIZE,
ixfr->zone->name); ixfr->zone->name);
const int64_t size_limit = conf_int(&val); const int64_t size_limit = conf_int(&val);
const size_t zone_size = ixfr->zone->contents->size;
// Process RRs in the message. // Process RRs in the message.
const knot_pktsection_t *answer = knot_pkt_section(pkt, KNOT_ANSWER); const knot_pktsection_t *answer = knot_pkt_section(pkt, KNOT_ANSWER);
...@@ -652,17 +638,10 @@ static int process_ixfrin_packet(knot_pkt_t *pkt, struct answer_data *adata) ...@@ -652,17 +638,10 @@ static int process_ixfrin_packet(knot_pkt_t *pkt, struct answer_data *adata)
return KNOT_STATE_DONE; return KNOT_STATE_DONE;
} }
if (ixfr->add_size + ixfr->del_size > 2 * size_limit) { if (ixfr->change_size > 2 * size_limit) {
IXFRIN_LOG(LOG_WARNING, "transfer size exceeded, limit %ld", IXFRIN_LOG(LOG_WARNING, "transfer size exceeded");
2 * size_limit);
} }
if (ixfr->add_size > ixfr->del_size &&
(zone_size + ixfr->add_size - ixfr->del_size) > size_limit) {
IXFRIN_LOG(LOG_WARNING, "zone size exceeded, limit %ld",
size_limit);
return KNOT_STATE_FAIL;
}
} }
return KNOT_STATE_CONSUME; return KNOT_STATE_CONSUME;
......
...@@ -220,6 +220,17 @@ static int adjust_nsec3_pointers(zone_node_t **tnode, void *data) ...@@ -220,6 +220,17 @@ static int adjust_nsec3_pointers(zone_node_t **tnode, void *data)
return ret; return ret;
} }
static int measure_size(zone_node_t *node, void *data){
size_t *size = data;
int rrset_count = node->rrset_count;
for (int i = 0; i < rrset_count; i++) {
knot_rrset_t rrset = node_rrset_at(node, i);
*size += knot_rrset_size(&rrset);
}
return KNOT_EOK;
}
/*! /*!
* \brief Adjust normal (non NSEC3) node. * \brief Adjust normal (non NSEC3) node.
* *
...@@ -243,6 +254,8 @@ static int adjust_normal_node(zone_node_t **tnode, void *data) ...@@ -243,6 +254,8 @@ static int adjust_normal_node(zone_node_t **tnode, void *data)
return ret; return ret;
} }
measure_size(*tnode, &((zone_adjust_arg_t *)data)->zone->size);
// Connect nodes to their NSEC3 nodes // Connect nodes to their NSEC3 nodes
return adjust_nsec3_pointers(tnode, data); return adjust_nsec3_pointers(tnode, data);
} }
...@@ -274,6 +287,8 @@ static int adjust_nsec3_node(zone_node_t **tnode, void *data) ...@@ -274,6 +287,8 @@ static int adjust_nsec3_node(zone_node_t **tnode, void *data)
node->prev = args->previous_node; node->prev = args->previous_node;
args->previous_node = node; args->previous_node = node;
measure_size(*tnode, &args->zone->size);
return KNOT_EOK; return KNOT_EOK;
} }
...@@ -980,6 +995,8 @@ static int contents_adjust(zone_contents_t *contents, bool normal) ...@@ -980,6 +995,8 @@ static int contents_adjust(zone_contents_t *contents, bool normal)
.zone = contents .zone = contents
}; };
contents->size = 0;
ret = adjust_nodes(contents->nodes, &arg, ret = adjust_nodes(contents->nodes, &arg,
normal ? adjust_normal_node : adjust_pointers); normal ? adjust_normal_node : adjust_pointers);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
...@@ -1130,17 +1147,6 @@ bool zone_contents_is_empty(const zone_contents_t *zone) ...@@ -1130,17 +1147,6 @@ bool zone_contents_is_empty(const zone_contents_t *zone)
return !zone || !node_rrtype_exists(zone->apex, KNOT_RRTYPE_SOA); return !zone || !node_rrtype_exists(zone->apex, KNOT_RRTYPE_SOA);
} }
static int measure_size(zone_node_t *node, void *data){
size_t *size = data;
int rrset_count = node->rrset_count;
for (int i = 0; i < rrset_count; i++) {
knot_rrset_t rrset = node_rrset_at(node, i);
*size += knot_rrset_size(&rrset);
}
return KNOT_EOK;
}
size_t zone_contents_measure_size(zone_contents_t *zone) size_t zone_contents_measure_size(zone_contents_t *zone)
{ {
zone->size = 0; zone->size = 0;
......
...@@ -144,7 +144,6 @@ static int check_rrsig(const zone_node_t *node, semchecks_data_t *data); ...@@ -144,7 +144,6 @@ static int check_rrsig(const zone_node_t *node, semchecks_data_t *data);
static int check_signed_rrsig(const zone_node_t *node, semchecks_data_t *data); static int check_signed_rrsig(const zone_node_t *node, semchecks_data_t *data);
static int check_nsec_bitmap(const zone_node_t *node, semchecks_data_t *data); static int check_nsec_bitmap(const zone_node_t *node, semchecks_data_t *data);
static int check_nsec3_presence(const zone_node_t *node, semchecks_data_t *data); static int check_nsec3_presence(const zone_node_t *node, semchecks_data_t *data);
static int measure_size(const zone_node_t *node, semchecks_data_t *data);
struct check_function { struct check_function {
int (*function)(const zone_node_t *, semchecks_data_t *); int (*function)(const zone_node_t *, semchecks_data_t *);
...@@ -163,29 +162,11 @@ static const struct check_function CHECK_FUNCTIONS[] = { ...@@ -163,29 +162,11 @@ static const struct check_function CHECK_FUNCTIONS[] = {
{check_nsec3_presence, NSEC3}, {check_nsec3_presence, NSEC3},
{check_nsec3_opt_out, NSEC3}, {check_nsec3_opt_out, NSEC3},
{check_nsec_bitmap, NSEC | NSEC3}, {check_nsec_bitmap, NSEC | NSEC3},
{measure_size, MANDATORY}
}; };
static const int CHECK_FUNCTIONS_LEN = sizeof(CHECK_FUNCTIONS) static const int CHECK_FUNCTIONS_LEN = sizeof(CHECK_FUNCTIONS)
/ sizeof(struct check_function); / sizeof(struct check_function);
/*!
* \biref Measure size of zone
*
* Not actual semantic check, but measure size of zone.
* Zone size is saved into zone_contents structure.
*/
static int measure_size(const zone_node_t *node, semchecks_data_t *data){
int rrset_count = node->rrset_count;
for (int i = 0; i < rrset_count; i++) {
knot_rrset_t rrset = node_rrset_at(node, i);
data->zone->size += knot_rrset_size(&rrset);
}
return KNOT_EOK;
}
/*! /*!
* \brief Check whether DNSKEY rdata are valid. * \brief Check whether DNSKEY rdata are valid.
* *
......
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