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:
Sergey Abramchuk
2019-02-24 15:02:57 +03:00
parent f5fda0fa73
commit ed98f2568b
18 changed files with 759 additions and 68 deletions
+10
View File
@@ -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
+18 -8
View File
@@ -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;
}
}
}
+79 -12
View File
@@ -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;