Commit cba78c8b authored by Marek Vavrusa's avatar Marek Vavrusa

API support for AXFR, IXFR, UPDATE processing.

IXFR SOA response implemented.
parent 03d0304a
......@@ -168,6 +168,12 @@ src/libknot/nameserver/chaos.c
src/libknot/nameserver/chaos.h
src/libknot/nameserver/internet.c
src/libknot/nameserver/internet.h
src/libknot/nameserver/axfr.c
src/libknot/nameserver/axfr.h
src/libknot/nameserver/ixfr.c
src/libknot/nameserver/ixfr.h
src/libknot/nameserver/update.c
src/libknot/nameserver/update.h
src/libknot/nameserver/name-server.c
src/libknot/nameserver/name-server.h
src/libknot/nameserver/ns_proc_query.c
......
......@@ -124,6 +124,12 @@ libknot_la_SOURCES = \
libknot/nameserver/chaos.c \
libknot/nameserver/internet.h \
libknot/nameserver/internet.c \
libknot/nameserver/axfr.h \
libknot/nameserver/axfr.c \
libknot/nameserver/ixfr.h \
libknot/nameserver/ixfr.c \
libknot/nameserver/update.h \
libknot/nameserver/update.c \
libknot/nameserver/ns_proc_query.h \
libknot/nameserver/ns_proc_query.c \
libknot/updates/changesets.h \
......
#include <config.h>
#include "libknot/nameserver/axfr.h"
#include "libknot/nameserver/ns_proc_query.h"
int axfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata)
{
qdata->rcode = KNOT_RCODE_NOTIMPL;
return NS_PROC_FAIL;
}
/*!
* \file axfr.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
* \brief AXFR processing.
*
* \addtogroup query_processing
* @{
*/
/* Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KNOT_AXFR_H_
#define _KNOT_AXFR_H_
#include "libknot/packet/pkt.h"
#include "libknot/zone/zonedb.h"
#include "libknot/nameserver/name-server.h"
struct query_data;
int axfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata);
#endif /* _KNOT_AXFR_H_ */
/*! @} */
/*!
* \file internet.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
* \brief IN zone lookup.
*
* \addtogroup query_processing
* @{
*/
/* Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KNOT_INTERNET_H_
#define _KNOT_INTERNET_H_
#include "libknot/packet/pkt.h"
#include "libknot/zone/zonedb.h"
#include "libknot/nameserver/name-server.h"
/* Query data (from query processing). */
struct query_data;
/*!
* \brief Answer query from IN class zone.
*/
int internet_answer(knot_pkt_t *resp, struct query_data *qdata);
/*!
* \brief Answer IN class zone NOTIFY message (RFC1996).
* \param response
* \param ns
* \param qdata
* \return
*/
int internet_notify(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata);
#endif /* _KNOT_INTERNET_H_ */
/*! @} */
#include <config.h>
#include "libknot/nameserver/ixfr.h"
#include "libknot/nameserver/ns_proc_query.h"
#include "common/descriptor.h"
int ixfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata)
{
qdata->rcode = KNOT_RCODE_NOTIMPL;
return NS_PROC_FAIL;
}
int ixfr_answer_soa(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata)
{
if (pkt == NULL || ns == NULL || qdata == NULL) {
return NS_PROC_FAIL;
}
/* Check zone state. */
const knot_zone_t *zone = pkt->zone;
switch(knot_zone_state(zone)) {
case KNOT_EOK:
break;
case KNOT_ENOENT:
qdata->rcode = KNOT_RCODE_NOTAUTH;
return NS_PROC_FAIL;
default:
qdata->rcode = KNOT_RCODE_SERVFAIL;
return NS_PROC_FAIL;
}
/* Guaranteed to have zone contents. */
const knot_node_t *apex = zone->contents->apex;
const knot_rrset_t *soa_rr = knot_node_rrset(apex, KNOT_RRTYPE_SOA);
int ret = knot_pkt_put(pkt, 0, soa_rr, 0);
if (ret != KNOT_EOK) {
qdata->rcode = KNOT_RCODE_SERVFAIL;
return NS_PROC_FAIL;
}
return NS_PROC_FINISH;
}
/*!
* \file ixfr.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
* \brief IXFR processing.
*
* \addtogroup query_processing
* @{
*/
/* Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KNOT_IXFR_H_
#define _KNOT_IXFR_H_
#include "libknot/packet/pkt.h"
#include "libknot/zone/zonedb.h"
#include "libknot/nameserver/name-server.h"
struct query_data;
int ixfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata);
int ixfr_answer_soa(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata);
#endif /* _KNOT_IXFR_H_ */
/*! @} */
......@@ -4110,6 +4110,8 @@ int ns_proc_begin(ns_proc_context_t *ctx, const ns_proc_module_t *module)
/* #10 implement */
ctx->module = module;
ctx->state = module->begin(ctx);
dbg_ns("%s -> %d\n", __func__, ctx->state);
return ctx->state;
}
......@@ -4117,6 +4119,8 @@ int ns_proc_reset(ns_proc_context_t *ctx)
{
/* #10 implement */
ctx->state = ctx->module->reset(ctx);
dbg_ns("%s -> %d\n", __func__, ctx->state);
return ctx->state;
}
......@@ -4124,13 +4128,25 @@ int ns_proc_finish(ns_proc_context_t *ctx)
{
/* #10 implement */
ctx->state = ctx->module->finish(ctx);
/* Free packet buffers. */
knot_pkt_free(&ctx->in);
knot_pkt_free(&ctx->out);
dbg_ns("%s -> %d\n", __func__, ctx->state);
return ctx->state;
}
int ns_proc_in(const uint8_t *wire, uint16_t wire_len, ns_proc_context_t *ctx)
{
/* #10 implement */
knot_pkt_t *pkt = knot_pkt_new((uint8_t *)wire, wire_len, &ctx->mm);
if (ctx->in == NULL) {
ctx->in = knot_pkt_new((uint8_t *)wire, wire_len, &ctx->mm);
} else {
knot_pkt_reset(ctx->in, (uint8_t *)wire, wire_len);
}
knot_pkt_t *pkt = ctx->in;
knot_pkt_parse(pkt, 0);
switch(ctx->state) {
......@@ -4140,13 +4156,20 @@ int ns_proc_in(const uint8_t *wire, uint16_t wire_len, ns_proc_context_t *ctx)
return NS_PROC_NOOP;
}
dbg_ns("%s -> %d\n", __func__, ctx->state);
return ctx->state;
}
int ns_proc_out(uint8_t *wire, uint16_t *wire_len, ns_proc_context_t *ctx)
{
/* #10 implement */
knot_pkt_t *pkt = knot_pkt_new(wire, *wire_len, &ctx->mm);
if (ctx->out == NULL) {
ctx->out = knot_pkt_new(wire, *wire_len, &ctx->mm);
} else {
knot_pkt_reset(ctx->out, wire, *wire_len);
}
knot_pkt_t *pkt = ctx->out;
switch(ctx->state) {
case NS_PROC_FULL: ctx->state = ctx->module->out(pkt, ctx); break;
......@@ -4158,9 +4181,7 @@ int ns_proc_out(uint8_t *wire, uint16_t *wire_len, ns_proc_context_t *ctx)
*wire_len = pkt->size;
/* Free packet. */
knot_pkt_free(&pkt);
dbg_ns("%s -> %d\n", __func__, ctx->state);
return ctx->state;
}
......
......@@ -448,8 +448,10 @@ enum ns_proc_state {
};
enum ns_proc_flag {
NS_NOFLAG = 0,
/* Common flags. */
NS_PKTSIZE_NOLIMIT = 1 << 0, /* Don't limit packet size (for TCP). */
/* Module-specific flags. */
NS_PROCFLAG = 1 << 8
};
struct ns_proc_module;
......@@ -460,6 +462,7 @@ typedef struct ns_proc_context
uint16_t type;
uint16_t flags;
void *data;
knot_pkt_t *in, *out;
int state;
knot_nameserver_t *ns;
......
......@@ -5,11 +5,16 @@
#include "libknot/nameserver/ns_proc_query.h"
#include "libknot/consts.h"
#include "libknot/util/debug.h"
#include "libknot/nameserver/chaos.h"
#include "libknot/nameserver/internet.h"
#include "libknot/common.h"
#include "common/descriptor.h"
/*! \todo Move close to server when done. */
#include "libknot/nameserver/chaos.h"
#include "libknot/nameserver/internet.h"
#include "libknot/nameserver/axfr.h"
#include "libknot/nameserver/ixfr.h"
#include "libknot/nameserver/update.h"
/* Forward decls. */
static int tsig_check(knot_pkt_t *pkt);
static const knot_zone_t *answer_zone_find(knot_pkt_t *pkt, knot_zonedb_t *zonedb);
......@@ -52,7 +57,7 @@ int ns_proc_query_reset(ns_proc_context_t *ctx)
/* Clear */
assert(ctx);
struct query_data *data = QUERY_DATA(ctx);
knot_pkt_free(&data->pkt);
data->pkt = NULL;
data->rcode = KNOT_RCODE_NOERROR;
data->rcode_tsig = 0;
data->node = data->encloser = data->previous = NULL;
......@@ -81,9 +86,12 @@ int ns_proc_query_in(knot_pkt_t *pkt, ns_proc_context_t *ctx)
switch(query_type) {
case KNOT_QUERY_NORMAL:
case KNOT_QUERY_NOTIFY:
case KNOT_QUERY_AXFR:
case KNOT_QUERY_IXFR:
case KNOT_QUERY_UPDATE:
break; /* Supported. */
default:
dbg_ns("%s: query_type(%hu) NOT SUPPORTED", __func__, query_type);
dbg_ns("%s: query_type(%hu) NOT SUPPORTED\n", __func__, query_type);
return NS_PROC_NOOP; /* Refuse to process. */
}
......@@ -187,6 +195,26 @@ int query_internet(knot_pkt_t *pkt, ns_proc_context_t *ctx)
case KNOT_QUERY_NOTIFY:
next_state = internet_notify(pkt, ctx->ns, data);
break;
case KNOT_QUERY_AXFR:
if (ctx->flags & NS_QUERY_NO_AXFR) {
/* AXFR disabled, respond with NOTIMPL. */
data->rcode = KNOT_RCODE_NOTIMPL;
next_state = NS_PROC_FAIL;
} else {
next_state = axfr_answer(pkt, ctx->ns, data);
}
break;
case KNOT_QUERY_IXFR:
if (ctx->flags & NS_QUERY_NO_IXFR) {
/* IXFR disabled, respond with SOA. */
next_state = ixfr_answer_soa(pkt, ctx->ns, data);
} else {
next_state = ixfr_answer(pkt, ctx->ns, data);
}
break;
case KNOT_QUERY_UPDATE:
next_state = update_answer(pkt, ctx->ns, data);
break;
default:
assert(0); /* Should be caught earlier. */
data->rcode = KNOT_RCODE_SERVFAIL;
......@@ -271,7 +299,7 @@ static int prepare_answer(knot_pkt_t *query, knot_pkt_t *resp, ns_proc_context_t
/* Copy DO bit if set (DNSSEC requested). */
if (knot_pkt_have_dnssec(query)) {
dbg_ns("%s: setting DO=1 in OPT RR\n", __func__);
knot_edns_set_do(&(resp)->opt_rr);
knot_edns_set_do(&resp->opt_rr);
}
/* Set minimal supported size from EDNS(0). */
if (!(ctx->flags & NS_PKTSIZE_NOLIMIT)) {
......
......@@ -29,10 +29,17 @@
#include "libknot/nameserver/name-server.h"
/* Query processing module implementation. */
extern const ns_proc_module_t _ns_proc_query;
#define NS_PROC_QUERY (&_ns_proc_query)
#define NS_PROC_QUERY_ID 1
/* Query processing flags. */
enum ns_proc_query_flag {
NS_QUERY_NO_AXFR = NS_PROCFLAG << 1, /* Don't process AXFR */
NS_QUERY_NO_IXFR = NS_PROCFLAG << 2 /* Don't process IXFR */
};
struct query_data {
uint16_t rcode;
uint16_t rcode_tsig;
......
#include <config.h>
#include "libknot/nameserver/update.h"
#include "libknot/nameserver/ns_proc_query.h"
int update_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata)
{
qdata->rcode = KNOT_RCODE_NOTIMPL;
return NS_PROC_FAIL;
}
/*!
* \file update.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
* \brief DDNS UPDATE processing.
*
* \addtogroup query_processing
* @{
*/
/* Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KNOT_UPDATE_H_
#define _KNOT_UPDATE_H_
#include "libknot/packet/pkt.h"
#include "libknot/zone/zonedb.h"
#include "libknot/nameserver/name-server.h"
struct query_data;
int update_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata);
#endif /* _KNOT_UPDATE_H_ */
/*! @} */
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