mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-02-11 00:00:08 +08:00
166 lines
5.5 KiB
C++
166 lines
5.5 KiB
C++
// 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/>.
|
|
|
|
// Create a special transport factory that persists an existing
|
|
// transport client. This is used to preserve the transport
|
|
// socket when other client components are restarted after
|
|
// a RELAY message is received from the server.
|
|
|
|
#ifndef OPENVPN_TRANSPORT_CLIENT_RELAY_H
|
|
#define OPENVPN_TRANSPORT_CLIENT_RELAY_H
|
|
|
|
#include <memory>
|
|
|
|
#include <openvpn/transport/client/transbase.hpp>
|
|
|
|
namespace openvpn {
|
|
class TransportRelayFactory : public TransportClientFactory
|
|
{
|
|
public:
|
|
TransportRelayFactory(openvpn_io::io_context& io_context,
|
|
TransportClient::Ptr transport,
|
|
TransportClientParent* old_parent)
|
|
: io_context_(io_context),
|
|
transport_(std::move(transport)),
|
|
null_parent_(new NullParent(old_parent))
|
|
{
|
|
// Temporarily point transport to our null parent
|
|
transport_->transport_reparent(null_parent_.get());
|
|
}
|
|
|
|
class TransportClientNull : public TransportClient
|
|
{
|
|
public:
|
|
TransportClientNull(TransportClient* old)
|
|
: endpoint_(old->server_endpoint_addr()),
|
|
protocol_(old->transport_protocol())
|
|
{
|
|
old->server_endpoint_info(host_, port_, proto_, ip_addr_);
|
|
}
|
|
|
|
private:
|
|
virtual void transport_start() {}
|
|
virtual void stop() {}
|
|
virtual bool transport_send_const(const Buffer& buf) { return false; }
|
|
virtual bool transport_send(BufferAllocated& buf) { return false; }
|
|
virtual bool transport_send_queue_empty() { return false; }
|
|
virtual bool transport_has_send_queue() { return false; }
|
|
virtual unsigned int transport_send_queue_size() { return 0; }
|
|
virtual void transport_stop_requeueing() { }
|
|
virtual void reset_align_adjust(const size_t align_adjust) {}
|
|
virtual void transport_reparent(TransportClientParent* parent) {}
|
|
|
|
virtual IP::Addr server_endpoint_addr() const
|
|
{
|
|
return endpoint_;
|
|
}
|
|
|
|
virtual Protocol transport_protocol() const
|
|
{
|
|
return protocol_;
|
|
}
|
|
|
|
virtual void server_endpoint_info(std::string& host, std::string& port, std::string& proto, std::string& ip_addr) const
|
|
{
|
|
host = host_;
|
|
port = port_;
|
|
proto = proto_;
|
|
ip_addr = ip_addr_;
|
|
}
|
|
|
|
IP::Addr endpoint_;
|
|
Protocol protocol_;
|
|
std::string host_;
|
|
std::string port_;
|
|
std::string proto_;
|
|
std::string ip_addr_;
|
|
};
|
|
|
|
private:
|
|
class NullParent : public TransportClientParent
|
|
{
|
|
public:
|
|
NullParent(TransportClientParent* old_parent)
|
|
: is_openvpn_protocol(old_parent->transport_is_openvpn_protocol())
|
|
{
|
|
}
|
|
|
|
private:
|
|
virtual void transport_recv(BufferAllocated& buf) {}
|
|
virtual void transport_needs_send() {}
|
|
|
|
virtual void transport_error(const Error::Type fatal_err, const std::string& err_text)
|
|
{
|
|
OPENVPN_LOG("TransportRelayFactory: Transport Error in null parent: " << Error::name(fatal_err) << " : " << err_text);
|
|
}
|
|
|
|
virtual void proxy_error(const Error::Type fatal_err, const std::string& err_text)
|
|
{
|
|
OPENVPN_LOG("TransportRelayFactory: Proxy Error in null parent: " << Error::name(fatal_err) << " : " << err_text);
|
|
}
|
|
|
|
// Return true if we are transporting OpenVPN protocol
|
|
virtual bool transport_is_openvpn_protocol() { return is_openvpn_protocol; }
|
|
|
|
// progress notifications
|
|
virtual void transport_pre_resolve() {}
|
|
virtual void transport_wait_proxy() {}
|
|
virtual void transport_wait() {}
|
|
virtual void transport_connecting() {}
|
|
|
|
// Return true if keepalive parameter(s) are enabled.
|
|
virtual bool is_keepalive_enabled() const { return false; }
|
|
|
|
// Disable keepalive for rest of session, but fetch
|
|
// the keepalive parameters (in seconds).
|
|
virtual void disable_keepalive(unsigned int& keepalive_ping, unsigned int& keepalive_timeout)
|
|
{
|
|
keepalive_ping = 0;
|
|
keepalive_timeout = 0;
|
|
}
|
|
|
|
bool is_openvpn_protocol;
|
|
};
|
|
|
|
virtual TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context& io_context,
|
|
TransportClientParent* parent) override
|
|
{
|
|
// io_context MUST stay consistent
|
|
if (&io_context != &io_context_)
|
|
throw Exception("TransportRelayFactory: inconsistent io_context");
|
|
|
|
transport_->transport_reparent(parent);
|
|
return transport_;
|
|
}
|
|
|
|
virtual bool is_relay() override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
openvpn_io::io_context& io_context_; // only used to verify consistency
|
|
TransportClient::Ptr transport_; // the persisted transport
|
|
std::unique_ptr<TransportClientParent> null_parent_; // placeholder for TransportClient parent before reparenting
|
|
};
|
|
}
|
|
|
|
#endif
|