From 607d9e07e2df14c28cc7f9c355948e79df11c14e Mon Sep 17 00:00:00 2001 From: Alexander Hoffer Date: Mon, 20 Jul 2026 11:14:03 +0100 Subject: [PATCH] fix: budget flood response for direct repeater login --- src/helpers/BaseChatMesh.cpp | 5 ++++- src/helpers/LoginTimeout.h | 16 +++++++++++++++ .../test_login_timeout/test_login_timeout.cpp | 20 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/helpers/LoginTimeout.h create mode 100644 test/test_login_timeout/test_login_timeout.cpp diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 972a97e9e6..ae43cc811c 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -1,4 +1,5 @@ #include +#include #include #ifndef SERVER_RESPONSE_DELAY @@ -597,7 +598,9 @@ int BaseChatMesh::sendLogin(const ContactInfo& recipient, const char* password, return MSG_SEND_SENT_FLOOD; } else { sendDirect(pkt, recipient.out_path, recipient.out_path_len); - est_timeout = calcDirectTimeoutMillisFor(t, recipient.out_path_len); + const uint32_t direct_timeout = calcDirectTimeoutMillisFor(t, recipient.out_path_len); + est_timeout = mesh::selectDirectLoginTimeout(recipient.type == ADV_TYPE_REPEATER, direct_timeout, + calcFloodTimeoutMillisFor(t)); return MSG_SEND_SENT_DIRECT; } } diff --git a/src/helpers/LoginTimeout.h b/src/helpers/LoginTimeout.h new file mode 100644 index 0000000000..b15c62eb14 --- /dev/null +++ b/src/helpers/LoginTimeout.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace mesh { + +// Direct logins to repeaters receive a flood-routed response because the login +// request does not carry a return path. Both timeout estimates cover a complete +// exchange, so use the larger estimate rather than adding them together. +inline uint32_t selectDirectLoginTimeout(bool reply_uses_flood, uint32_t direct_timeout, + uint32_t flood_timeout) { + if (reply_uses_flood && flood_timeout > direct_timeout) return flood_timeout; + return direct_timeout; +} + +} // namespace mesh diff --git a/test/test_login_timeout/test_login_timeout.cpp b/test/test_login_timeout/test_login_timeout.cpp new file mode 100644 index 0000000000..020a9f621b --- /dev/null +++ b/test/test_login_timeout/test_login_timeout.cpp @@ -0,0 +1,20 @@ +#include + +#include + +TEST(LoginTimeout, UsesFloodBudgetForRepeaterResponseWhenLonger) { + EXPECT_EQ(mesh::selectDirectLoginTimeout(true, 2200, 3700), 3700); +} + +TEST(LoginTimeout, KeepsDirectBudgetWhenItIsLonger) { + EXPECT_EQ(mesh::selectDirectLoginTimeout(true, 4200, 3700), 4200); +} + +TEST(LoginTimeout, KeepsDirectBudgetWhenResponseDoesNotFlood) { + EXPECT_EQ(mesh::selectDirectLoginTimeout(false, 2200, 3700), 2200); +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}