summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemon/defer.c18
-rw-r--r--lib/kru.h8
-rw-r--r--lib/kru.inc.c12
3 files changed, 25 insertions, 13 deletions
diff --git a/daemon/defer.c b/daemon/defer.c
index 7c09751c..a4a58e5b 100644
--- a/daemon/defer.c
+++ b/daemon/defer.c
@@ -48,6 +48,7 @@ static bool using_avx2(void)
void defer_account(uint64_t nsec, union kr_sockaddr addr) {
_Alignas(16) uint8_t key[16] = {0, };
uint16_t max_load = 0;
+ uint8_t prefix = 0;
if (defer_sample_state.addr.ip.sa_family == AF_INET6) {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&defer_sample_state.addr.ip;
memcpy(key, &ipv6->sin6_addr, 16);
@@ -58,7 +59,7 @@ void defer_account(uint64_t nsec, union kr_sockaddr addr) {
}
max_load = KRU.load_multi_prefix_max((struct kru *)defer->kru, kr_now(),
- 1, key, V6_PREFIXES, prices, V6_PREFIXES_CNT);
+ 1, key, V6_PREFIXES, prices, V6_PREFIXES_CNT, &prefix);
} else if (defer_sample_state.addr.ip.sa_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)&defer_sample_state.addr.ip;
memcpy(key, &ipv4->sin_addr, 4); // TODO append port?
@@ -69,11 +70,11 @@ void defer_account(uint64_t nsec, union kr_sockaddr addr) {
}
max_load = KRU.load_multi_prefix_max((struct kru *)defer->kru, kr_now(),
- 0, key, V4_PREFIXES, prices, V4_PREFIXES_CNT);
+ 0, key, V4_PREFIXES, prices, V4_PREFIXES_CNT, &prefix);
}
- kr_log_notice(DEVEL, "%8.3f ms for %s, load: %d\n", nsec / 1000000.0,
- kr_straddr(&defer_sample_state.addr.ip), max_load);
+ kr_log_notice(DEVEL, "%8.3f ms for %s, load: %d on /%d\n", nsec / 1000000.0,
+ kr_straddr(&defer_sample_state.addr.ip), max_load, prefix);
}
/// Determine whether the request should be deferred during unwrapping.
@@ -88,26 +89,27 @@ static enum protolayer_iter_cb_result pl_defer_unwrap(
_Alignas(16) uint8_t key[16] = {0, };
uint16_t max_load = 0;
+ uint8_t prefix = 0;
if (ctx->comm->comm_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)ctx->comm->comm_addr;
memcpy(key, &ipv6->sin6_addr, 16);
max_load = KRU.load_multi_prefix_max((struct kru *)defer->kru, kr_now(),
- 1, key, V6_PREFIXES, NULL, V6_PREFIXES_CNT);
+ 1, key, V6_PREFIXES, NULL, V6_PREFIXES_CNT, &prefix);
} else if (ctx->comm->comm_addr->sa_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)ctx->comm->comm_addr;
memcpy(key, &ipv4->sin_addr, 4); // TODO append port?
max_load = KRU.load_multi_prefix_max((struct kru *)defer->kru, kr_now(),
- 0, key, V4_PREFIXES, NULL, V4_PREFIXES_CNT);
+ 0, key, V4_PREFIXES, NULL, V4_PREFIXES_CNT, &prefix);
}
int threshold_index = 0; // 0: synchronous
for (; LOADS_THRESHOLDS[threshold_index] < max_load; threshold_index++);
- kr_log_notice(DEVEL, "DEFER | addr: %s, load: %d, queue: %d\n",
+ kr_log_notice(DEVEL, "DEFER | addr: %s, load: %d on /%d, queue: %d\n",
kr_straddr(ctx->comm->src_addr),
- max_load, threshold_index);
+ max_load, prefix, threshold_index);
if (threshold_index == 0)
return protolayer_continue(ctx);
diff --git a/lib/kru.h b/lib/kru.h
index 0a3a8e80..b36feeb5 100644
--- a/lib/kru.h
+++ b/lib/kru.h
@@ -70,16 +70,18 @@ struct kru_api {
/// Updates KRU only if no query is blocked, unless a race condition occurs --
/// in such a case all longer prefixes might have been updated.
/// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace.
- /// If zero is returned, *max_load_out is set to the maximum of final values of the involved counters normalized to the limit 2^16.
+ /// If zero is returned, *max_load_out (unless NULL) is set to
+ /// the maximum of final values of the involved counters normalized to the limit 2^16.
uint8_t (*limited_multi_prefix_or)(struct kru *kru, uint32_t time_now,
uint8_t namespace, uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint16_t *max_load_out);
/// Multiple queries based on different prefixes of a single key.
- /// Returns the maximum of final values of the involved counters normalized to the limit 2^16.
+ /// Returns the maximum of final values of the involved counters normalized to the limit 2^16
+ /// and stores the corresponding prefix (value in prefixes) to *prefix_out (unless NULL).
/// Set prices to NULL to skip updating; otherwise, KRU is always updated, using maximal allowed value on overflow.
/// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace.
uint16_t (*load_multi_prefix_max)(struct kru *kru, uint32_t time_now,
- uint8_t namespace, uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt);
+ uint8_t namespace, uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint8_t *prefix_out);
};
// The functions are stored this way to make it easier to switch
diff --git a/lib/kru.inc.c b/lib/kru.inc.c
index b67d3237..53a9f97b 100644
--- a/lib/kru.inc.c
+++ b/lib/kru.inc.c
@@ -565,7 +565,7 @@ static uint8_t kru_limited_multi_prefix_or(struct kru *kru, uint32_t time_now, u
}
static uint16_t kru_load_multi_prefix_max(struct kru *kru, uint32_t time_now, uint8_t namespace,
- uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt)
+ uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint8_t *prefix_out)
{
struct query_ctx ctx[queries_cnt];
@@ -583,10 +583,18 @@ static uint16_t kru_load_multi_prefix_max(struct kru *kru, uint32_t time_now, ui
}
}
+ uint8_t prefix = 0;
uint16_t max_load = 0;
for (size_t i = 0; i < queries_cnt; i++) {
- max_load = MAX(max_load, ctx[i].final_load_value);
+ if (max_load < ctx[i].final_load_value) {
+ max_load = ctx[i].final_load_value;
+ prefix = prefixes[i];
+ }
+ }
+ if (prefix_out) {
+ *prefix_out = prefix;
}
+
return max_load;
}