Commit c83c3a90 authored by Marek Vavrusa's avatar Marek Vavrusa

Fixed max_size being set to 0 with multiple error responses.

parent fef5d8f4
......@@ -132,21 +132,20 @@ static int tcp_handle(ns_proc_context_t *query_ctx, int fd,
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);
/* Resolve until NOOP or finished. */
ret = KNOT_EOK;
while (state == NS_PROC_FULL || state == NS_PROC_FAIL) {
while (state & (NS_PROC_FULL|NS_PROC_FAIL)) {
uint16_t tx_len = tx->iov_len;
state = ns_proc_out(tx->iov_base, &tx_len, query_ctx);
/* If it has response, send it. */
if (state == NS_PROC_DONE || state == NS_PROC_FULL) {
if (tx_len > 0) {
if (tcp_send(fd, tx->iov_base, tx_len) != tx_len) {
ret = KNOT_ECONNREFUSED;
break;
}
tx_len = tx->iov_len; /* Reset size. */
}
}
......
......@@ -132,16 +132,17 @@ int udp_handle(ns_proc_context_t *query_ctx, int fd, sockaddr_t *addr,
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);
/* Process answer. */
uint16_t tx_len = tx->iov_len;
if (state == NS_PROC_FULL) {
state = ns_proc_out(tx->iov_base, &tx_len, query_ctx);
}
/* Process error response (if failed). */
if (state == NS_PROC_FAIL) {
tx_len = tx->iov_len; /* Reset size. */
state = ns_proc_out(tx->iov_base, &tx_len, query_ctx);
}
......
......@@ -485,6 +485,7 @@ void knot_ns_destroy(knot_nameserver_t **nameserver)
}
/* State -> string translation table. */
#ifdef KNOT_NS_DEBUG
#define NS_STATE_STR(x) _state_table[x]
static const char* _state_table[] = {
[NS_PROC_NOOP] = "NOOP",
......@@ -493,6 +494,7 @@ static const char* _state_table[] = {
[NS_PROC_DONE] = "DONE",
[NS_PROC_FAIL] = "FAIL"
};
#endif /* KNOT_NS_DEBUG */
int ns_proc_begin(ns_proc_context_t *ctx, void *module_param, const ns_proc_module_t *module)
{
......
......@@ -189,34 +189,24 @@ int ns_proc_query_err(knot_pkt_t *pkt, ns_proc_context_t *ctx)
__func__, qdata->rcode, qdata->rcode_tsig);
/* Initialize response from query packet. */
knot_pkt_clear(pkt);
knot_pkt_t *query = qdata->query;
pkt->size = knot_pkt_question_size(query);
knot_pkt_init_response(pkt, query);
/* If original QNAME is empty, Query is either unparsed or for root domain.
* Either way, letter case doesn't matter. */
if (qdata->orig_qname[0] == '\0') {
memcpy(pkt->wire, query->wire, pkt->size);
} else {
/* Copy header and QNAME with original case. */
memcpy(pkt->wire, query->wire, KNOT_WIRE_HEADER_SIZE);
memcpy(pkt->wire + KNOT_WIRE_HEADER_SIZE, qdata->orig_qname, query->qname_size);
if (qdata->orig_qname[0] != '\0') {
memcpy(pkt->wire + KNOT_WIRE_HEADER_SIZE,
qdata->orig_qname, query->qname_size);
}
/* Set QR=1 and RCODE. */
knot_wire_set_qr(pkt->wire);
/* Set RCODE. */
knot_wire_set_rcode(pkt->wire, qdata->rcode);
/* Copy RD bit. */
if (knot_wire_get_rd(query->wire)) {
knot_wire_set_rd(pkt->wire);
}
/* Transaction security (if applicable). */
if (ns_proc_query_sign_response(pkt, qdata) != KNOT_EOK) {
return NS_PROC_FAIL;
}
return NS_PROC_DONE;
}
......@@ -237,6 +227,7 @@ bool ns_proc_query_acl_check(acl_t *acl, struct query_data *qdata)
/* Did not authenticate, no fitting rule found. */
if (match == NULL || (match->key && match->key->algorithm != key_alg)) {
dbg_ns("%s: no ACL match => NOTAUTH\n", __func__);
qdata->rcode = KNOT_RCODE_NOTAUTH;
qdata->rcode_tsig = KNOT_RCODE_BADKEY;
return false;
......@@ -267,6 +258,8 @@ int ns_proc_query_verify(struct query_data *qdata)
int ret = knot_tsig_server_check(query->tsig_rr, query->wire,
query->size, ctx->tsig_key);
dbg_ns("%s: QUERY TSIG check result = %s\n", __func__, knot_strerror(ret));
/* Evaluate TSIG check results. */
switch(ret) {
case KNOT_EOK:
......@@ -356,6 +349,7 @@ static int query_internet(knot_pkt_t *pkt, ns_proc_context_t *ctx)
{
struct query_data *data = QUERY_DATA(ctx);
int next_state = NS_PROC_FAIL;
dbg_ns("%s(%p, %p, pkt_type=%u)\n", __func__, pkt, ctx, data->packet_type);
switch(data->packet_type) {
case KNOT_QUERY_NORMAL:
......
......@@ -212,6 +212,7 @@ int knot_pkt_init_response(knot_pkt_t *pkt, const knot_pkt_t *query)
/* Header + question size. */
size_t question_size = knot_pkt_question_size(query);
if (question_size > pkt->max_size) {
dbg_packet("%s: pkt max size < HEADER size\n", __func__);
return KNOT_ESPACE;
}
pkt->query = query;
......@@ -220,7 +221,6 @@ int knot_pkt_init_response(knot_pkt_t *pkt, const knot_pkt_t *query)
memcpy(pkt->wire, query->wire, question_size);
/* Update size and flags. */
knot_wire_set_qdcount(pkt->wire, 1);
knot_wire_set_qr(pkt->wire);
knot_wire_clear_tc(pkt->wire);
knot_wire_clear_ad(pkt->wire);
......
......@@ -64,7 +64,7 @@ enum {
*/
typedef struct {
const knot_rrset_t **rr; /*!< Array of RRSets for this section. */
const knot_rrinfo_t *rrinfo; /*!< Compression info for each RRSet. */
knot_rrinfo_t *rrinfo; /*!< Compression info for each RRSet. */
uint16_t count; /*!< Number of RRSets in this section. */
} knot_pktsection_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