OpenVPN 3 Core Library
Loading...
Searching...
No Matches
pool.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#ifndef OPENVPN_ADDR_POOL_H
13#define OPENVPN_ADDR_POOL_H
14
15#include <deque>
16#include <optional>
17#include <string>
18#include <unordered_map>
19
21#include <openvpn/addr/ip.hpp>
23
24namespace openvpn::IP {
25
26// Maintain a pool of IP addresses.
27// Should be IP::Addr, IPv4::Addr, or IPv6::Addr.
28template <typename ADDR>
30{
31 public:
36 void add_range(const RangeType<ADDR> &range)
37 {
38 for (const auto &address : range)
39 {
41 }
42 }
43
44 // Add single address to pool (pool will own the address).
45 void add_addr(const ADDR &addr)
46 {
47 auto [iter, inserted] = map.try_emplace(addr, false);
48 if (inserted)
49 {
50 freelist.push_back(addr);
51 }
52 }
53
58 [[nodiscard]] size_t n_in_use() const noexcept
59 {
60 return map.size() - freelist.size();
61 }
62
67 [[nodiscard]] size_t n_free() const noexcept
68 {
69 return freelist.size();
70 }
71
72 // Acquire an address from pool. Returns true if successful,
73 // with address placed in dest, or false if pool depleted.
74 bool acquire_addr(ADDR &dest)
75 {
76 while (true)
77 {
79 if (freelist.empty())
80 return false;
81 const ADDR &a = freelist.front();
82 auto e = map.find(a);
83 if (e == map.end()) // any address in freelist must exist in map
84 throw Exception("PoolType: address in freelist doesn't exist in map");
85 if (!e->second)
86 {
87 e->second = true;
88 dest = a;
89 freelist.pop_front();
90 return true;
91 }
92 freelist.pop_front();
93 }
94 }
95
106 bool acquire_specific_addr(const ADDR &addr)
107 {
108 auto optional_iterator = is_address_available(addr);
109 if (optional_iterator)
110 {
111 (*optional_iterator)->second = true;
112 return true;
113 }
114 return false;
115 }
116
117 // Return a previously acquired address to the pool. Does nothing if
118 // (a) the address is owned by the pool and marked as free, or
119 // (b) the address is not owned by the pool.
120 void release_addr(const ADDR &addr)
121 {
122 auto optional_iterator = is_address_in_use(addr);
123 if (optional_iterator)
124 {
125 freelist.push_back(addr);
126 (*optional_iterator)->second = false;
127 }
128 }
129
130 // Override to refill freelist on demand
131 virtual void freelist_fill()
132 {
133 }
134
135 std::string to_string() const
136 {
137 std::string ret;
138 for (const auto &e : map)
139 {
140 if (e.second)
141 {
142 ret += e.first.to_string();
143 ret += '\n';
144 }
145 }
146 return ret;
147 }
148
149 virtual ~PoolType() = default;
150
151 private:
152 std::deque<ADDR> freelist;
153 std::unordered_map<ADDR, bool> map;
154
160 auto is_address_available(const ADDR &addr) -> std::optional<decltype(map.begin())> // Easy decltype for map iterator
161 {
162 auto it = map.find(addr);
163 if (it != map.end() && !it->second)
164 return it;
165 return std::nullopt;
166 }
167
173 auto is_address_in_use(const ADDR &addr) -> std::optional<decltype(map.begin())> // Easy decltype for map iterator
174 {
175 if (auto it = map.find(addr); it != map.end())
176 return it;
177 return std::nullopt;
178 }
179};
180
182} // namespace openvpn::IP
183
184#endif
size_t n_free() const noexcept
Returns number of free pool addresses.
Definition pool.hpp:67
void add_range(const RangeType< ADDR > &range)
Adds range of addresses to pool (pool will own the addresses).
Definition pool.hpp:36
std::string to_string() const
Definition pool.hpp:135
auto is_address_available(const ADDR &addr) -> std::optional< decltype(map.begin())>
Checks if address is available (free)
Definition pool.hpp:160
void add_addr(const ADDR &addr)
Definition pool.hpp:45
bool acquire_addr(ADDR &dest)
Definition pool.hpp:74
virtual ~PoolType()=default
bool acquire_specific_addr(const ADDR &addr)
Acquires a specific address from the pool.
Definition pool.hpp:106
std::deque< ADDR > freelist
Definition pool.hpp:152
void release_addr(const ADDR &addr)
Definition pool.hpp:120
size_t n_in_use() const noexcept
Returns number of pool addresses currently in use.
Definition pool.hpp:58
std::unordered_map< ADDR, bool > map
Definition pool.hpp:153
virtual void freelist_fill()
Definition pool.hpp:131
auto is_address_in_use(const ADDR &addr) -> std::optional< decltype(map.begin())>
Checks if address is in use.
Definition pool.hpp:173
designed to represent and manage a range of IP addresses.
Definition range.hpp:65
std::string ret
remote_address address