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:
32 PoolType() = default;
33
38 void add_range(const RangeType<ADDR> &range)
39 {
40 for (const auto &address : range)
41 {
43 }
44 }
45
46 // Add single address to pool (pool will own the address).
47 void add_addr(const ADDR &addr)
48 {
49 auto [iter, inserted] = map.try_emplace(addr, false);
50 if (inserted)
51 {
52 freelist.push_back(addr);
53 }
54 }
55
60 [[nodiscard]] size_t n_in_use() const noexcept
61 {
62 return map.size() - freelist.size();
63 }
64
69 [[nodiscard]] size_t n_free() const noexcept
70 {
71 return freelist.size();
72 }
73
74 // Acquire an address from pool. Returns true if successful,
75 // with address placed in dest, or false if pool depleted.
76 bool acquire_addr(ADDR &dest)
77 {
78 while (true)
79 {
81 if (freelist.empty())
82 return false;
83 const ADDR &a = freelist.front();
84 auto e = map.find(a);
85 if (e == map.end()) // any address in freelist must exist in map
86 throw Exception("PoolType: address in freelist doesn't exist in map");
87 if (!e->second)
88 {
89 e->second = true;
90 dest = a;
91 freelist.pop_front();
92 return true;
93 }
94 freelist.pop_front();
95 }
96 }
97
108 bool acquire_specific_addr(const ADDR &addr)
109 {
110 auto optional_iterator = is_address_available(addr);
111 if (optional_iterator)
112 {
113 (*optional_iterator)->second = true;
114 return true;
115 }
116 return false;
117 }
118
119 // Return a previously acquired address to the pool. Does nothing if
120 // (a) the address is owned by the pool and marked as free, or
121 // (b) the address is not owned by the pool.
122 void release_addr(const ADDR &addr)
123 {
124 auto optional_iterator = is_address_in_use(addr);
125 if (optional_iterator)
126 {
127 freelist.push_back(addr);
128 (*optional_iterator)->second = false;
129 }
130 }
131
132 // Override to refill freelist on demand
133 virtual void freelist_fill()
134 {
135 }
136
137 std::string to_string() const
138 {
139 std::string ret;
140 for (const auto &e : map)
141 {
142 if (e.second)
143 {
144 ret += e.first.to_string();
145 ret += '\n';
146 }
147 }
148 return ret;
149 }
150
151 virtual ~PoolType() = default;
152
153 private:
154 std::deque<ADDR> freelist;
155 std::unordered_map<ADDR, bool> map;
156
162 auto is_address_available(const ADDR &addr) -> std::optional<decltype(map.begin())> // Easy decltype for map iterator
163 {
164 auto it = map.find(addr);
165 if (it != map.end() && !it->second)
166 return it;
167 return std::nullopt;
168 }
169
175 auto is_address_in_use(const ADDR &addr) -> std::optional<decltype(map.begin())> // Easy decltype for map iterator
176 {
177 if (auto it = map.find(addr); it != map.end())
178 return it;
179 return std::nullopt;
180 }
181};
182
184} // namespace openvpn::IP
185
186#endif
size_t n_free() const noexcept
Returns number of free pool addresses.
Definition pool.hpp:69
void add_range(const RangeType< ADDR > &range)
Adds range of addresses to pool (pool will own the addresses).
Definition pool.hpp:38
std::string to_string() const
Definition pool.hpp:137
auto is_address_available(const ADDR &addr) -> std::optional< decltype(map.begin())>
Checks if address is available (free)
Definition pool.hpp:162
void add_addr(const ADDR &addr)
Definition pool.hpp:47
bool acquire_addr(ADDR &dest)
Definition pool.hpp:76
virtual ~PoolType()=default
bool acquire_specific_addr(const ADDR &addr)
Acquires a specific address from the pool.
Definition pool.hpp:108
std::deque< ADDR > freelist
Definition pool.hpp:154
void release_addr(const ADDR &addr)
Definition pool.hpp:122
size_t n_in_use() const noexcept
Returns number of pool addresses currently in use.
Definition pool.hpp:60
std::unordered_map< ADDR, bool > map
Definition pool.hpp:155
virtual void freelist_fill()
Definition pool.hpp:133
auto is_address_in_use(const ADDR &addr) -> std::optional< decltype(map.begin())>
Checks if address is in use.
Definition pool.hpp:175
designed to represent and manage a range of IP addresses.
Definition range.hpp:65
PoolType< IP::Addr > Pool
Definition pool.hpp:183
remote_address address
std::string ret