]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
modules: fix issues with dropped answers
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 30 Oct 2020 15:29:44 +0000 (16:29 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 10 Nov 2020 16:16:47 +0000 (17:16 +0100)
lib/resolve.h
modules/dnstap/dnstap.c
modules/policy/policy.lua
modules/stats/stats.c
modules/ta_sentinel/ta_sentinel.lua

index d18bd64790450739105b16f718e558b957a2ecf6..1095fa9ac46dc4951823d5a5c1e8b4ee0b152db1 100644 (file)
@@ -264,7 +264,8 @@ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx);
  *
  * It may return NULL, in which case it marks ->state with _FAIL and no answer will be sent.
  * Only use this when it's guaranteed that there will be no delay before sending it.
- * You don't need to call this in places where "resolver knows" that there will be no delay.
+ * You don't need to call this in places where "resolver knows" that there will be no delay,
+ * but even there you need to check if the ->answer is NULL (unless you check for _FAIL anyway).
  */
 KR_EXPORT
 knot_pkt_t * kr_request_ensure_answer(struct kr_request *request);
index 7b1dde55ae2296ac23615e9c218744e86ac938ef..b774860112e69935ed12cd071dec959df82ea017 100644 (file)
@@ -136,9 +136,11 @@ static int dnstap_log(kr_layer_t *ctx) {
 
        if (dnstap_dt->log_resp_pkt) {
                const knot_pkt_t *rpkt = req->answer;
-               m.response_message.len = rpkt->size;
-               m.response_message.data = (uint8_t *)rpkt->wire;
-               m.has_response_message = true;
+               m.has_response_message = rpkt != NULL;
+               if (rpkt != NULL) {
+                       m.response_message.len = rpkt->size;
+                       m.response_message.data = (uint8_t *)rpkt->wire;
+               }
        }
 
        /* set query time to the timestamp of the first kr_query
index 99985947194f01c450a07784bcee86459c8d76b8..e19d7146684699c5f323c05aaa022836c960ea06 100644 (file)
@@ -654,9 +654,14 @@ local debug_logfinish_cb = ffi.cast('trace_callback_f', function (req)
        ffi.C.kr_log_req(req, 0, 0, 'dbg',
                'following rrsets were marked as interesting:\n' ..
                req:selected_tostring())
-       ffi.C.kr_log_req(req, 0, 0, 'dbg',
-               'answer packet:\n' ..
-               tostring(req.answer))
+       if req.answer ~= nil then
+               ffi.C.kr_log_req(req, 0, 0, 'dbg',
+                       'answer packet:\n' ..
+                       tostring(req.answer))
+       else
+               ffi.C.kr_log_req(req, 0, 0, 'dbg',
+                       'answer packet DROPPED\n')
+       end
 end)
 ffi.gc(debug_logfinish_cb, free_cb)
 
index a83ead891d2a24bb2462caf8f4c6785d903e5388..132c05c496982cb096a980494edbdbf02d295440 100644 (file)
@@ -118,7 +118,7 @@ static inline int collect_key(char *key, const knot_dname_t *name, uint16_t type
        return key_len + sizeof(type);
 }
 
-static void collect_sample(struct stat_data *data, struct kr_rplan *rplan, knot_pkt_t *pkt)
+static void collect_sample(struct stat_data *data, struct kr_rplan *rplan)
 {
        /* Sample key = {[2] type, [1-255] owner} */
        char key[sizeof(uint16_t) + KNOT_DNAME_MAXLEN];
@@ -208,9 +208,14 @@ static int collect(kr_layer_t *ctx)
        struct kr_rplan *rplan = &param->rplan;
        struct stat_data *data = module->data;
 
+       collect_sample(data, rplan);
+       if (!param->answer) {
+               /* The answer is being dropped.  TODO: perhaps add some stat for this? */
+               return ctx->state;
+       }
+
        /* Collect data on final answer */
        collect_answer(data, param->answer);
-       collect_sample(data, rplan, param->answer);
        /* Count cached and unresolved */
        if (rplan->resolved.len > 0) {
                /* Histogram of answer latency. */
index 2cb04b11a75151b2771f245d6cdeb8f72e01bc0e..a0fb67ec8e2edc9e88e89154cb6c2dbf3d8458d1 100644 (file)
@@ -4,6 +4,7 @@ M.layer = {}
 local ffi = require('ffi')
 
 function M.layer.finish(state, req, pkt)
+       if pkt == nil then return end
        -- fast filter by the length of the first QNAME label
        if pkt.wire[5] == 0 then return state end -- QDCOUNT % 256 == 0, in case we produced that
        local label_len = pkt.wire[12]