Skip to content

Commit

Permalink
Use new Session_Manager::find_some() efficiently
Browse files Browse the repository at this point in the history
  • Loading branch information
reneme committed Mar 28, 2023
1 parent eeb2f9e commit 95b908e
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 13 deletions.
41 changes: 31 additions & 10 deletions src/lib/tls/tls_session_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,35 @@ std::optional<Session> Session_Manager::retrieve(const Session_Handle& handle,
}
}

std::vector<Session_with_Handle> Session_Manager::find(const Server_Information& info,
Callbacks& callbacks,
const Policy& policy)
{
lock_guard_type<recursive_mutex_type> lk(mutex());

const auto max_sessions = std::max(policy.maximum_session_tickets_per_client_hello(), size_t(1000));
auto sessions_and_handles = find_some(info, max_sessions);

std::vector<Session_with_Handle> Session_Manager::find_and_filter(const Server_Information& info,
Callbacks& callbacks,
const Policy& policy)
{
// A value of '0' means: No policy restrictions. Session ticket lifetimes as
// communicated by the server apply regardless.
const std::chrono::seconds policy_lifetime =
(policy.session_ticket_lifetime().count() > 0)
? policy.session_ticket_lifetime()
: std::chrono::seconds::max();

if(!sessions_and_handles.empty())
const size_t max_sessions_hint = std::max(policy.maximum_session_tickets_per_client_hello(), size_t(1));
const auto now = callbacks.tls_current_timestamp();

// An arbitrary number of loop iterations to perform before giving up
// to avoid a potential endless loop with a misbehaving session manager.
constexpr unsigned int max_attempts = 10;
std::vector<Session_with_Handle> sessions_and_handles;

// Query the session manager implementation for new sessions until at least
// one session passes the filter or no more sessions are found.
for(unsigned int attempt = 0; attempt < max_attempts && sessions_and_handles.empty(); ++attempt)
{
const auto now = callbacks.tls_current_timestamp();
sessions_and_handles = find_some(info, max_sessions_hint);

// ... underlying implementation didn't find anything. Early exit.
if(sessions_and_handles.empty())
{ break; }

// TODO: C++20, use std::ranges::remove_if() once XCode and Android NDK caught up.
sessions_and_handles.erase(
Expand Down Expand Up @@ -157,6 +167,17 @@ std::vector<Session_with_Handle> Session_Manager::find(const Server_Information&
}), sessions_and_handles.end());
}

return sessions_and_handles;
}

std::vector<Session_with_Handle> Session_Manager::find(const Server_Information& info,
Callbacks& callbacks,
const Policy& policy)
{
lock_guard_type<recursive_mutex_type> lk(mutex());

auto sessions_and_handles = find_and_filter(info, callbacks, policy);

// std::vector::resize() cannot be used as the vector's members aren't
// default constructible.
const auto session_limit = policy.maximum_session_tickets_per_client_hello();
Expand Down
5 changes: 5 additions & 0 deletions src/lib/tls/tls_session_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ class BOTAN_PUBLIC_API(3, 0) Session_Manager
*/
recursive_mutex_type& mutex() { return m_mutex; }

private:
std::vector<Session_with_Handle> find_and_filter(const Server_Information& info,
Callbacks& callbacks,
const Policy& policy);

protected:
std::shared_ptr<RandomNumberGenerator> m_rng;

Expand Down
4 changes: 4 additions & 0 deletions src/tests/test_tls_rfc8448.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,7 @@ class Test_TLS_RFC8448_Client : public Test_TLS_RFC8448
"tls_inspect_handshake_msg_client_hello",
"tls_modify_extensions_client_hello",
"tls_generate_ephemeral_key",
"tls_current_timestamp",
});

result.test_eq("TLS client hello", ctx->pull_send_buffer(), vars.get_req_bin("Record_ClientHello_1"));
Expand Down Expand Up @@ -1251,6 +1252,7 @@ class Test_TLS_RFC8448_Client : public Test_TLS_RFC8448
"tls_inspect_handshake_msg_client_hello",
"tls_modify_extensions_client_hello",
"tls_generate_ephemeral_key",
"tls_current_timestamp",
});

result.test_eq("TLS client hello (1)", ctx->pull_send_buffer(), vars.get_req_bin("Record_ClientHello_1"));
Expand Down Expand Up @@ -1361,6 +1363,7 @@ class Test_TLS_RFC8448_Client : public Test_TLS_RFC8448
"tls_inspect_handshake_msg_client_hello",
"tls_modify_extensions_client_hello",
"tls_generate_ephemeral_key",
"tls_current_timestamp",
});

result.test_eq("Client Hello", ctx->pull_send_buffer(), vars.get_req_bin("Record_ClientHello_1"));
Expand Down Expand Up @@ -1458,6 +1461,7 @@ class Test_TLS_RFC8448_Client : public Test_TLS_RFC8448
"tls_inspect_handshake_msg_client_hello",
"tls_modify_extensions_client_hello",
"tls_generate_ephemeral_key",
"tls_current_timestamp",
});
}),

Expand Down
6 changes: 3 additions & 3 deletions src/tests/test_tls_session_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class Session_Manager_Policy : public Botan::TLS::Policy
size_t maximum_session_tickets_per_client_hello() const override { return session_limit; }

public:
size_t session_limit = 0; /// no limit
size_t session_limit = 1000; // basically 'no limit'
bool allow_session_reuse = true;
};

Expand Down Expand Up @@ -1027,8 +1027,8 @@ std::vector<Test::Result> tls_session_manager_expiry()
plcy.session_limit = 3;
result.test_is_eq("find three", mgr->find(server_info, cbs, plcy).size(), size_t(plcy.session_limit));

plcy.session_limit = 0;
result.test_is_eq("unlimited", mgr->find(server_info, cbs, plcy).size(), size_t(5));
plcy.session_limit = 10;
result.test_is_eq("find all five", mgr->find(server_info, cbs, plcy).size(), size_t(5));
}),

#if defined(BOTAN_HAS_TLS_13)
Expand Down

0 comments on commit 95b908e

Please sign in to comment.