Commit 408dd6b8 authored by Marek Vavrusa's avatar Marek Vavrusa

TSIG for query processing, NS processing now allows module parameter.

Cleanup of some debug messages.
parent 2e9d4e3d
......@@ -109,18 +109,9 @@ static int notify_reschedule(knot_nameserver_t *ns,
return KNOT_EINVAL;
}
/* Check ACL for notify-in. */
zonedata_t *zone_data = (zonedata_t *)knot_zone_data(zone);
if (from) {
if (acl_find(zone_data->notify_in, from) == NULL) {
return KNOT_EDENIED;
}
} else {
dbg_ns("%s: no zone data/address, can't do ACL check\n", __func__);
}
/* Cancel REFRESH/RETRY timer. */
server_t *server = ns->data;
zonedata_t *zone_data = (zonedata_t *)knot_zone_data(zone);
event_t *refresh_ev = zone_data->xfr_in.timer;
if (refresh_ev && server) {
dbg_ns("%s: expiring REFRESH timer\n", __func__);
......@@ -141,10 +132,18 @@ int internet_notify(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *q
/* RFC1996 require SOA question. */
NS_NEED_QTYPE(qdata, KNOT_RRTYPE_SOA, KNOT_RCODE_FORMERR);
/*! \note NOTIFY/RFC1996 isn't clear on error RCODEs.
* Most servers use NOTAUTH from RFC2136. */
NS_NEED_VALID_ZONE(qdata, KNOT_RCODE_NOTAUTH);
/* Need valid transaction security. */
zonedata_t *zone_data = (zonedata_t *)knot_zone_data(qdata->zone);
NS_NEED_AUTH(zone_data->notify_in, qdata);
/* Reserve space for TSIG. */
knot_pkt_tsig_set(pkt, qdata->sign.tsig_key);
/* SOA RR in answer may be included, recover serial. */
unsigned serial = 0;
const knot_pktsection_t *answer = knot_pkt_section(qdata->pkt, KNOT_ANSWER);
......
......@@ -51,13 +51,6 @@ typedef struct tcp_worker_t {
int pipe[2]; /*!< Master-worker signalization pipes. */
} tcp_worker_t;
/*! \brief Buffers .*/
enum {
QBUF = 0, /* Query buffer ID. */
QRBUF = 1, /* Response buffer ID. */
NBUFS = 2 /* Buffer count. */
};
/*
* Forward decls.
*/
......@@ -107,34 +100,22 @@ static enum fdset_sweep_state tcp_sweep(fdset_t *set, int i, void *data)
/*!
* \brief TCP event handler function.
*
* Handle single TCP event.
*
* \param w Associated I/O event.
* \param revents Returned events.
*
* \note We do not know if the packet makes sense or if it is
* a bunch of random bytes. There is no way to find out
* without parsing. However, it is irrelevant if we copy
* these random bytes to the response, so we may do it
* and ensure that in case of good packet the response
* is proper.
*/
static int tcp_handle(ns_proc_context_t *query_ctx, int fd,
struct iovec *rx, struct iovec *tx)
{
/* Check address type. */
sockaddr_t addr;
sockaddr_prep(&addr);
/* Create query processing parameter. */
struct ns_proc_query_param param;
sockaddr_prep(&param.query_source);
/* Receive data. */
int ret = tcp_recv(fd, rx->iov_base, rx->iov_len, &addr);
int ret = tcp_recv(fd, rx->iov_base, rx->iov_len, &param.query_source);
if (ret <= 0) {
dbg_net("tcp: client on fd=%d disconnected\n", fd);
if (ret == KNOT_EAGAIN) {
char r_addr[SOCKADDR_STRLEN];
sockaddr_tostr(&addr, r_addr, sizeof(r_addr));
int r_port = sockaddr_portnum(&addr);
sockaddr_tostr(&param.query_source, r_addr, sizeof(r_addr));
int r_port = sockaddr_portnum(&param.query_source);
rcu_read_lock();
log_server_warning("Couldn't receive query from '%s@%d'"
" within the time limit of %ds.\n",
......@@ -145,7 +126,10 @@ static int tcp_handle(ns_proc_context_t *query_ctx, int fd,
} else {
rx->iov_len = ret;
}
/* Create query processing context. */
ns_proc_begin(query_ctx, &param, NS_PROC_QUERY);
/* Input packet. */
uint16_t tx_len = tx->iov_len;
int state = ns_proc_in(rx->iov_base, rx->iov_len, query_ctx);
......@@ -165,7 +149,7 @@ static int tcp_handle(ns_proc_context_t *query_ctx, int fd,
}
/* Reset after processing. */
ns_proc_reset(query_ctx);
ns_proc_finish(query_ctx);
return ret;
}
......@@ -462,28 +446,26 @@ int tcp_loop_worker(dthread_t *thread)
}
#endif /* HAVE_CAP_NG_H */
/* Create TCP answering context. */
tcp_worker_t *w = thread->data;
int ret = KNOT_EOK;
tcp_worker_t *w = thread->data;
/* Create TCP answering context. */
ns_proc_context_t query_ctx;
memset(&query_ctx, 0, sizeof(query_ctx));
mm_ctx_init(&query_ctx.mm);
query_ctx.ns = w->ioh->server->nameserver;
/* Create big enough memory cushion. */
mm_ctx_mempool(&query_ctx.mm, 4 * sizeof(knot_pkt_t));
/* Packet size not limited by EDNS. */
query_ctx.flags |= NS_PKTSIZE_NOLIMIT;
/* Create query processing context. */
ns_proc_begin(&query_ctx, NS_PROC_QUERY);
/* Create iovec abstraction. */
mm_ctx_t *mm = &query_ctx.mm;
struct iovec bufs[2];
struct iovec iov[2];
for (unsigned i = 0; i < 2; ++i) {
bufs[i].iov_len = KNOT_WIRE_MAX_PKTSIZE;
bufs[i].iov_base = mm->alloc(mm->ctx, bufs[i].iov_len);
if (bufs[i].iov_base == NULL) {
iov[i].iov_len = KNOT_WIRE_MAX_PKTSIZE;
iov[i].iov_base = malloc(iov[i].iov_len);
if (iov[i].iov_base == NULL) {
ret = KNOT_ENOMEM;
goto finish;
}
......@@ -535,7 +517,11 @@ int tcp_loop_worker(dthread_t *thread)
if (fd == w->pipe[0]) {
tcp_loop_assign(fd, set);
} else {
int ret = tcp_handle(&query_ctx, fd, &bufs[0], &bufs[1]);
int ret = tcp_handle(&query_ctx, fd, &iov[0], &iov[1]);
/* Flush per-query memory. */
mp_flush(query_ctx.mm.ctx);
if (ret == KNOT_EOK) {
/* Update socket activity timer. */
fdset_set_watchdog(set, i, max_idle);
......@@ -563,9 +549,9 @@ int tcp_loop_worker(dthread_t *thread)
}
finish:
mm->free(bufs[0].iov_base);
mm->free(bufs[1].iov_base);
ns_proc_finish(&query_ctx);
free(iov[0].iov_base);
free(iov[1].iov_base);
mp_delete(query_ctx.mm.ctx);
return ret;
}
......
......@@ -143,8 +143,12 @@ int udp_handle(ns_proc_context_t *query_ctx, int fd, sockaddr_t *addr,
strfrom, sockaddr_portnum(addr));
#endif
/* Create query processing parameter. */
struct ns_proc_query_param param;
sockaddr_copy(&param.query_source, addr);
/* Create query processing context. */
ns_proc_begin(query_ctx, NS_PROC_QUERY);
ns_proc_begin(query_ctx, &param, NS_PROC_QUERY);
/* Input packet. */
uint16_t tx_len = tx->iov_len;
......
......@@ -606,6 +606,8 @@ static int xfr_task_resp(xfrworker_t *w, knot_ns_xfr_t *rq)
* reply and we should pass query sign time as the time
* may be different. Leaving to 0.
*/
memcpy(rq->tsig_data, rq->wire, rq->wire_size);
rq->tsig_data_size = rq->wire_size;
ret = knot_tsig_client_check(tsig_rr, rq->wire, rq->wire_size,
rq->digest, rq->digest_size,
rq->tsig_key, 0);
......@@ -835,121 +837,6 @@ static enum fdset_sweep_state xfr_sweep(fdset_t *set, int i, void *data)
return FDSET_KEEP;
}
/*! \brief Check TSIG if exists. */
static int xfr_check_tsig(knot_ns_xfr_t *xfr, knot_rcode_t *rcode, char **tag)
{
/* Parse rest of the packet. */
int ret = KNOT_EOK;
knot_pkt_t *qry = xfr->query;
knot_tsig_key_t *key = 0;
const knot_rrset_t *tsig_rr = qry->tsig_rr;
/* Find TSIG key name from query. */
const knot_dname_t* kname = NULL;
if (tsig_rr) {
kname = knot_rrset_owner(tsig_rr);
if (tag) {
*tag = knot_dname_to_str(kname);
}
} else {
// return REFUSED
xfr->tsig_key = NULL;
*rcode = KNOT_RCODE_REFUSED;
return KNOT_EDENIED;
}
if (tsig_rr) {
knot_tsig_algorithm_t alg = tsig_rdata_alg(tsig_rr);
if (knot_tsig_digest_length(alg) == 0) {
*rcode = KNOT_RCODE_NOTAUTH;
xfr->tsig_key = NULL;
xfr->tsig_rcode = KNOT_RCODE_BADKEY;
xfr->tsig_prev_time_signed =
tsig_rdata_time_signed(tsig_rr);
return KNOT_TSIG_EBADKEY;
}
}
/* Evaluate configured key for claimed key name.*/
key = xfr->tsig_key; /* Expects already set key (check_zone) */
xfr->tsig_key = 0;
if (key && kname && knot_dname_cmp(key->name, kname) == 0) {
dbg_xfr("xfr: found claimed TSIG key for comparison\n");
} else {
/* TSIG is mandatory if configured for interface. */
/* Configured, but doesn't match. */
dbg_xfr("xfr: no claimed key configured or not received"
", treating as bad key\n");
*rcode = KNOT_RCODE_NOTAUTH;
ret = KNOT_TSIG_EBADKEY;
xfr->tsig_rcode = KNOT_RCODE_BADKEY;
key = NULL; /* Invalidate, ret already set to BADKEY */
}
/* Validate with TSIG. */
if (key) {
/* Prepare variables for TSIG */
xfr_task_setsig(xfr, key);
/* Copy MAC from query. */
dbg_xfr("xfr: validating TSIG from query\n");
const uint8_t* mac = tsig_rdata_mac(tsig_rr);
size_t mac_len = tsig_rdata_mac_length(tsig_rr);
if (mac_len > xfr->digest_max_size) {
ret = KNOT_EMALF;
dbg_xfr("xfr: MAC length %zu exceeds digest "
"maximum size %zu\n",
mac_len, xfr->digest_max_size);
} else {
memcpy(xfr->digest, mac, mac_len);
xfr->digest_size = mac_len;
/* Check query TSIG. */
ret = knot_tsig_server_check(
tsig_rr,
qry->wire,
qry->size,
key);
dbg_xfr("knot_tsig_server_check() returned %s\n",
knot_strerror(ret));
}
/* Evaluate TSIG check results. */
switch(ret) {
case KNOT_EOK:
*rcode = KNOT_RCODE_NOERROR;
break;
case KNOT_TSIG_EBADKEY:
xfr->tsig_rcode = KNOT_RCODE_BADKEY;
xfr->tsig_key = NULL;
*rcode = KNOT_RCODE_NOTAUTH;
break;
case KNOT_TSIG_EBADSIG:
xfr->tsig_rcode = KNOT_RCODE_BADSIG;
xfr->tsig_key = NULL;
*rcode = KNOT_RCODE_NOTAUTH;
break;
case KNOT_TSIG_EBADTIME:
xfr->tsig_rcode = KNOT_RCODE_BADTIME;
// store the time signed from the query
assert(tsig_rr != NULL);
xfr->tsig_prev_time_signed =
tsig_rdata_time_signed(tsig_rr);
*rcode = KNOT_RCODE_NOTAUTH;
break;
case KNOT_EMALF:
*rcode = KNOT_RCODE_FORMERR;
break;
default:
*rcode = KNOT_RCODE_SERVFAIL;
}
}
return ret;
}
int xfr_worker(dthread_t *thread)
{
assert(thread != NULL && thread->data != NULL);
......
......@@ -1387,251 +1387,6 @@ int zones_xfr_check_zone(knot_ns_xfr_t *xfr, knot_rcode_t *rcode)
rcode);
}
/*! \todo #10 leaving it here for TSIG later on */
#if 0
/*----------------------------------------------------------------------------*/
/*! \todo This function is here only because TSIG key is associated with the
* zone via zonedata. If it was in the zone structure (which would be
* IMHO ok, this whole function could be moved to nameserver.c.
*/
int zones_normal_query_answer(knot_nameserver_t *nameserver,
knot_pkt_t *query, const sockaddr_t *addr,
uint8_t *resp_wire, size_t *rsize,
knot_ns_transport_t transport)
{
rcu_read_lock();
knot_rcode_t rcode = 0;
const knot_zone_t *zone = NULL;
const uint16_t qclass = knot_pkt_qclass(query);
/* Create response packet. */
knot_pkt_t *resp = knot_pkt_new(resp_wire, *rsize, &query->mm);
assert(resp != NULL);
dbg_zones_verb("Preparing response structure.\n");
int ret = knot_ns_prep_normal_response(nameserver, query, resp, &zone,
(transport == NS_TRANSPORT_TCP)
? *rsize : 0);
switch (ret) {
case KNOT_EOK:
rcode = KNOT_RCODE_NOERROR;
break;
case KNOT_EMALF:
// no TSIG signing in this case
rcode = KNOT_RCODE_FORMERR;
break;
default:
// no TSIG signing in this case
rcode = KNOT_RCODE_SERVFAIL;
break;
}
if (rcode == KNOT_RCODE_NOERROR) {
switch (qclass) {
case KNOT_CLASS_IN:
case KNOT_CLASS_CH:
case KNOT_CLASS_ANY:
break;
default:
rcode = KNOT_RCODE_REFUSED;
}
}
if (rcode != KNOT_RCODE_NOERROR) {
dbg_zones_verb("Failed preparing response structure: %s.\n",
knot_strerror(rcode));
if (resp == NULL) {
knot_ns_error_response_from_query(nameserver, query,
rcode, resp_wire,
rsize);
rcu_read_unlock();
return KNOT_EOK;
}
knot_ns_error_response_full(nameserver, resp, rcode, resp_wire,
rsize);
} else {
/*
* Now we have zone. Verify TSIG if it is in the packet.
*/
assert(resp != NULL);
assert(rcode == KNOT_RCODE_NOERROR);
uint16_t tsig_rcode = 0;
knot_tsig_key_t *tsig_key_zone = NULL;
uint64_t tsig_prev_time_signed = 0;
/*! \todo Verify, as it was uninitialized! */
size_t answer_size = *rsize;
int ret = KNOT_EOK;
if (query->tsig_rr != NULL) {
dbg_zones_verb("Checking TSIG in query.\n");
if (zone == NULL) {
// treat as BADKEY error
/*! \todo Is this OK?? */
rcode = KNOT_RCODE_NOTAUTH;
tsig_rcode = KNOT_RCODE_BADKEY;
ret = KNOT_TSIG_EBADKEY;
} else {
ret = zones_check_tsig_query(zone, query, addr,
&rcode, &tsig_rcode, &tsig_key_zone,
&tsig_prev_time_signed);
}
}
if (ret == KNOT_EOK) {
dbg_zones_verb("TSIG check successful. Answering "
"query.\n");
assert(tsig_rcode == 0);
// reserve place for the TSIG
knot_pkt_tsig_set(resp, tsig_key_zone);
// handle IXFR queries
if (knot_pkt_qtype(query) == KNOT_RRTYPE_IXFR) {
assert(transport == NS_TRANSPORT_UDP);
ret = knot_ns_answer_ixfr_udp(nameserver, zone,
resp, resp_wire,
&answer_size);
} else {
if (qclass == KNOT_CLASS_CH) {
ret = knot_ns_answer_chaos(nameserver,
resp, resp_wire, &answer_size);
} else {
ret = knot_ns_answer_normal(nameserver,
zone, resp, resp_wire, &answer_size,
transport == NS_TRANSPORT_UDP);
}
/* Copy wildcard markers. */
if (resp->flags & KNOT_PF_WILDCARD)
query->flags |= KNOT_PF_WILDCARD;
}
dbg_zones_detail("rsize = %zu\n", *rsize);
dbg_zones_detail("answer_size = %zu\n", answer_size);
assert(ret == KNOT_EOK);
// sign the message
if (tsig_key_zone != NULL) {
dbg_zones_verb("Signing message with TSIG.\n");
// TODO check
//*rsize = answer_size;
size_t digest_max_size =
knot_tsig_digest_length(
tsig_key_zone->algorithm);
uint8_t *digest = (uint8_t *)malloc(
digest_max_size);
if (digest == NULL) {
knot_pkt_free(&resp);
rcu_read_unlock();
return KNOT_ENOMEM;
}
size_t digest_size = digest_max_size;
ret = knot_tsig_sign(resp_wire, &answer_size,
*rsize, tsig_rdata_mac(query->tsig_rr),
tsig_rdata_mac_length(query->tsig_rr),
digest, &digest_size,
tsig_key_zone, tsig_rcode,
tsig_prev_time_signed);
free(digest);
dbg_zones_detail("answer_size = %zu\n",
answer_size);
if (ret != KNOT_EOK) {
dbg_zones_verb("Failed to sign message:"
"%s\n", knot_strerror(ret));
rcode = KNOT_RCODE_SERVFAIL;
} else {
*rsize = answer_size;
}
} else {
*rsize = answer_size;
}
} else {
dbg_zones_verb("Failed TSIG check: %s, TSIG err: %u.\n",
knot_strerror(ret), tsig_rcode);
if (tsig_rcode != 0) {
dbg_zones_verb("Sending TSIG error.\n");
// first, convert the response to wire format
answer_size = *rsize;
knot_wire_set_rcode(resp->wire, rcode);
ret = ns_response_to_wire(resp, resp_wire,
&answer_size);
dbg_zones_detail("Packet to wire returned %d\n",
ret);
// then add the TSIG to the wire format
if (ret == KNOT_EOK &&
tsig_rcode != KNOT_RCODE_BADTIME) {
dbg_zones_verb("Adding TSIG.\n");
ret = knot_tsig_add(resp_wire,
&answer_size,
*rsize, tsig_rcode,
query->tsig_rr);
*rsize = answer_size;
} else if (tsig_rcode
== KNOT_RCODE_BADTIME) {
dbg_zones_verb("Signing error resp.\n");
//*rsize = answer_size;
size_t digest_max_size =
knot_tsig_digest_length(
tsig_key_zone->algorithm);
uint8_t *digest = (uint8_t *)malloc(
digest_max_size);
if (digest == NULL) {
knot_pkt_free(&resp);
rcu_read_unlock();
return KNOT_ENOMEM;
}
size_t digest_size = digest_max_size;
ret = knot_tsig_sign(resp_wire,
&answer_size, *rsize,
tsig_rdata_mac(query->tsig_rr),
tsig_rdata_mac_length(query->tsig_rr),
digest, &digest_size, tsig_key_zone,
tsig_rcode, tsig_prev_time_signed);
// no need to keep the digest
free(digest);
*rsize = answer_size;
} else {
dbg_zones_verb("Failed.\n");
rcode = KNOT_RCODE_SERVFAIL;
}
}
// in other case the RCODE is set and ret != KNOT_EOK
// and a normal error is returned below
}
if (ret != KNOT_EOK) {
knot_ns_error_response_full(nameserver, resp,
rcode, resp_wire,
rsize);
}
}
knot_pkt_free(&resp);
rcu_read_unlock();
return KNOT_EOK;
}
#endif
/*----------------------------------------------------------------------------*/
int zones_process_update(knot_nameserver_t *nameserver,
......
......@@ -6,6 +6,7 @@
#include "libknot/util/debug.h"
#include "common/descriptor.h"
#include "common/lists.h"
#include "knot/server/zones.h"
struct axfr_proc {
struct xfr_proc proc;
......@@ -83,9 +84,6 @@ static int axfr_answer_init(struct query_data *qdata)
{
assert(qdata);
/* Check zone state. */
NS_NEED_VALID_ZONE(qdata, KNOT_RCODE_NOTAUTH);
/* Begin zone iterator. */
mm_ctx_t *mm = qdata->mm;
knot_zone_contents_t *zone = qdata->zone->contents;
......@@ -157,13 +155,23 @@ int axfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata
/* Initialize on first call. */
if (qdata->ext == NULL) {
/* Check zone state. */
NS_NEED_VALID_ZONE(qdata, KNOT_RCODE_NOTAUTH);
/* Need valid transaction security. */
zonedata_t *zone_data = (zonedata_t *)knot_zone_data(qdata->zone);
NS_NEED_AUTH(zone_data->xfr_out, qdata);
ret = axfr_answer_init(qdata);
dbg_ns("%s: init => %s\n", __func__, knot_strerror(ret));
if (ret != KNOT_EOK) {
dbg_ns("%s: init => %s\n", __func__, knot_strerror(ret));
return ret;
}
}
/* Reserve space for TSIG. */
knot_pkt_tsig_set(pkt, qdata->sign.tsig_key);
/* Answer current packet (or continue). */
struct xfr_proc *xfer = qdata->ext;
......
......@@ -614,6 +614,13 @@ int internet_answer(knot_pkt_t *response, struct query_data *qdata)
}
NS_NEED_VALID_ZONE(qdata, KNOT_RCODE_REFUSED);
/* No applicable ACL, refuse transaction security. */
if (knot_pkt_have_tsig(qdata->pkt)) {
qdata->rcode = KNOT_RCODE_NOTAUTH;
qdata->rcode_tsig = KNOT_RCODE_BADKEY;
return NS_PROC_FAIL;
}
/* Write answer RRs for QNAME. */
dbg_ns("%s: writing %p ANSWER\n", __func__, response);
......
......@@ -65,6 +65,17 @@ int internet_answer(knot_pkt_t *resp, struct query_data *qdata);
return NS_PROC_FAIL; \
}
/*! \brief Require authentication. */
#define NS_NEED_AUTH(acl, qdata) \
if (!ns_proc_query_acl_check((acl), (qdata))) { \
return NS_PROC_FAIL; \
} else { \
if (ns_proc_query_verify(qdata) != KNOT_EOK) { \
return NS_PROC_FAIL; \
} \
}
#endif /* _KNOT_INTERNET_H_ */
/*! @} */
......@@ -158,6 +158,11 @@ static int ixfr_query_check(struct query_data *qdata)
}
/* SOA needs to match QNAME. */
NS_NEED_QNAME(qdata, their_soa->owner, KNOT_RCODE_FORMERR);
/* Need valid transaction security. */
zonedata_t *zone_data = (zonedata_t *)knot_zone_data(qdata->zone);
NS_NEED_AUTH(zone_data->xfr_out, qdata);
return NS_PROC_FINISH;
}
......@@ -206,8 +211,14 @@ int ixfr_answer_soa(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *q
return NS_PROC_FAIL;
}
/* Check zone state. */
NS_NEED_VALID_ZONE(qdata, KNOT_RCODE_NOTAUTH);
/* Check query. */
int state = ixfr_query_check(qdata);
if (state == NS_PROC_FAIL) {
return state; /* Malformed query. */
}
/* Reserve space for TSIG. */
knot_pkt_tsig_set(pkt, qdata->sign.tsig_key);
/* Guaranteed to have zone contents. */
const knot_node_t *apex = qdata->zone->contents->apex;
......@@ -235,19 +246,24 @@ int ixfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata
/* Initialize on first call. */
if (qdata->ext == NULL) {
ret = ixfr_answer_init(qdata);
dbg_ns("%s: init => %s\n", __func__, knot_strerror(ret));
switch(ret) {
case KNOT_EOK: /* OK */
break;
case KNOT_EUPTODATE: /* Our zone is same age/older, send SOA. */
dbg_ns("%s: nothing new => SOA response\n", __func__);
return ixfr_answer_soa(pkt, ns, qdata);
case KNOT_ERANGE: /* No history -> AXFR. */
case KNOT_ENOENT:
dbg_ns("%s: not enough history => AXFR answer\n", __func__);
return axfr_answer(pkt, ns, qdata);
default: /* Server errors. */
dbg_ns("%s: init => %s\n", __func__, knot_strerror(ret));
return NS_PROC_FAIL;
}
}
/* Reserve space for TSIG. */
knot_pkt_tsig_set(pkt, qdata->sign.tsig_key);
/* Answer current packet (or continue). */
struct ixfr_proc *ixfr = (struct ixfr_proc*)qdata->ext;
......
......@@ -134,123 +134,6 @@ int knot_ns_tsig_required(int packet_nr)
/*----------------------------------------------------------------------------*/
static int ns_xfr_send_and_clear(knot_ns_xfr_t *xfr, int add_tsig)
{
assert(xfr != NULL);
assert(xfr->query != NULL);
assert(xfr->response != NULL);
assert(xfr->wire != NULL);
assert(xfr->send != NULL);
// Transform the packet into wire format
dbg_ns_verb("Converting response to wire format..\n");
size_t real_size = xfr->wire_size;
if (ns_response_to_wire(xfr->response, xfr->wire, &real_size) != 0) {
return NS_ERR_SERVFAIL;
}
int res = 0;
size_t digest_real_size = xfr->digest_max_size;
dbg_ns_detail("xfr->tsig_key=%p\n", xfr->tsig_key);
dbg_ns_detail("xfr->tsig_rcode=%d\n", xfr->tsig_rcode);
if (xfr->tsig_key) {
// add the data to TSIG data
assert(KNOT_NS_TSIG_DATA_MAX_SIZE - xfr->tsig_data_size
>= xfr->wire_size);
memcpy(xfr->tsig_data + xfr->tsig_data_size,
xfr->wire, real_size);
xfr->tsig_data_size += real_size;
}