mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 12:12:15 +02:00
Merge remote-tracking branch 'origin/qa'
This commit is contained in:
commit
c3026c65a6
@ -858,6 +858,9 @@ namespace openvpn {
|
|||||||
#endif
|
#endif
|
||||||
Log::Context log_context(this);
|
Log::Context log_context(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
OPENVPN_LOG(ClientAPI::OpenVPNClient::platform());
|
||||||
|
|
||||||
return do_connect();
|
return do_connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <openvpn/io/io.hpp>
|
#include <openvpn/io/io.hpp>
|
||||||
|
#include <openvpn/asio/asiowork.hpp>
|
||||||
|
|
||||||
#include <openvpn/common/exception.hpp>
|
#include <openvpn/common/exception.hpp>
|
||||||
#include <openvpn/common/rc.hpp>
|
#include <openvpn/common/rc.hpp>
|
||||||
@ -53,6 +54,79 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace openvpn {
|
namespace openvpn {
|
||||||
|
template<typename RESOLVER_TYPE>
|
||||||
|
class AsyncResolvable: public virtual RC<thread_unsafe_refcount>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef RCPtr<AsyncResolvable> Ptr;
|
||||||
|
|
||||||
|
openvpn_io::io_context& io_context;
|
||||||
|
std::unique_ptr<AsioWork> asio_work;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AsyncResolvable(openvpn_io::io_context& io_context_arg)
|
||||||
|
: io_context(io_context_arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void resolve_callback(const openvpn_io::error_code& error,
|
||||||
|
typename RESOLVER_TYPE::results_type results) = 0;
|
||||||
|
|
||||||
|
// mimic the asynchronous DNS resolution by performing a
|
||||||
|
// synchronous one in a detached thread.
|
||||||
|
//
|
||||||
|
// This strategy has the advantage of allowing the core to
|
||||||
|
// stop/exit without waiting for the getaddrinfo() (used
|
||||||
|
// internally) to terminate.
|
||||||
|
// Note: getaddrinfo() is non-interruptible by design.
|
||||||
|
//
|
||||||
|
// In other words, we are re-creating exactly what ASIO would
|
||||||
|
// normally do in case of async_resolve(), with the difference
|
||||||
|
// that here we have control over the resolving thread and we
|
||||||
|
// can easily detach it. Deatching the internal thread created
|
||||||
|
// by ASIO would not be feasible as it is not exposed.
|
||||||
|
void async_resolve_name(const std::string& host, const std::string& port)
|
||||||
|
{
|
||||||
|
// there might be nothing else in the main io_context queue
|
||||||
|
// right now, therefore we use AsioWork to prevent the loop
|
||||||
|
// from exiting while we perform the DNS resolution in the
|
||||||
|
// detached thread.
|
||||||
|
asio_work.reset(new AsioWork(io_context));
|
||||||
|
|
||||||
|
std::thread resolve_thread([self=Ptr(this), host, port]() {
|
||||||
|
openvpn_io::io_context io_context(1);
|
||||||
|
openvpn_io::error_code error;
|
||||||
|
RESOLVER_TYPE resolver(io_context);
|
||||||
|
typename RESOLVER_TYPE::results_type results;
|
||||||
|
results = resolver.resolve(host, port, error);
|
||||||
|
|
||||||
|
openvpn_io::post(self->io_context, [self, results, error]() {
|
||||||
|
OPENVPN_ASYNC_HANDLER;
|
||||||
|
self->resolve_callback(error, results);
|
||||||
|
});
|
||||||
|
|
||||||
|
// the AsioWork can be released now that we have posted
|
||||||
|
// something else to the main io_context queue
|
||||||
|
self->asio_work.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
// detach the thread so that the client won't need to wait for
|
||||||
|
// it to join.
|
||||||
|
resolve_thread.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
// to be called by the child class when the core wants to stop
|
||||||
|
// and we don't need to wait for the detached thread any longer.
|
||||||
|
// It simulates a resolve abort
|
||||||
|
void async_resolve_cancel()
|
||||||
|
{
|
||||||
|
asio_work.reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef AsyncResolvable<openvpn_io::ip::udp::resolver> AsyncResolvableUDP;
|
||||||
|
typedef AsyncResolvable<openvpn_io::ip::tcp::resolver> AsyncResolvableTCP;
|
||||||
|
|
||||||
|
|
||||||
class RemoteList : public RC<thread_unsafe_refcount>
|
class RemoteList : public RC<thread_unsafe_refcount>
|
||||||
{
|
{
|
||||||
@ -262,7 +336,7 @@ namespace openvpn {
|
|||||||
// This is useful in tun_persist mode, where it may be necessary
|
// This is useful in tun_persist mode, where it may be necessary
|
||||||
// to pre-resolve all potential remote server items prior
|
// to pre-resolve all potential remote server items prior
|
||||||
// to initial tunnel establishment.
|
// to initial tunnel establishment.
|
||||||
class PreResolve : public RC<thread_unsafe_refcount>
|
class PreResolve : public virtual RC<thread_unsafe_refcount>, AsyncResolvableTCP
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef RCPtr<PreResolve> Ptr;
|
typedef RCPtr<PreResolve> Ptr;
|
||||||
@ -276,7 +350,7 @@ namespace openvpn {
|
|||||||
PreResolve(openvpn_io::io_context& io_context_arg,
|
PreResolve(openvpn_io::io_context& io_context_arg,
|
||||||
const RemoteList::Ptr& remote_list_arg,
|
const RemoteList::Ptr& remote_list_arg,
|
||||||
const SessionStats::Ptr& stats_arg)
|
const SessionStats::Ptr& stats_arg)
|
||||||
: resolver(io_context_arg),
|
: AsyncResolvableTCP(io_context_arg),
|
||||||
notify_callback(nullptr),
|
notify_callback(nullptr),
|
||||||
remote_list(remote_list_arg),
|
remote_list(remote_list_arg),
|
||||||
stats(stats_arg),
|
stats(stats_arg),
|
||||||
@ -312,7 +386,7 @@ namespace openvpn {
|
|||||||
{
|
{
|
||||||
notify_callback = nullptr;
|
notify_callback = nullptr;
|
||||||
index = 0;
|
index = 0;
|
||||||
resolver.cancel();
|
async_resolve_cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -335,14 +409,8 @@ namespace openvpn {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// call into Asio to do the resolve operation
|
|
||||||
OPENVPN_LOG_REMOTELIST("*** PreResolve RESOLVE on " << item.server_host << " : " << item.server_port);
|
OPENVPN_LOG_REMOTELIST("*** PreResolve RESOLVE on " << item.server_host << " : " << item.server_port);
|
||||||
resolver.async_resolve(item.server_host, item.server_port,
|
async_resolve_name(item.server_host, item.server_port);
|
||||||
[self=Ptr(this)](const openvpn_io::error_code& error, openvpn_io::ip::tcp::resolver::results_type results)
|
|
||||||
{
|
|
||||||
OPENVPN_ASYNC_HANDLER;
|
|
||||||
self->resolve_callback(error, results);
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,7 +431,7 @@ namespace openvpn {
|
|||||||
|
|
||||||
// callback on resolve completion
|
// callback on resolve completion
|
||||||
void resolve_callback(const openvpn_io::error_code& error,
|
void resolve_callback(const openvpn_io::error_code& error,
|
||||||
openvpn_io::ip::tcp::resolver::results_type results)
|
openvpn_io::ip::tcp::resolver::results_type results) override
|
||||||
{
|
{
|
||||||
if (notify_callback && index < remote_list->list.size())
|
if (notify_callback && index < remote_list->list.size())
|
||||||
{
|
{
|
||||||
@ -384,7 +452,6 @@ namespace openvpn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openvpn_io::ip::tcp::resolver resolver;
|
|
||||||
NotifyCallback* notify_callback;
|
NotifyCallback* notify_callback;
|
||||||
RemoteList::Ptr remote_list;
|
RemoteList::Ptr remote_list;
|
||||||
SessionStats::Ptr stats;
|
SessionStats::Ptr stats;
|
||||||
|
@ -117,7 +117,8 @@ namespace openvpn {
|
|||||||
class Client : public TransportClient,
|
class Client : public TransportClient,
|
||||||
public TunClient,
|
public TunClient,
|
||||||
public KoRekey::Receiver,
|
public KoRekey::Receiver,
|
||||||
public SessionStats::DCOTransportSource
|
public SessionStats::DCOTransportSource,
|
||||||
|
public AsyncResolvableUDP
|
||||||
{
|
{
|
||||||
friend class ClientConfig;
|
friend class ClientConfig;
|
||||||
|
|
||||||
@ -473,7 +474,8 @@ namespace openvpn {
|
|||||||
Client(openvpn_io::io_context& io_context_arg,
|
Client(openvpn_io::io_context& io_context_arg,
|
||||||
ClientConfig* config_arg,
|
ClientConfig* config_arg,
|
||||||
TransportClientParent* parent_arg)
|
TransportClientParent* parent_arg)
|
||||||
: io_context(io_context_arg),
|
: AsyncResolvableUDP(io_context),
|
||||||
|
io_context(io_context_arg),
|
||||||
halt(false),
|
halt(false),
|
||||||
state(new TunProp::State()),
|
state(new TunProp::State()),
|
||||||
config(config_arg),
|
config(config_arg),
|
||||||
@ -498,17 +500,13 @@ namespace openvpn {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
transport_parent->transport_pre_resolve();
|
transport_parent->transport_pre_resolve();
|
||||||
udp().resolver.async_resolve(server_host, server_port,
|
async_resolve_name(server_host, server_port);
|
||||||
[self=Ptr(this)](const openvpn_io::error_code& error, openvpn_io::ip::udp::resolver::results_type results)
|
|
||||||
{
|
|
||||||
self->do_resolve_udp(error, results);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// called after DNS resolution has succeeded or failed
|
// called after DNS resolution has succeeded or failed
|
||||||
void do_resolve_udp(const openvpn_io::error_code& error,
|
void resolve_callback(const openvpn_io::error_code& error,
|
||||||
openvpn_io::ip::udp::resolver::results_type results)
|
openvpn_io::ip::udp::resolver::results_type results)
|
||||||
{
|
{
|
||||||
if (!halt)
|
if (!halt)
|
||||||
{
|
{
|
||||||
|
@ -209,7 +209,7 @@ namespace openvpn {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client : public TransportClient
|
class Client : public TransportClient, AsyncResolvableTCP
|
||||||
{
|
{
|
||||||
typedef RCPtr<Client> Ptr;
|
typedef RCPtr<Client> Ptr;
|
||||||
|
|
||||||
@ -245,12 +245,8 @@ namespace openvpn {
|
|||||||
{
|
{
|
||||||
// resolve it
|
// resolve it
|
||||||
parent->transport_pre_resolve();
|
parent->transport_pre_resolve();
|
||||||
resolver.async_resolve(proxy_host, proxy_port,
|
|
||||||
[self=Ptr(this)](const openvpn_io::error_code& error, openvpn_io::ip::tcp::resolver::results_type results)
|
async_resolve_name(proxy_host, proxy_port);
|
||||||
{
|
|
||||||
OPENVPN_ASYNC_HANDLER;
|
|
||||||
self->do_resolve_(error, results);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,7 +336,7 @@ namespace openvpn {
|
|||||||
Client(openvpn_io::io_context& io_context_arg,
|
Client(openvpn_io::io_context& io_context_arg,
|
||||||
ClientConfig* config_arg,
|
ClientConfig* config_arg,
|
||||||
TransportClientParent* parent_arg)
|
TransportClientParent* parent_arg)
|
||||||
: io_context(io_context_arg),
|
: AsyncResolvableTCP(io_context_arg),
|
||||||
socket(io_context_arg),
|
socket(io_context_arg),
|
||||||
config(config_arg),
|
config(config_arg),
|
||||||
parent(parent_arg),
|
parent(parent_arg),
|
||||||
@ -860,12 +856,13 @@ namespace openvpn {
|
|||||||
|
|
||||||
socket.close();
|
socket.close();
|
||||||
resolver.cancel();
|
resolver.cancel();
|
||||||
|
async_resolve_cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do DNS resolve
|
// do DNS resolve
|
||||||
void do_resolve_(const openvpn_io::error_code& error,
|
void resolve_callback(const openvpn_io::error_code& error,
|
||||||
openvpn_io::ip::tcp::resolver::results_type results)
|
openvpn_io::ip::tcp::resolver::results_type results) override
|
||||||
{
|
{
|
||||||
if (!halt)
|
if (!halt)
|
||||||
{
|
{
|
||||||
@ -1008,7 +1005,6 @@ namespace openvpn {
|
|||||||
std::string server_host;
|
std::string server_host;
|
||||||
std::string server_port;
|
std::string server_port;
|
||||||
|
|
||||||
openvpn_io::io_context& io_context;
|
|
||||||
openvpn_io::ip::tcp::socket socket;
|
openvpn_io::ip::tcp::socket socket;
|
||||||
ClientConfig::Ptr config;
|
ClientConfig::Ptr config;
|
||||||
TransportClientParent* parent;
|
TransportClientParent* parent;
|
||||||
|
@ -74,7 +74,7 @@ namespace openvpn {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client : public TransportClient
|
class Client : public TransportClient, AsyncResolvableTCP
|
||||||
{
|
{
|
||||||
typedef RCPtr<Client> Ptr;
|
typedef RCPtr<Client> Ptr;
|
||||||
|
|
||||||
@ -102,12 +102,8 @@ namespace openvpn {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
parent->transport_pre_resolve();
|
parent->transport_pre_resolve();
|
||||||
resolver.async_resolve(server_host, server_port,
|
|
||||||
[self=Ptr(this)](const openvpn_io::error_code& error, openvpn_io::ip::tcp::resolver::results_type results)
|
async_resolve_name(server_host, server_port);
|
||||||
{
|
|
||||||
OPENVPN_ASYNC_HANDLER;
|
|
||||||
self->do_resolve_(error, results);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,7 +171,8 @@ namespace openvpn {
|
|||||||
Client(openvpn_io::io_context& io_context_arg,
|
Client(openvpn_io::io_context& io_context_arg,
|
||||||
ClientConfig* config_arg,
|
ClientConfig* config_arg,
|
||||||
TransportClientParent* parent_arg)
|
TransportClientParent* parent_arg)
|
||||||
: io_context(io_context_arg),
|
: AsyncResolvableTCP(io_context_arg),
|
||||||
|
io_context(io_context_arg),
|
||||||
socket(io_context_arg),
|
socket(io_context_arg),
|
||||||
config(config_arg),
|
config(config_arg),
|
||||||
parent(parent_arg),
|
parent(parent_arg),
|
||||||
@ -249,12 +246,13 @@ namespace openvpn {
|
|||||||
|
|
||||||
socket.close();
|
socket.close();
|
||||||
resolver.cancel();
|
resolver.cancel();
|
||||||
|
async_resolve_cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do DNS resolve
|
// do DNS resolve
|
||||||
void do_resolve_(const openvpn_io::error_code& error,
|
void resolve_callback(const openvpn_io::error_code& error,
|
||||||
openvpn_io::ip::tcp::resolver::results_type results)
|
openvpn_io::ip::tcp::resolver::results_type results) override
|
||||||
{
|
{
|
||||||
if (!halt)
|
if (!halt)
|
||||||
{
|
{
|
||||||
|
@ -74,7 +74,7 @@ namespace openvpn {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client : public TransportClient
|
class Client : public TransportClient, AsyncResolvableUDP
|
||||||
{
|
{
|
||||||
typedef RCPtr<Client> Ptr;
|
typedef RCPtr<Client> Ptr;
|
||||||
|
|
||||||
@ -101,16 +101,11 @@ namespace openvpn {
|
|||||||
{
|
{
|
||||||
openvpn_io::error_code error;
|
openvpn_io::error_code error;
|
||||||
openvpn_io::ip::udp::resolver::results_type results = resolver.resolve(server_host, server_port, error);
|
openvpn_io::ip::udp::resolver::results_type results = resolver.resolve(server_host, server_port, error);
|
||||||
do_resolve_(error, results);
|
resolve_callback(error, results);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resolver.async_resolve(server_host, server_port,
|
async_resolve_name(server_host, server_port);
|
||||||
[self=Ptr(this)](const openvpn_io::error_code& error, openvpn_io::ip::udp::resolver::results_type results)
|
|
||||||
{
|
|
||||||
OPENVPN_ASYNC_HANDLER;
|
|
||||||
self->do_resolve_(error, results);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,7 +176,8 @@ namespace openvpn {
|
|||||||
Client(openvpn_io::io_context& io_context_arg,
|
Client(openvpn_io::io_context& io_context_arg,
|
||||||
ClientConfig* config_arg,
|
ClientConfig* config_arg,
|
||||||
TransportClientParent* parent_arg)
|
TransportClientParent* parent_arg)
|
||||||
: socket(io_context_arg),
|
: AsyncResolvableUDP(io_context_arg),
|
||||||
|
socket(io_context_arg),
|
||||||
config(config_arg),
|
config(config_arg),
|
||||||
parent(parent_arg),
|
parent(parent_arg),
|
||||||
resolver(io_context_arg),
|
resolver(io_context_arg),
|
||||||
@ -236,12 +232,13 @@ namespace openvpn {
|
|||||||
impl->stop();
|
impl->stop();
|
||||||
socket.close();
|
socket.close();
|
||||||
resolver.cancel();
|
resolver.cancel();
|
||||||
|
async_resolve_cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// called after DNS resolution has succeeded or failed
|
// called after DNS resolution has succeeded or failed
|
||||||
void do_resolve_(const openvpn_io::error_code& error,
|
void resolve_callback(const openvpn_io::error_code& error,
|
||||||
openvpn_io::ip::udp::resolver::results_type results)
|
openvpn_io::ip::udp::resolver::results_type results) override
|
||||||
{
|
{
|
||||||
if (!halt)
|
if (!halt)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user