mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-04-24 00:00:05 +08:00
Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from 6608878d5..934f4e741
934f4e741 Merge remote-tracking branch 'origin/qa' 8c87c7696 [UCONNECT-1027] use proper io_context when initializing AsyncResolve class c3026c65a Merge remote-tracking branch 'origin/qa' f33fe7665 [UCONNECT-1027] perform async DNS resolution in a detached thread 0c0af6781 [OVPN3-342] Generate ICMP "packet too big" reply c93af60a7 Move files from ovpn3-common to openvpn3 repo d5eeb78ed ClientAPI: print core version when starting 04de9c425 Merge branch 'qa' 2c0dbc6c3 buildep.py: add asio patching 600c68012 Allow updating auth-token during session 7391096b9 [OC-85] tunprop: exclude routes for additional remotes also on macOS 3587628d7 [OC-84] tunprop: exclude routes for additional remotes also on Windows 25471635d Revert "[UCONNECT-868] When no network is present pause instead of stopping" 5713ff34a Fixed some breakage caused by recent endian/ffs commits a9ce44a22 endian.hpp: break out endian compile-time tests to endian_platform.hpp 72181f9e7 [UCONNECT-868] When no network is present pause instead of stopping 10d636cfe version: switch to 3.2 git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/openvpn git-subtree-split: 934f4e741f760160dc65a6f4b29af57bb5be8f93
This commit is contained in:
@@ -395,7 +395,12 @@ namespace openvpn {
|
||||
tunconf->stats = cli_stats;
|
||||
tunconf->stop = config.stop;
|
||||
if (config.tun_persist)
|
||||
{
|
||||
tunconf->tun_persist.reset(new TunMac::TunPersist(true, false, nullptr));
|
||||
tunconf->tun_prop.remote_bypass = true;
|
||||
/* remote_list is required by remote_bypass to work */
|
||||
tunconf->tun_prop.remote_list = remote_list;
|
||||
}
|
||||
client_lifecycle.reset(new MacLifeCycle);
|
||||
#ifdef OPENVPN_COMMAND_AGENT
|
||||
tunconf->tun_setup_factory = UnixCommandAgent::new_agent(opt);
|
||||
@@ -414,7 +419,12 @@ namespace openvpn {
|
||||
tunconf->stats = cli_stats;
|
||||
tunconf->stop = config.stop;
|
||||
if (config.tun_persist)
|
||||
{
|
||||
tunconf->tun_persist.reset(new TunWin::TunPersist(true, false, nullptr));
|
||||
tunconf->tun_prop.remote_bypass = true;
|
||||
/* remote_list is required by remote_bypass to work */
|
||||
tunconf->tun_prop.remote_list = remote_list;
|
||||
}
|
||||
#ifdef OPENVPN_COMMAND_AGENT
|
||||
tunconf->tun_setup_factory = WinCommandAgent::new_agent(opt);
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <openvpn/common/count.hpp>
|
||||
#include <openvpn/common/string.hpp>
|
||||
#include <openvpn/common/base64.hpp>
|
||||
#include <openvpn/ip/ptb.hpp>
|
||||
#include <openvpn/tun/client/tunbase.hpp>
|
||||
#include <openvpn/transport/client/transbase.hpp>
|
||||
#include <openvpn/transport/client/relay.hpp>
|
||||
@@ -376,15 +377,24 @@ namespace openvpn {
|
||||
// encrypt packet
|
||||
if (buf.size())
|
||||
{
|
||||
Base::data_encrypt(buf);
|
||||
if (buf.size())
|
||||
const ProtoContext::Config& c = Base::conf();
|
||||
if (c.mss_inter > 0 && buf.size() > c.mss_inter)
|
||||
{
|
||||
// send packet via transport to destination
|
||||
OPENVPN_LOG_CLIPROTO("Transport SEND " << server_endpoint_render() << ' ' << Base::dump_packet(buf));
|
||||
if (transport->transport_send(buf))
|
||||
Base::update_last_sent();
|
||||
else if (halt)
|
||||
return;
|
||||
Ptb::generate_icmp_ptb(buf, c.mss_inter);
|
||||
tun->tun_send(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
Base::data_encrypt(buf);
|
||||
if (buf.size())
|
||||
{
|
||||
// send packet via transport to destination
|
||||
OPENVPN_LOG_CLIPROTO("Transport SEND " << server_endpoint_render() << ' ' << Base::dump_packet(buf));
|
||||
if (transport->transport_send(buf))
|
||||
Base::update_last_sent();
|
||||
else if (halt)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include <openvpn/io/io.hpp>
|
||||
#include <openvpn/asio/asiowork.hpp>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/rc.hpp>
|
||||
@@ -53,6 +54,79 @@
|
||||
#endif
|
||||
|
||||
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>
|
||||
{
|
||||
@@ -262,7 +336,7 @@ namespace openvpn {
|
||||
// This is useful in tun_persist mode, where it may be necessary
|
||||
// to pre-resolve all potential remote server items prior
|
||||
// to initial tunnel establishment.
|
||||
class PreResolve : public RC<thread_unsafe_refcount>
|
||||
class PreResolve : public virtual RC<thread_unsafe_refcount>, AsyncResolvableTCP
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<PreResolve> Ptr;
|
||||
@@ -276,7 +350,7 @@ namespace openvpn {
|
||||
PreResolve(openvpn_io::io_context& io_context_arg,
|
||||
const RemoteList::Ptr& remote_list_arg,
|
||||
const SessionStats::Ptr& stats_arg)
|
||||
: resolver(io_context_arg),
|
||||
: AsyncResolvableTCP(io_context_arg),
|
||||
notify_callback(nullptr),
|
||||
remote_list(remote_list_arg),
|
||||
stats(stats_arg),
|
||||
@@ -312,7 +386,7 @@ namespace openvpn {
|
||||
{
|
||||
notify_callback = nullptr;
|
||||
index = 0;
|
||||
resolver.cancel();
|
||||
async_resolve_cancel();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -335,14 +409,8 @@ namespace openvpn {
|
||||
}
|
||||
else
|
||||
{
|
||||
// call into Asio to do the resolve operation
|
||||
OPENVPN_LOG_REMOTELIST("*** PreResolve RESOLVE on " << item.server_host << " : " << item.server_port);
|
||||
resolver.async_resolve(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);
|
||||
});
|
||||
async_resolve_name(item.server_host, item.server_port);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -363,7 +431,7 @@ namespace openvpn {
|
||||
|
||||
// callback on resolve completion
|
||||
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())
|
||||
{
|
||||
@@ -384,7 +452,6 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
openvpn_io::ip::tcp::resolver resolver;
|
||||
NotifyCallback* notify_callback;
|
||||
RemoteList::Ptr remote_list;
|
||||
SessionStats::Ptr stats;
|
||||
|
||||
Reference in New Issue
Block a user