mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-04-24 00:00:05 +08:00
Merge commit '86cc97e55fe346502462284d2e636a2b3708163e' as 'Sources/OpenVPN3'
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_SERVER_VPNSERVPOOL_H
|
||||
#define OPENVPN_SERVER_VPNSERVPOOL_H
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <cstdint> // for std::uint32_t
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/rc.hpp>
|
||||
#include <openvpn/common/arraysize.hpp>
|
||||
#include <openvpn/server/vpnservnetblock.hpp>
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
#include <openvpn/addr/route.hpp>
|
||||
#include <openvpn/addr/pool.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace VPNServerPool {
|
||||
|
||||
OPENVPN_EXCEPTION(vpn_serv_pool_error);
|
||||
|
||||
struct IP46
|
||||
{
|
||||
void add_routes(std::vector<IP::Route>& rtvec)
|
||||
{
|
||||
if (ip4.defined())
|
||||
rtvec.emplace_back(ip4, ip4.size());
|
||||
if (ip6.defined())
|
||||
rtvec.emplace_back(ip6, ip6.size());
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << '[' << ip4 << ' ' << ip6 << ']';
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool defined() const
|
||||
{
|
||||
return ip4.defined() || ip6.defined();
|
||||
}
|
||||
|
||||
IP::Addr ip4;
|
||||
IP::Addr ip6;
|
||||
};
|
||||
|
||||
class Pool : public VPNServerNetblock
|
||||
{
|
||||
public:
|
||||
enum Flags {
|
||||
IPv4_DEPLETION=(1<<0),
|
||||
IPv6_DEPLETION=(1<<1),
|
||||
};
|
||||
|
||||
Pool(const OptionList& opt)
|
||||
: VPNServerNetblock(init_snb_from_opt(opt))
|
||||
{
|
||||
if (configured(opt, "server"))
|
||||
{
|
||||
pool4.add_range(netblock4().clients);
|
||||
pool6.add_range(netblock6().clients);
|
||||
}
|
||||
}
|
||||
|
||||
// returns flags
|
||||
unsigned int acquire(IP46& addr_pair, const bool request_ipv6)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
unsigned int flags = 0;
|
||||
if (!pool4.acquire_addr(addr_pair.ip4))
|
||||
flags |= IPv4_DEPLETION;
|
||||
if (request_ipv6 && netblock6().defined())
|
||||
{
|
||||
if (!pool6.acquire_addr(addr_pair.ip6))
|
||||
flags |= IPv6_DEPLETION;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
void release(IP46& addr_pair)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
if (addr_pair.ip4.defined())
|
||||
pool4.release_addr(addr_pair.ip4);
|
||||
if (addr_pair.ip6.defined())
|
||||
pool6.release_addr(addr_pair.ip6);
|
||||
}
|
||||
|
||||
private:
|
||||
static VPNServerNetblock init_snb_from_opt(const OptionList& opt)
|
||||
{
|
||||
if (configured(opt, "server"))
|
||||
return VPNServerNetblock(opt, "server", false, 0);
|
||||
else if (configured(opt, "ifconfig"))
|
||||
return VPNServerNetblock(opt, "ifconfig", false, 0);
|
||||
else
|
||||
throw vpn_serv_pool_error("one of 'server' or 'ifconfig' directives is required");
|
||||
}
|
||||
|
||||
static bool configured(const OptionList& opt,
|
||||
const std::string& opt_name)
|
||||
{
|
||||
return opt.exists(opt_name) || opt.exists(opt_name + "-ipv6");
|
||||
}
|
||||
|
||||
std::mutex mutex;
|
||||
|
||||
IP::Pool pool4;
|
||||
IP::Pool pool6;
|
||||
};
|
||||
|
||||
class IP46AutoRelease : public IP46, public RC<thread_safe_refcount>
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<IP46AutoRelease> Ptr;
|
||||
|
||||
IP46AutoRelease(Pool* pool_arg)
|
||||
: pool(pool_arg)
|
||||
{
|
||||
}
|
||||
|
||||
~IP46AutoRelease()
|
||||
{
|
||||
if (pool)
|
||||
pool->release(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
Pool* pool;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user