Commit d715ef2f authored by Jan Kadlec's avatar Jan Kadlec

zone API: changeset+zone combo for DDNS prereqs

parent 4b154079
......@@ -22,6 +22,7 @@
#include "common/debug.h"
#include "knot/dnssec/zone-events.h"
#include "knot/updates/ddns.h"
#include "knot/updates/zone-update.h"
#include "libknot/descriptor.h"
#include "libknot/tsig-op.h"
#include "knot/zone/zone.h"
......@@ -136,18 +137,18 @@ static int sign_update(zone_t *zone, const zone_contents_t *old_contents,
return KNOT_EOK;
}
static int process_single_update(struct request_data *request, const zone_t *zone,
changeset_t *ch)
static int process_single_update(struct request_data *request,
const zone_t *zone, zone_update_t *update)
{
uint16_t rcode = KNOT_RCODE_NOERROR;
int ret = ddns_process_prereqs(request->query, zone->contents, &rcode);
int ret = ddns_process_prereqs(request->query, update, &rcode);
if (ret != KNOT_EOK) {
assert(rcode != KNOT_RCODE_NOERROR);
knot_wire_set_rcode(request->resp->wire, rcode);
return ret;
}
ret = ddns_process_update(zone, request->query, ch, &rcode);
ret = ddns_process_update(zone, request->query, update, &rcode);
if (ret != KNOT_EOK) {
assert(rcode != KNOT_RCODE_NOERROR);
knot_wire_set_rcode(request->resp->wire, rcode);
......@@ -178,10 +179,14 @@ static int process_normal(zone_t *zone, list_t *queries)
set_rcodes(queries, KNOT_RCODE_SERVFAIL);
return ret;
}
// Init zone update structure
zone_update_t zone_update;
zone_update_init(&zone_update, zone->contents, &ddns_ch);
struct request_data *query;
WALK_LIST(query, *queries) {
ret = process_single_update(query, zone, &ddns_ch);
ret = process_single_update(query, zone, &zone_update);
if (ret != KNOT_EOK) {
changeset_clear(&ddns_ch);
set_rcodes(queries, KNOT_RCODE_SERVFAIL);
......
......@@ -20,6 +20,7 @@
#include "knot/updates/ddns.h"
#include "knot/updates/changesets.h"
#include "knot/updates/zone-update.h"
#include "libknot/packet/pkt.h"
#include "libknot/common.h"
#include "libknot/consts.h"
......@@ -62,12 +63,12 @@ static int add_rr_to_list(list_t *l, const knot_rrset_t *rr)
}
/*!< \brief Checks whether RRSet exists in the zone. */
static int check_rrset_exists(const zone_contents_t *zone,
static int check_rrset_exists(zone_update_t *update,
const knot_rrset_t *rrset, uint16_t *rcode)
{
assert(rrset->type != KNOT_RRTYPE_ANY);
const zone_node_t *node = zone_contents_find_node(zone, rrset->owner);
const zone_node_t *node = zone_update_get_node(update, rrset->owner);
if (node == NULL || !node_rrtype_exists(node, rrset->type)) {
*rcode = KNOT_RCODE_NXRRSET;
return KNOT_EPREREQ;
......@@ -84,14 +85,14 @@ static int check_rrset_exists(const zone_contents_t *zone,
}
/*!< \brief Checks whether RRSets in the list exist in the zone. */
static int check_stored_rrsets(list_t *l, const zone_contents_t *zone,
static int check_stored_rrsets(list_t *l, zone_update_t *update,
uint16_t *rcode)
{
node_t *n;
WALK_LIST(n, *l) {
ptrnode_t *ptr_n = (ptrnode_t *)n;
knot_rrset_t *rrset = (knot_rrset_t *)ptr_n->d;
int ret = check_rrset_exists(zone, rrset, rcode);
int ret = check_rrset_exists(update, rrset, rcode);
if (ret != KNOT_EOK) {
return ret;
}
......@@ -101,10 +102,10 @@ static int check_stored_rrsets(list_t *l, const zone_contents_t *zone,
}
/*!< \brief Checks whether node of given owner, with given type exists. */
static bool check_type(const zone_contents_t *zone, const knot_rrset_t *rrset)
static bool check_type(zone_update_t *update, const knot_rrset_t *rrset)
{
assert(rrset->type != KNOT_RRTYPE_ANY);
const zone_node_t *node = zone_contents_find_node(zone, rrset->owner);
const zone_node_t *node = zone_update_get_node(update, rrset->owner);
if (node == NULL || !node_rrtype_exists(node, rrset->type)) {
return false;
}
......@@ -113,11 +114,11 @@ static bool check_type(const zone_contents_t *zone, const knot_rrset_t *rrset)
}
/*!< \brief Checks whether RR type exists in the zone. */
static int check_type_exist(const zone_contents_t *zone,
static int check_type_exist(zone_update_t *update,
const knot_rrset_t *rrset, uint16_t *rcode)
{
assert(rrset->rclass == KNOT_CLASS_ANY);
if (check_type(zone, rrset)) {
if (check_type(update, rrset)) {
return KNOT_EOK;
} else {
*rcode = KNOT_RCODE_NXRRSET;
......@@ -126,11 +127,11 @@ static int check_type_exist(const zone_contents_t *zone,
}
/*!< \brief Checks whether RR type is not in the zone. */
static int check_type_not_exist(const zone_contents_t *zone,
static int check_type_not_exist(zone_update_t *update,
const knot_rrset_t *rrset, uint16_t *rcode)
{
assert(rrset->rclass == KNOT_CLASS_NONE);
if (check_type(zone, rrset)) {
if (check_type(update, rrset)) {
*rcode = KNOT_RCODE_YXRRSET;
return KNOT_EPREREQ;
} else {
......@@ -139,10 +140,10 @@ static int check_type_not_exist(const zone_contents_t *zone,
}
/*!< \brief Checks whether DNAME is in the zone. */
static int check_in_use(const zone_contents_t *zone,
static int check_in_use(zone_update_t *update,
const knot_dname_t *dname, uint16_t *rcode)
{
const zone_node_t *node = zone_contents_find_node(zone, dname);
const zone_node_t *node = zone_update_get_node(update, dname);
if (node == NULL || node->rrset_count == 0) {
*rcode = KNOT_RCODE_NXDOMAIN;
return KNOT_EPREREQ;
......@@ -152,10 +153,10 @@ static int check_in_use(const zone_contents_t *zone,
}
/*!< \brief Checks whether DNAME is not in the zone. */
static int check_not_in_use(const zone_contents_t *zone,
static int check_not_in_use(zone_update_t *update,
const knot_dname_t *dname, uint16_t *rcode)
{
const zone_node_t *node = zone_contents_find_node(zone, dname);
const zone_node_t *node = zone_update_get_node(update, dname);
if (node == NULL || node->rrset_count == 0) {
return KNOT_EOK;
} else {
......@@ -180,7 +181,7 @@ static bool rrset_empty(const knot_rrset_t *rrset)
/*!< \brief Checks prereq for given packet RR. */
static int process_prereq(const knot_rrset_t *rrset, uint16_t qclass,
const zone_contents_t *zone, uint16_t *rcode,
zone_update_t *update, uint16_t *rcode,
list_t *rrset_list)
{
if (knot_rdata_ttl(knot_rdataset_at(&rrset->rrs, 0)) != 0) {
......@@ -188,7 +189,7 @@ static int process_prereq(const knot_rrset_t *rrset, uint16_t qclass,
return KNOT_EMALF;
}
if (!knot_dname_is_sub(rrset->owner, zone->apex->owner)) {
if (!knot_dname_is_sub(rrset->owner, update->zone->apex->owner)) {
*rcode = KNOT_RCODE_NOTZONE;
return KNOT_EOUTOFZONE;
}
......@@ -199,9 +200,9 @@ static int process_prereq(const knot_rrset_t *rrset, uint16_t qclass,
return KNOT_EMALF;
}
if (rrset->type == KNOT_RRTYPE_ANY) {
return check_in_use(zone, rrset->owner, rcode);
return check_in_use(update, rrset->owner, rcode);
} else {
return check_type_exist(zone, rrset, rcode);
return check_type_exist(update, rrset, rcode);
}
} else if (rrset->rclass == KNOT_CLASS_NONE) {
if (!rrset_empty(rrset)) {
......@@ -209,9 +210,9 @@ static int process_prereq(const knot_rrset_t *rrset, uint16_t qclass,
return KNOT_EMALF;
}
if (rrset->type == KNOT_RRTYPE_ANY) {
return check_not_in_use(zone, rrset->owner, rcode);
return check_not_in_use(update, rrset->owner, rcode);
} else {
return check_type_not_exist(zone, rrset, rcode);
return check_type_not_exist(update, rrset, rcode);
}
} else if (rrset->rclass == qclass) {
// Store RRs for full check into list
......@@ -882,10 +883,10 @@ static uint16_t ret_to_rcode(int ret)
/* ---------------------------------- API ----------------------------------- */
int ddns_process_prereqs(const knot_pkt_t *query, const zone_contents_t *zone,
int ddns_process_prereqs(const knot_pkt_t *query, zone_update_t *update,
uint16_t *rcode)
{
if (query == NULL || rcode == NULL || zone == NULL) {
if (query == NULL || rcode == NULL || update == NULL) {
return KNOT_EINVAL;
}
......@@ -897,7 +898,7 @@ int ddns_process_prereqs(const knot_pkt_t *query, const zone_contents_t *zone,
for (int i = 0; i < answer->count; ++i) {
// Check what can be checked, store full RRs into list
ret = process_prereq(&answer->rr[i], knot_pkt_qclass(query),
zone, rcode, &rrset_list);
update, rcode, &rrset_list);
if (ret != KNOT_EOK) {
rrset_list_clear(&rrset_list);
return ret;
......@@ -905,20 +906,22 @@ int ddns_process_prereqs(const knot_pkt_t *query, const zone_contents_t *zone,
}
// Check stored RRSets
ret = check_stored_rrsets(&rrset_list, zone, rcode);
ret = check_stored_rrsets(&rrset_list, update, rcode);
rrset_list_clear(&rrset_list);
return ret;
}
int ddns_process_update(const zone_t *zone, const knot_pkt_t *query,
changeset_t *changeset, uint16_t *rcode)
zone_update_t *update, uint16_t *rcode)
{
if (zone == NULL || query == NULL || changeset == NULL || rcode == NULL) {
if (zone == NULL || query == NULL || update == NULL || rcode == NULL) {
if (rcode) {
*rcode = ret_to_rcode(KNOT_EINVAL);
}
return KNOT_EINVAL;
}
changeset_t *changeset = update->change;
if (changeset->soa_from == NULL) {
// Copy base SOA RR.
......
......@@ -28,6 +28,7 @@
#pragma once
#include "knot/updates/changesets.h"
#include "knot/updates/zone-update.h"
#include "knot/zone/zone.h"
#include "libknot/packet/pkt.h"
#include "libknot/dname.h"
......@@ -41,7 +42,7 @@
*
* \return KNOT_E*
*/
int ddns_process_prereqs(const knot_pkt_t *query, const zone_contents_t *zone,
int ddns_process_prereqs(const knot_pkt_t *query, zone_update_t *update,
uint16_t *rcode);
/*!
......@@ -56,6 +57,6 @@ int ddns_process_prereqs(const knot_pkt_t *query, const zone_contents_t *zone,
* \return KNOT_E*
*/
int ddns_process_update(const zone_t *zone, const knot_pkt_t *query,
changeset_t *changeset, uint16_t *rcode);
zone_update_t *update, uint16_t *rcode);
/*! @} */
......@@ -32,7 +32,7 @@
typedef struct {
const zone_contents_t *zone;
const changeset_t *change;
changeset_t *change;
mm_ctx_t mm;
} zone_update_t;
......
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