From 8c7c88ab274d0cd0076ad18995731f499390c7d4 Mon Sep 17 00:00:00 2001 From: Daniel Salzman <daniel.salzman@nic.cz> Date: Mon, 2 Dec 2024 15:26:25 +0100 Subject: [PATCH] mod-rrl: add QNAME, if possible, and PROTO to log messages --- src/knot/modules/rrl/functions.c | 29 +++++++++++++++++++++++------ src/knot/modules/rrl/functions.h | 10 ++++++++-- src/knot/modules/rrl/rrl.c | 6 ++++-- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/knot/modules/rrl/functions.c b/src/knot/modules/rrl/functions.c index 01d89cb669..5534b44377 100644 --- a/src/knot/modules/rrl/functions.c +++ b/src/knot/modules/rrl/functions.c @@ -68,18 +68,35 @@ static void addr_tostr(char *dst, size_t maxlen, const struct sockaddr_storage * } } -static void rrl_log_limited(knotd_mod_t *mod, const struct sockaddr_storage *ss, +static void rrl_log_limited(rrl_log_params_t *params, const struct sockaddr_storage *ss, const uint8_t prefix, bool rate) { - if (mod == NULL) { + if (params == NULL) { return; } char addr_str[SOCKADDR_STRLEN]; addr_tostr(addr_str, sizeof(addr_str), ss); - knotd_mod_log(mod, LOG_NOTICE, "address %s limited on /%d by %s", - addr_str, prefix, rate ? "rate" : "time"); + const char *proto_str = "UDP"; + const char *qname_str = NULL; + knot_dname_txt_storage_t buf; + if (params->qdata != NULL) { + qname_str = knot_dname_to_str(buf, knot_pkt_qname(params->qdata->query), + sizeof(buf)); + } else { + switch (params->proto) { + case KNOTD_QUERY_PROTO_TCP: proto_str = "TCP"; break; + case KNOTD_QUERY_PROTO_QUIC: proto_str = "QUIC"; break; + case KNOTD_QUERY_PROTO_TLS: proto_str = "TLS"; break; + default: break; + } + } + + knotd_mod_log(params->mod, LOG_NOTICE, "address %s %s limited on /%d by %s%s%s", + addr_str, proto_str, prefix, rate ? "rate" : "time", + (qname_str != NULL ? ", qname " : ""), + (qname_str != NULL ? qname_str : "")); } rrl_table_t *rrl_create(size_t size, uint32_t instant_limit, uint32_t rate_limit, @@ -131,7 +148,7 @@ rrl_table_t *rrl_create(size_t size, uint32_t instant_limit, uint32_t rate_limit return rrl; } -int rrl_query(rrl_table_t *rrl, const struct sockaddr_storage *remote, knotd_mod_t *mod) +int rrl_query(rrl_table_t *rrl, const struct sockaddr_storage *remote, rrl_log_params_t *log) { assert(rrl); assert(remote); @@ -186,7 +203,7 @@ int rrl_query(rrl_table_t *rrl, const struct sockaddr_storage *remote, knotd_mod do { if (atomic_compare_exchange_weak_explicit(&rrl->log_time, &log_time_orig, now, memory_order_relaxed, memory_order_relaxed)) { - rrl_log_limited(mod, remote, prefix, rrl->rw_mode); + rrl_log_limited(log, remote, prefix, rrl->rw_mode); break; } } while (now - log_time_orig + 1024 >= rrl->log_period + 1024); diff --git a/src/knot/modules/rrl/functions.h b/src/knot/modules/rrl/functions.h index 0941c8378f..8fe1383c5f 100644 --- a/src/knot/modules/rrl/functions.h +++ b/src/knot/modules/rrl/functions.h @@ -37,6 +37,12 @@ typedef struct rrl_table rrl_table_t; rrl_table_t *rrl_create(size_t size, uint32_t instant_limit, uint32_t rate_limit, bool rw_mode, uint32_t log_period); +typedef struct { + knotd_mod_t *mod; + knotd_qdata_t *qdata; // For rate limiting. + knotd_query_proto_t proto; // For time limiting. +} rrl_log_params_t; + /*! * \brief Query the RRL table for accept or deny, when the rate limit is reached. * @@ -44,12 +50,12 @@ rrl_table_t *rrl_create(size_t size, uint32_t instant_limit, uint32_t rate_limit * * \param rrl RRL table. * \param remote Source address. - * \param mod Query module (needed for logging). + * \param log Logging parameters (can be NULL). * * \retval KNOT_EOK if passed. * \retval KNOT_ELIMIT when the limit is reached. */ -int rrl_query(rrl_table_t *rrl, const struct sockaddr_storage *remote, knotd_mod_t *mod); +int rrl_query(rrl_table_t *rrl, const struct sockaddr_storage *remote, rrl_log_params_t *log); /*! * \brief Update the RRL table. diff --git a/src/knot/modules/rrl/rrl.c b/src/knot/modules/rrl/rrl.c index 72c1d33e9b..9fcb8724dc 100644 --- a/src/knot/modules/rrl/rrl.c +++ b/src/knot/modules/rrl/rrl.c @@ -104,7 +104,8 @@ static knotd_proto_state_t protolimit_start(knotd_proto_state_t state, } // Check if the packet is limited. - if (rrl_query(ctx->time_table, params->remote, mod) != KNOT_EOK) { + rrl_log_params_t log = { .mod = mod, .proto = params->proto }; + if (rrl_query(ctx->time_table, params->remote, &log) != KNOT_EOK) { thrd->skip = true; knotd_mod_stats_incr(mod, params->thread_id, 2, 0, 1); return ctx->dry_run ? state : KNOTD_PROTO_STATE_BLOCK; @@ -168,7 +169,8 @@ static knotd_state_t ratelimit_apply(knotd_state_t state, knot_pkt_t *pkt, return state; } - if (rrl_query(ctx->rate_table, knotd_qdata_remote_addr(qdata), mod) == KNOT_EOK) { + rrl_log_params_t log = { .mod = mod, .qdata = qdata }; + if (rrl_query(ctx->rate_table, knotd_qdata_remote_addr(qdata), &log) == KNOT_EOK) { // Rate limiting not applied. return state; } -- GitLab