Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/helpers/BaseChatMesh.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <helpers/BaseChatMesh.h>
#include <helpers/LoginTimeout.h>
#include <Utils.h>

#ifndef SERVER_RESPONSE_DELAY
Expand Down Expand Up @@ -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;
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/helpers/LoginTimeout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <stdint.h>

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
20 changes: 20 additions & 0 deletions test/test_login_timeout/test_login_timeout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <gtest/gtest.h>

#include <helpers/LoginTimeout.h>

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();
}