- avoid SERVFAILs due to certain kind of NS dependency cycles, again
(#374) this time seen as 'circular dependency' in verbose logs
- policy and view modules do not overwrite result finished requests (!678)
+- cache: fix some cases of caching answers over 4 KiB (!976)
Improvements
------------
static struct qr_task *qr_task_create(struct request_ctx *ctx)
{
- /* How much can client handle? */
- struct engine *engine = ctx->worker->engine;
- size_t pktbuf_max = KR_EDNS_PAYLOAD;
- if (engine->resolver.opt_rr) {
- pktbuf_max = MAX(knot_edns_get_payload(engine->resolver.opt_rr),
- pktbuf_max);
+ /* Choose (initial) pktbuf size. As it is now, pktbuf can be used
+ * for UDP answers from upstream *and* from cache
+ * and for sending non-UDP queries upstream (?) */
+ uint16_t pktbuf_max = KR_EDNS_PAYLOAD;
+ const knot_rrset_t *opt_our = ctx->worker->engine->resolver.opt_rr;
+ if (opt_our) {
+ pktbuf_max = MAX(pktbuf_max, knot_edns_get_payload(opt_our));
}
/* Create resolution task */
struct kr_request *req = ctx->req;
struct kr_query *qry = req->current_query;
+ const uint16_t msgid = knot_wire_get_id(pkt->wire);
+
+ /* Ensure the wire buffer is large enough. Strategy: fit and at least double. */
uint16_t pkt_len;
memcpy(&pkt_len, eh->data, sizeof(pkt_len));
if (pkt_len > pkt->max_size) {
- return kr_error(ENOENT);
+ pkt->max_size = MIN(KNOT_WIRE_MAX_PKTSIZE,
+ MAX(pkt->max_size * 2, pkt_len));
+ mm_free(&ctx->req->pool, pkt->wire); /* no-op, but... */
+ pkt->wire = mm_alloc(&ctx->req->pool, pkt->max_size);
+ pkt->compr.wire = pkt->wire;
+ /* TODO: ^^ nicer way how to replace knot_pkt_t::wire ? */
}
+ assert(pkt->max_size >= pkt_len);
/* Copy answer and reparse it, but keep the original message id. */
- uint16_t msgid = knot_wire_get_id(pkt->wire);
knot_pkt_clear(pkt);
memcpy(pkt->wire, eh->data + 2, pkt_len);
pkt->size = pkt_len;
} else
#endif
if (pkt->parsed <= KNOT_WIRE_HEADER_SIZE) {
- VERBOSE_MSG("<= malformed response\n");
+ VERBOSE_MSG("<= malformed response (parsed %d)\n", (int)pkt->parsed);
return resolve_badmsg(pkt, req, query);
} else if (!is_paired_to_query(pkt, query)) {
WITH_VERBOSE(query) {
struct kr_context
{
struct kr_qflags options;
+
+ /** Default EDNS towards *both* clients and upstream.
+ * LATER: consider splitting the two, e.g. allow separately
+ * configured limits for UDP packet size (say, LAN is under control). */
knot_rrset_t *opt_rr;
+
map_t trust_anchors;
map_t negative_anchors;
struct kr_zonecut root_hints;
/* Kept outside, because kres-gen.lua can't handle this depth
* (and lines here were too long anyway). */
struct kr_request_qsource_flags {
- bool tcp:1; /**< true if the request is on TCP (or TLS); only meaningful if (dst_addr). */
- bool tls:1; /**< true if the request is on TLS (or HTTPS); only meaningful if (dst_addr). */
+ bool tcp:1; /**< true if the request is not on UDP; only meaningful if (dst_addr). */
+ bool tls:1; /**< true if the request is encrypted; only meaningful if (dst_addr). */
bool http:1; /**< true if the request is on HTTP; only meaningful if (dst_addr). */
};