diff --git a/daemon/worker.c b/daemon/worker.c index 26a913a37fd085cf2837334d71ee218e7fb9a3bc..1043629bd106dbc178d87e4a9658cf49d1f47372 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -117,6 +117,7 @@ static void qr_task_timeout(uv_timer_t *req) { struct qr_task *task = req->data; if (task->next_handle) { + uv_cancel((uv_req_t *)&task->ioreq); io_stop_read(task->next_handle); qr_task_step(task, NULL); } @@ -182,7 +183,9 @@ static int qr_task_step(struct qr_task *task, knot_pkt_t *packet) { /* Cancel timeout if active, close handle. */ if (task->next_handle) { - uv_close(task->next_handle, (uv_close_cb) free); + if (!uv_is_closing(task->next_handle)) { + uv_close(task->next_handle, (uv_close_cb) free); + } uv_timer_stop(&task->timeout); task->next_handle = NULL; } @@ -214,10 +217,10 @@ static int qr_task_step(struct qr_task *task, knot_pkt_t *packet) task->next_handle->data = task; if (sock_type == SOCK_STREAM) { uv_connect_t *connect = &task->ioreq.connect; + connect->data = task; if (uv_tcp_connect(connect, (uv_tcp_t *)task->next_handle, addr, qr_task_on_connect) != 0) { return qr_task_step(task, NULL); } - connect->data = task; } else { if (qr_task_send(task, task->next_handle, addr, next_query) != 0) { return qr_task_step(task, NULL); diff --git a/lib/layer/pktcache.c b/lib/layer/pktcache.c index fb627685cc07988ca87772cdfabbf1856dc1ebff..050aec156255e35320b7e1c11b12af6f0289cdd5 100644 --- a/lib/layer/pktcache.c +++ b/lib/layer/pktcache.c @@ -24,6 +24,7 @@ #define DEBUG_MSG(fmt...) QRDEBUG(kr_rplan_current(rplan), " pc ", fmt) #define DEFAULT_MAXTTL (15 * 60) +#define DEFAULT_NOTTL (5) /* Short-time "no data" retention to avoid bursts */ static inline uint8_t get_tag(knot_pkt_t *pkt) { @@ -47,7 +48,9 @@ static void adjust_ttl(knot_rrset_t *rr, uint32_t drift) for (uint16_t i = 0; i < rr->rrs.rr_count; ++i) { knot_rdata_t *rd = knot_rdataset_at(&rr->rrs, i); uint32_t ttl = knot_rdata_ttl(rd); - knot_rdata_set_ttl(rd, ttl - drift); + if (ttl >= drift) { + knot_rdata_set_ttl(rd, ttl - drift); + } } } @@ -96,6 +99,9 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) if (!qry || ctx->state & (KNOT_STATE_DONE|KNOT_STATE_FAIL)) { return ctx->state; } + if (knot_pkt_qclass(pkt) != KNOT_CLASS_IN) { + return ctx->state; /* Only IN class */ + } /* Fetch packet from cache */ namedb_txn_t txn; @@ -119,7 +125,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) static uint32_t packet_ttl(knot_pkt_t *pkt) { - uint32_t ttl = 0; + uint32_t ttl = DEFAULT_NOTTL; /* Fetch SOA from authority. */ const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY); for (unsigned i = 0; i < ns->count; ++i) { @@ -134,6 +140,10 @@ static uint32_t packet_ttl(knot_pkt_t *pkt) const knot_pktsection_t *sec = knot_pkt_section(pkt, i); for (unsigned k = 0; k < sec->count; ++k) { const knot_rrset_t *rr = knot_pkt_rr(sec, k); + /* Skip OPT and TSIG */ + if (rr->type == KNOT_RRTYPE_OPT || rr->type == KNOT_RRTYPE_TSIG) { + continue; + } for (uint16_t i = 0; i < rr->rrs.rr_count; ++i) { knot_rdata_t *rd = knot_rdataset_at(&rr->rrs, i); if (knot_rdata_ttl(rd) < ttl) { @@ -149,12 +159,16 @@ static int stash(knot_layer_t *ctx) { struct kr_request *req = ctx->data; struct kr_rplan *rplan = &req->rplan; - if (EMPTY_LIST(rplan->resolved) || ctx->state == KNOT_STATE_FAIL) { + if (EMPTY_LIST(rplan->resolved) || ctx->state & KNOT_STATE_FAIL) { return ctx->state; /* Don't cache anything if failed. */ } - knot_pkt_t *pkt = req->answer; struct kr_query *qry = TAIL(rplan->resolved); - if (qry->flags & QUERY_CACHED || !(kr_response_classify(pkt) & (PKT_NODATA|PKT_NXDOMAIN))) { + knot_pkt_t *pkt = req->answer; + if (knot_pkt_qclass(pkt) != KNOT_CLASS_IN) { + return ctx->state; /* Only IN class */ + } + int pkt_class = kr_response_classify(pkt); + if (qry->flags & QUERY_CACHED || !(pkt_class & (PKT_NODATA|PKT_NXDOMAIN))) { return ctx->state; /* Cache only negative, not-cached answers. */ } uint32_t ttl = packet_ttl(pkt); diff --git a/lib/resolve.c b/lib/resolve.c index 23d4744408cb142e77b279ae83c521066e04738b..92cee2d76529652599c0c5e2824469fe00075a6c 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -347,6 +347,8 @@ int kr_resolve_consume(struct kr_request *request, knot_pkt_t *packet) /* Pop query if resolved. */ if (qry->flags & QUERY_RESOLVED) { kr_rplan_pop(rplan, qry); + } else { /* Clear query flags for next attempt */ + qry->flags &= ~QUERY_CACHED; } knot_overlay_reset(&request->overlay);