• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.55
/src/lib/tls/tls_session_manager_memory.cpp
1
/**
2
 * TLS Session Management
3
 * (C) 2011,2012 Jack Lloyd
4
 *     2023 René Meusel - Rohde & Schwarz Cybersecurity
5
 *
6
 * Botan is released under the Simplified BSD License (see license.txt)
7
 */
8

9
#include <botan/tls_session_manager_memory.h>
10

11
#include <botan/rng.h>
12
#include <botan/internal/stl_util.h>
13

14
#include <algorithm>
15

16
namespace Botan::TLS {
17

18
Session_Manager_In_Memory::Session_Manager_In_Memory(const std::shared_ptr<RandomNumberGenerator>& rng,
2,002✔
19
                                                     size_t max_sessions) :
2,002✔
20
      Session_Manager(rng), m_max_sessions(max_sessions) {
2,002✔
21
   if(max_sessions > 0) {
2,002✔
22
      m_fifo.emplace();
2,002✔
23
   }
24
}
2,002✔
25

26
void Session_Manager_In_Memory::store(const Session& session, const Session_Handle& handle) {
1,447✔
27
   // TODO: C++20 allows CTAD for template aliases (read: lock_guard_type), so
28
   //       technically we should be able to omit the explicit mutex type.
29
   //       Unfortuately clang does not agree, yet.
30
   lock_guard_type<recursive_mutex_type> lk(mutex());
1,447✔
31

32
   if(m_fifo.has_value()) {
1,447✔
33
      while(m_sessions.size() >= capacity()) {
1,453✔
34
         BOTAN_ASSERT_NOMSG(m_sessions.size() <= m_fifo->size());
6✔
35
         m_sessions.erase(m_fifo->front());
6✔
36
         m_fifo->pop_front();
6✔
37
      }
38
   }
39

40
   // Generate a random session ID if the peer did not provide one. Note that
41
   // this ID is just for internal use and won't be returned on ::find().
42
   auto id = handle.id().value_or(m_rng->random_vec<Session_ID>(32));
3,071✔
43
   m_sessions.emplace(id, Session_with_Handle{session, handle});
2,894✔
44

45
   if(m_fifo.has_value()) {
1,447✔
46
      m_fifo->emplace_back(std::move(id));
1,447✔
47
   }
48
}
1,447✔
49

50
std::optional<Session> Session_Manager_In_Memory::retrieve_one(const Session_Handle& handle) {
91✔
51
   lock_guard_type<recursive_mutex_type> lk(mutex());
91✔
52

53
   if(auto id = handle.id()) {
91✔
54
      const auto session = m_sessions.find(id.value());
84✔
55
      if(session != m_sessions.end()) {
84✔
56
         return session->second.session;
59✔
57
      }
58
   }
59✔
59

60
   return std::nullopt;
32✔
61
}
91✔
62

63
std::vector<Session_with_Handle> Session_Manager_In_Memory::find_some(const Server_Information& info,
1,474✔
64
                                                                      const size_t max_sessions_hint) {
65
   BOTAN_UNUSED(max_sessions_hint);
1,474✔
66

67
   lock_guard_type<recursive_mutex_type> lk(mutex());
1,474✔
68

69
   std::vector<Session_with_Handle> found_sessions;
1,474✔
70
   // TODO: std::copy_if?
71
   for(const auto& [_, session_and_handle] : m_sessions) {
2,210✔
72
      if(session_and_handle.session.server_info() == info) {
736✔
73
         found_sessions.emplace_back(session_and_handle);
736✔
74
      }
75
   }
76

77
   return found_sessions;
1,474✔
78
}
1,474✔
79

80
size_t Session_Manager_In_Memory::remove(const Session_Handle& handle) {
470✔
81
   lock_guard_type<recursive_mutex_type> lk(mutex());
470✔
82
   return remove_internal(handle);
470✔
83
}
470✔
84

85
size_t Session_Manager_In_Memory::remove_internal(const Session_Handle& handle) {
576✔
86
   return std::visit(overloaded{
1,152✔
87
                        // We deliberately leave the deleted session in m_fifo. Finding it would be
88
                        // another O(n) operation. Instead, purging will run in a loop and skip m_fifo
89
                        // entries that were not found anymore.
90
                        [&](const Session_Ticket& ticket) -> size_t {
453✔
91
                           // TODO: This is an O(n) operation. Typically, the Session_Manager will
92
                           //       not contain a plethora of sessions and this should be fine. If
93
                           //       it's not, we'll need to consider another index on tickets.
94
                           //
95
                           // TODO: C++20's std::erase_if should return the number of erased items
96
                           //
97
                           // Unfortunately, at the time of this writing Android NDK shipped with
98
                           // a std::erase_if that returns void. Hence, the workaround.
99
                           const auto before = m_sessions.size();
453✔
100
                           std::erase_if(m_sessions, [&](const auto& item) {
453✔
101
                              const auto& [_unused1, session_and_handle] = item;
410✔
102
                              const auto& [_unused2, this_handle] = session_and_handle;
410✔
103
                              return this_handle.is_ticket() && this_handle.ticket().value() == ticket;
600✔
104
                           });
105
                           return before - m_sessions.size();
453✔
106
                        },
107
                        [&](const Session_ID& id) -> size_t { return m_sessions.erase(id); },
18✔
108
                        [&](const Opaque_Session_Handle&) -> size_t {
105✔
109
                           if(auto id = handle.id()) {
105✔
110
                              auto removed = remove_internal(id.value());
12✔
111
                              if(removed > 0) {
4✔
112
                                 return removed;
3✔
113
                              }
114
                           }
3✔
115

116
                           if(auto ticket = handle.ticket()) {
102✔
117
                              return remove_internal(ticket.value());
306✔
118
                           }
102✔
119

120
                           return 0;
×
121
                        },
122
                     },
123
                     handle.get());
1,152✔
124
}
125

126
size_t Session_Manager_In_Memory::remove_all() {
9✔
127
   lock_guard_type<recursive_mutex_type> lk(mutex());
9✔
128

129
   const auto sessions = m_sessions.size();
9✔
130
   m_sessions.clear();
9✔
131
   if(m_fifo.has_value()) {
9✔
132
      m_fifo->clear();
9✔
133
   }
134

135
   return sessions;
9✔
136
}
9✔
137

138
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc