2018-08-08 06:12:38 -05:00
|
|
|
// SPDX-License-Identifier: AGPL-1.0-only
|
|
|
|
// Copyright (C) 2018 Ludvig Strigeus <info@tunsafe.com>. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "netapi.h"
|
|
|
|
#include "network_win32_api.h"
|
2018-08-11 20:27:14 -05:00
|
|
|
#include "network_win32_dnsblock.h"
|
|
|
|
#include "wireguard_config.h"
|
|
|
|
#include "tunsafe_threading.h"
|
2018-10-21 09:00:15 -05:00
|
|
|
#include "tunsafe_dnsresolve.h"
|
2018-11-17 12:14:05 -06:00
|
|
|
#include "network_common.h"
|
|
|
|
#include "network_win32_tcp.h"
|
2018-11-19 14:24:43 -06:00
|
|
|
#include "tunsafe_wg_plugin.h"
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
enum {
|
|
|
|
ADAPTER_GUID_SIZE = 40,
|
|
|
|
};
|
|
|
|
|
2018-08-08 06:12:38 -05:00
|
|
|
class WireguardProcessor;
|
2018-08-11 20:27:14 -05:00
|
|
|
class TunsafeBackendWin32;
|
2018-12-16 09:02:50 -06:00
|
|
|
class TunsafeRunner;
|
2018-11-17 12:14:05 -06:00
|
|
|
class DnsBlocker;
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-10-29 20:19:20 -05:00
|
|
|
struct PacketProcessorTunCb : QueuedItemCallback {
|
|
|
|
virtual void OnQueuedItemEvent(QueuedItem *ow, uintptr_t extra) override;
|
|
|
|
virtual void OnQueuedItemDelete(QueuedItem *ow) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PacketProcessorUdpCb : QueuedItemCallback {
|
|
|
|
virtual void OnQueuedItemEvent(QueuedItem *ow, uintptr_t extra) override;
|
|
|
|
virtual void OnQueuedItemDelete(QueuedItem *ow) override;
|
|
|
|
};
|
|
|
|
|
2018-12-10 16:31:22 -06:00
|
|
|
struct PacketProcessorDeobfuscateUdpCb : PacketProcessorUdpCb {
|
|
|
|
virtual void OnQueuedItemEvent(QueuedItem *ow, uintptr_t extra) override;
|
|
|
|
};
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
class PacketProcessor {
|
2018-08-08 06:12:38 -05:00
|
|
|
public:
|
2018-09-15 11:22:05 -05:00
|
|
|
explicit PacketProcessor();
|
|
|
|
~PacketProcessor();
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
void Reset();
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-12-16 09:02:50 -06:00
|
|
|
int Run(WireguardProcessor *wg, TunsafeRunner *runner);
|
2018-10-29 20:19:20 -05:00
|
|
|
void PostPackets(Packet *first, Packet **end, int count);
|
|
|
|
void ForcePost(QueuedItem *item);
|
2018-09-15 11:22:05 -05:00
|
|
|
void PostExit(int exit_code);
|
2018-12-10 16:31:22 -06:00
|
|
|
void EnableDeobfuscation() {
|
|
|
|
udp_cb_maybe_deobfuscate_ = &udp_cb_deobfuscate_;
|
|
|
|
}
|
2018-09-15 11:22:05 -05:00
|
|
|
|
|
|
|
const uint32 *posted_exit_code() { return &exit_code_; }
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-12-10 16:31:22 -06:00
|
|
|
// Handler for tun packets
|
2018-10-29 20:19:20 -05:00
|
|
|
QueuedItemCallback *tun_queue() { return &tun_cb_; }
|
2018-12-10 16:31:22 -06:00
|
|
|
|
|
|
|
// Handler for udp packets
|
|
|
|
QueuedItemCallback *udp_queue() { return udp_cb_maybe_deobfuscate_; }
|
|
|
|
|
|
|
|
// Incoming queue for tcp packets that do not use deobfuscation
|
|
|
|
QueuedItemCallback *tcp_queue() { return &udp_cb_; }
|
2018-10-29 20:19:20 -05:00
|
|
|
|
|
|
|
struct QueueContext {
|
|
|
|
WireguardProcessor *wg;
|
2018-12-16 09:02:50 -06:00
|
|
|
TunsafeRunner *runner;
|
2018-10-29 20:19:20 -05:00
|
|
|
bool overload;
|
|
|
|
};
|
|
|
|
|
2018-08-08 06:12:38 -05:00
|
|
|
private:
|
2018-09-15 11:22:05 -05:00
|
|
|
static void CALLBACK ThreadPoolTimerCallback(PTP_CALLBACK_INSTANCE iTimerInstance, PVOID pContext, PTP_TIMER);
|
2018-10-29 20:19:20 -05:00
|
|
|
QueuedItem *first_;
|
|
|
|
QueuedItem **last_ptr_;
|
2018-08-08 06:12:38 -05:00
|
|
|
uint32 packets_in_queue_;
|
|
|
|
uint32 need_notify_;
|
2018-08-11 20:27:14 -05:00
|
|
|
Mutex mutex_;
|
2018-08-08 06:12:38 -05:00
|
|
|
HANDLE event_;
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
uint32 exit_code_;
|
2018-08-08 06:12:38 -05:00
|
|
|
bool timer_interrupt_;
|
2018-10-29 20:19:20 -05:00
|
|
|
|
2018-12-10 16:31:22 -06:00
|
|
|
QueuedItemCallback *udp_cb_maybe_deobfuscate_;
|
|
|
|
|
2018-10-29 20:19:20 -05:00
|
|
|
PacketProcessorTunCb tun_cb_;
|
|
|
|
PacketProcessorUdpCb udp_cb_;
|
2018-12-10 16:31:22 -06:00
|
|
|
PacketProcessorDeobfuscateUdpCb udp_cb_deobfuscate_;
|
2018-08-08 06:12:38 -05:00
|
|
|
};
|
|
|
|
|
2018-10-29 18:31:33 -05:00
|
|
|
class NetworkWin32;
|
|
|
|
class PacketAllocPool;
|
|
|
|
|
|
|
|
// Encapsulates a UDP socket pair (ipv4 / ipv6), optionally listening for incoming packets
|
2018-08-08 06:12:38 -05:00
|
|
|
// on a specific port.
|
2018-11-17 12:14:05 -06:00
|
|
|
class UdpSocketWin32 : public QueuedItemCallback {
|
2018-08-08 06:12:38 -05:00
|
|
|
public:
|
2018-10-29 18:31:33 -05:00
|
|
|
explicit UdpSocketWin32(NetworkWin32 *network_win32);
|
2018-08-08 06:12:38 -05:00
|
|
|
~UdpSocketWin32();
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
void SetPacketHandler(PacketProcessor *packet_handler) { packet_handler_ = packet_handler; }
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-11-17 12:14:05 -06:00
|
|
|
bool Configure(int listen_on_port);
|
|
|
|
inline void WriteUdpPacket(Packet *packet);
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-10-29 18:31:33 -05:00
|
|
|
void DoIO();
|
|
|
|
void CancelAllIO();
|
|
|
|
bool HasOutstandingIO();
|
|
|
|
|
|
|
|
enum {
|
|
|
|
kConcurrentReadUdp = 16,
|
|
|
|
kConcurrentWriteUdp = 16
|
|
|
|
};
|
|
|
|
|
2018-08-08 06:12:38 -05:00
|
|
|
private:
|
2018-10-29 18:31:33 -05:00
|
|
|
void DoMoreReads();
|
|
|
|
void DoMoreWrites();
|
2018-11-17 12:14:05 -06:00
|
|
|
void ProcessPackets();
|
2018-10-29 18:31:33 -05:00
|
|
|
|
|
|
|
// From OverlappedCallbacks
|
|
|
|
virtual void OnQueuedItemEvent(QueuedItem *ow, uintptr_t extra) override;
|
|
|
|
virtual void OnQueuedItemDelete(QueuedItem *ow) override;
|
|
|
|
|
|
|
|
NetworkWin32 *network_;
|
2018-08-08 06:12:38 -05:00
|
|
|
|
|
|
|
// All packets queued for writing. Locked by |mutex_|
|
2018-10-29 18:31:33 -05:00
|
|
|
// Both ipv6 and ipv4 are supported
|
2018-08-08 06:12:38 -05:00
|
|
|
Packet *wqueue_, **wqueue_end_;
|
|
|
|
|
2018-10-29 18:31:33 -05:00
|
|
|
// Protects wqueue
|
2018-08-11 20:27:14 -05:00
|
|
|
Mutex mutex_;
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-10-29 18:31:33 -05:00
|
|
|
// This is where packets end up
|
2018-09-15 11:22:05 -05:00
|
|
|
PacketProcessor *packet_handler_;
|
2018-10-29 18:31:33 -05:00
|
|
|
|
|
|
|
// The two socket handles, since we support both ipv4 and ipv6
|
|
|
|
SOCKET socket_, socket_ipv6_;
|
|
|
|
|
|
|
|
enum { IPV4, IPV6 };
|
|
|
|
int max_read_ipv6_;
|
|
|
|
int num_reads_[2];
|
|
|
|
int num_writes_;
|
|
|
|
Packet *pending_writes_;
|
|
|
|
|
|
|
|
Packet *finished_reads_, **finished_reads_end_;
|
|
|
|
int finished_reads_count_;
|
2018-11-17 12:14:05 -06:00
|
|
|
|
2018-12-16 09:02:50 -06:00
|
|
|
uint32 qsize1_;
|
|
|
|
uint8 align[64-4];
|
|
|
|
uint32 qsize2_;
|
2018-10-29 18:31:33 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
// Holds the thread for network communications
|
2018-12-16 09:02:50 -06:00
|
|
|
class NetworkWin32 {
|
2018-10-29 18:31:33 -05:00
|
|
|
friend class UdpSocketWin32;
|
2018-11-17 12:14:05 -06:00
|
|
|
friend class TcpSocketWin32;
|
|
|
|
friend class TcpSocketQueue;
|
2018-10-29 18:31:33 -05:00
|
|
|
public:
|
|
|
|
explicit NetworkWin32();
|
|
|
|
~NetworkWin32();
|
2018-12-16 09:02:50 -06:00
|
|
|
|
2018-10-29 18:31:33 -05:00
|
|
|
void StartThread();
|
|
|
|
void StopThread();
|
|
|
|
|
|
|
|
UdpSocketWin32 &udp() { return udp_socket_; }
|
2018-11-17 12:14:05 -06:00
|
|
|
SimplePacketPool &packet_pool() { return packet_pool_; }
|
|
|
|
void WakeUp();
|
|
|
|
void PostQueuedItem(QueuedItem *item);
|
2018-10-29 18:31:33 -05:00
|
|
|
private:
|
|
|
|
void ThreadMain();
|
|
|
|
static DWORD WINAPI NetworkThread(void *x);
|
|
|
|
|
2018-11-17 12:14:05 -06:00
|
|
|
bool HasOutstandingIO();
|
2018-10-29 18:31:33 -05:00
|
|
|
|
|
|
|
// The network thread handle
|
2018-08-08 06:12:38 -05:00
|
|
|
HANDLE thread_;
|
|
|
|
|
2018-10-29 18:31:33 -05:00
|
|
|
// Whether we're exiting the thread
|
2018-08-08 06:12:38 -05:00
|
|
|
bool exit_thread_;
|
2018-10-29 18:31:33 -05:00
|
|
|
|
|
|
|
// The handle to the completion port
|
|
|
|
HANDLE completion_port_handle_;
|
|
|
|
|
|
|
|
// Right now there's always one udp socket only
|
|
|
|
UdpSocketWin32 udp_socket_;
|
|
|
|
|
2018-11-17 12:14:05 -06:00
|
|
|
// A linked list of all tcp sockets
|
|
|
|
TcpSocketWin32 *tcp_socket_;
|
2018-10-29 18:31:33 -05:00
|
|
|
|
2018-11-17 12:14:05 -06:00
|
|
|
SimplePacketPool packet_pool_;
|
|
|
|
};
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-08-08 06:12:38 -05:00
|
|
|
class TunWin32Adapter {
|
|
|
|
public:
|
2018-09-15 11:22:05 -05:00
|
|
|
TunWin32Adapter(DnsBlocker *dns_blocker, const char guid[ADAPTER_GUID_SIZE]);
|
2018-08-08 06:12:38 -05:00
|
|
|
~TunWin32Adapter();
|
|
|
|
|
2018-12-16 09:02:50 -06:00
|
|
|
bool OpenAdapter(TunsafeRunner *backend, DWORD open_flags);
|
2018-09-15 11:22:05 -05:00
|
|
|
bool ConfigureAdapter(const TunInterface::TunConfig &&config, TunInterface::TunConfigOut *out);
|
|
|
|
void CloseAdapter(bool is_restart);
|
2018-08-08 06:12:38 -05:00
|
|
|
|
|
|
|
HANDLE handle() { return handle_; }
|
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
void DisassociateDnsBlocker() { dns_blocker_ = NULL; }
|
|
|
|
|
2018-08-08 06:12:38 -05:00
|
|
|
private:
|
|
|
|
bool RunPrePostCommand(const std::vector<std::string> &vec);
|
|
|
|
|
|
|
|
HANDLE handle_;
|
2018-08-11 20:27:14 -05:00
|
|
|
DnsBlocker *dns_blocker_;
|
2018-08-08 06:12:38 -05:00
|
|
|
|
|
|
|
std::vector<MIB_IPFORWARD_ROW2> routes_to_undo_;
|
|
|
|
uint8 mac_adress_[6];
|
2018-09-10 16:46:49 -05:00
|
|
|
bool has_dns6_setting_;
|
2018-08-08 06:12:38 -05:00
|
|
|
int mtu_;
|
2018-09-10 16:46:49 -05:00
|
|
|
|
|
|
|
int old_ipv4_metric_, old_ipv6_metric_;
|
|
|
|
|
2018-10-22 17:48:20 -05:00
|
|
|
std::vector<WgCidrAddr> old_ipv6_address_;
|
2018-09-10 16:46:49 -05:00
|
|
|
|
|
|
|
NET_LUID interface_luid_;
|
2018-08-08 06:12:38 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
void *backend_;
|
|
|
|
|
2018-08-08 06:12:38 -05:00
|
|
|
std::vector<std::string> pre_down_, post_down_;
|
2018-09-15 11:22:05 -05:00
|
|
|
char guid_[ADAPTER_GUID_SIZE];
|
2018-08-08 06:12:38 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
// Implementation of TUN interface handling using IO Completion Ports
|
|
|
|
class TunWin32Iocp : public TunInterface {
|
|
|
|
public:
|
2018-12-16 09:02:50 -06:00
|
|
|
explicit TunWin32Iocp(DnsBlocker *blocker, TunsafeRunner *backend);
|
2018-08-08 06:12:38 -05:00
|
|
|
~TunWin32Iocp();
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
void SetPacketHandler(PacketProcessor *packet_handler) { packet_handler_ = packet_handler; }
|
2018-08-08 06:12:38 -05:00
|
|
|
|
|
|
|
void StartThread();
|
|
|
|
void StopThread();
|
|
|
|
|
|
|
|
// -- from TunInterface
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual bool Configure(const TunConfig &&config, TunConfigOut *out) override;
|
2018-08-08 06:12:38 -05:00
|
|
|
virtual void WriteTunPacket(Packet *packet) override;
|
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
TunWin32Adapter &adapter() { return adapter_; }
|
|
|
|
|
2018-08-08 06:12:38 -05:00
|
|
|
private:
|
2018-09-15 11:22:05 -05:00
|
|
|
void CloseTun(bool is_restart);
|
2018-08-08 06:12:38 -05:00
|
|
|
void ThreadMain();
|
|
|
|
static DWORD WINAPI TunThread(void *x);
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
PacketProcessor *packet_handler_;
|
2018-08-08 06:12:38 -05:00
|
|
|
HANDLE completion_port_handle_;
|
|
|
|
HANDLE thread_;
|
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
Mutex mutex_;
|
2018-08-08 06:12:38 -05:00
|
|
|
|
|
|
|
bool exit_thread_;
|
2018-10-21 16:35:40 -05:00
|
|
|
bool did_show_tun_queue_warning_;
|
|
|
|
|
|
|
|
int wqueue_size_;
|
2018-08-08 06:12:38 -05:00
|
|
|
|
|
|
|
// All packets queued for writing
|
|
|
|
Packet *wqueue_, **wqueue_end_;
|
|
|
|
|
2018-12-16 09:02:50 -06:00
|
|
|
TunsafeRunner *runner_;
|
2018-08-08 06:12:38 -05:00
|
|
|
TunWin32Adapter adapter_;
|
|
|
|
};
|
|
|
|
|
2018-12-16 09:02:50 -06:00
|
|
|
// This class is the actual TunSafe thing and runs inside of a thread.
|
|
|
|
class TunsafeRunner : public UdpInterface, public ProcessorDelegate, public PluginDelegate, public QueuedItemCallback {
|
|
|
|
friend class TunsafeBackendWin32;
|
|
|
|
public:
|
|
|
|
TunsafeRunner(TunsafeBackendWin32 *backend);
|
|
|
|
~TunsafeRunner();
|
|
|
|
|
|
|
|
void SetConfigFile(const char *file, bool is_text_format);
|
|
|
|
|
|
|
|
TunsafeBackendWin32 *backend() { return backend_; }
|
|
|
|
|
|
|
|
// -- from UdpInterface
|
|
|
|
virtual bool Configure(int listen_port_udp, int listen_port_tcp) override;
|
|
|
|
virtual void WriteUdpPacket(Packet *packet) override;
|
|
|
|
|
|
|
|
virtual void OnConnected() override;
|
|
|
|
virtual void OnConnectionRetry(uint32 attempts) override;
|
|
|
|
|
|
|
|
// -- from PluginDelegate
|
|
|
|
virtual void OnRequestToken(WgPeer *peer, uint32 type) override;
|
|
|
|
|
|
|
|
bool Start();
|
|
|
|
|
|
|
|
// Called by the tun thing if tun stops working and a reset is needed.
|
|
|
|
void PostTunRestart();
|
|
|
|
|
|
|
|
uint32 exit_code() { return *packet_processor_.posted_exit_code(); }
|
|
|
|
|
|
|
|
TunsafePlugin *plugin() { return plugin_; }
|
|
|
|
|
|
|
|
void CollectStats();
|
|
|
|
|
|
|
|
private:
|
|
|
|
// From OverlappedCallbacks
|
|
|
|
virtual void OnQueuedItemEvent(QueuedItem *ow, uintptr_t extra) override;
|
|
|
|
virtual void OnQueuedItemDelete(QueuedItem *ow) override;
|
|
|
|
|
|
|
|
TunsafeBackendWin32 *backend_;
|
|
|
|
TunsafePlugin *plugin_;
|
|
|
|
bool config_file_is_text_format_;
|
|
|
|
std::string config_file_;
|
|
|
|
TunWin32Iocp tun_;
|
|
|
|
NetworkWin32 net_;
|
|
|
|
TcpSocketQueue tcp_socket_queue_;
|
|
|
|
WireguardProcessor wg_proc_;
|
|
|
|
PacketProcessor packet_processor_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class TunsafeBackendWin32 : public TunsafeBackend {
|
|
|
|
friend class TunsafeRunner;
|
2018-09-15 11:22:05 -05:00
|
|
|
friend class PacketProcessor;
|
2018-08-11 20:27:14 -05:00
|
|
|
friend class TunWin32Iocp;
|
|
|
|
friend class TunWin32Overlapped;
|
2018-09-15 11:22:05 -05:00
|
|
|
friend class TunWin32Adapter;
|
2018-10-29 20:19:20 -05:00
|
|
|
friend struct ConfigQueueItem;
|
2018-08-11 20:27:14 -05:00
|
|
|
public:
|
|
|
|
TunsafeBackendWin32(Delegate *delegate);
|
|
|
|
~TunsafeBackendWin32();
|
|
|
|
|
|
|
|
// -- from TunsafeBackend
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual bool Configure() override;
|
2018-08-11 20:27:14 -05:00
|
|
|
virtual void Teardown() override;
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual bool SetTunAdapterName(const char *name) override;
|
2018-08-11 20:27:14 -05:00
|
|
|
virtual void Start(const char *config_file) override;
|
|
|
|
virtual void Stop() override;
|
|
|
|
virtual void RequestStats(bool enable) override;
|
|
|
|
virtual void ResetStats() override;
|
2018-10-21 14:53:02 -05:00
|
|
|
virtual InternetBlockState GetInternetBlockState() override;
|
2018-08-11 20:27:14 -05:00
|
|
|
virtual void SetInternetBlockState(InternetBlockState s) override;
|
|
|
|
virtual void SetServiceStartupFlags(uint32 flags) override;
|
|
|
|
virtual LinearizedGraph *GetGraph(int type) override;
|
|
|
|
virtual std::string GetConfigFileName() override;
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual void SendConfigurationProtocolPacket(uint32 identifier, const std::string &&message) override;
|
2018-11-19 14:24:43 -06:00
|
|
|
virtual uint32 GetTokenRequest() override;
|
|
|
|
virtual void SubmitToken(const std::string &&message) override;
|
|
|
|
|
2018-12-16 09:02:50 -06:00
|
|
|
void OnRequestToken(WgPeer *peer, uint32 type);
|
2018-11-19 14:24:43 -06:00
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
void SetPublicKey(const uint8 key[32]);
|
2018-12-16 09:02:50 -06:00
|
|
|
|
|
|
|
StatusCode status() { return status_; }
|
|
|
|
void SetStatus(StatusCode status);
|
|
|
|
|
|
|
|
void CollectStats();
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
enum {
|
|
|
|
MODE_NONE = 0,
|
|
|
|
MODE_EXIT = 1,
|
|
|
|
MODE_RESTART = 2,
|
|
|
|
};
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
void StopInner(bool is_restart);
|
|
|
|
static DWORD WINAPI WorkerThread(void *x);
|
|
|
|
void PushStats();
|
|
|
|
|
2018-12-16 09:02:50 -06:00
|
|
|
TunsafeRunner *runner_;
|
2018-09-15 11:22:05 -05:00
|
|
|
HANDLE worker_thread_;
|
2018-08-11 20:27:14 -05:00
|
|
|
bool want_periodic_stats_;
|
2018-10-21 14:53:02 -05:00
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
Delegate *delegate_;
|
|
|
|
|
2018-11-19 14:24:43 -06:00
|
|
|
std::atomic<uint32> token_request_;
|
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
DnsBlocker dns_blocker_;
|
|
|
|
DnsResolver dns_resolver_;
|
|
|
|
|
|
|
|
uint32 last_tun_adapter_failed_;
|
|
|
|
StatsCollector stats_collector_;
|
|
|
|
|
|
|
|
Mutex stats_mutex_;
|
|
|
|
WgProcessorStats stats_;
|
2018-09-15 11:22:05 -05:00
|
|
|
|
|
|
|
char guid_[ADAPTER_GUID_SIZE];
|
2018-08-11 20:27:14 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
// This class ensures that all callbacks get rescheduled to another thread
|
|
|
|
class TunsafeBackendDelegateThreaded : public TunsafeBackend::Delegate {
|
|
|
|
public:
|
|
|
|
TunsafeBackendDelegateThreaded(TunsafeBackend::Delegate *delegate, const std::function<void(void)> &callback);
|
|
|
|
~TunsafeBackendDelegateThreaded();
|
|
|
|
|
|
|
|
private:
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual void OnGetStats(const WgProcessorStats &stats) override;
|
|
|
|
virtual void OnGraphAvailable() override;
|
|
|
|
virtual void OnStateChanged() override;
|
|
|
|
virtual void OnClearLog() override;
|
|
|
|
virtual void OnLogLine(const char **s) override;
|
|
|
|
virtual void OnStatusCode(TunsafeBackend::StatusCode status) override;
|
|
|
|
virtual void OnConfigurationProtocolReply(uint32 ident, const std::string &&reply) override;
|
|
|
|
virtual void DoWork() override;
|
2018-08-11 20:27:14 -05:00
|
|
|
|
|
|
|
enum Which {
|
|
|
|
Id_OnGetStats,
|
|
|
|
Id_OnStateChanged,
|
|
|
|
Id_OnClearLog,
|
|
|
|
Id_OnLogLine,
|
|
|
|
Id_OnUpdateUI,
|
|
|
|
Id_OnStatusCode,
|
|
|
|
Id_OnGraphAvailable,
|
2018-09-15 11:22:05 -05:00
|
|
|
Id_OnConfigurationProtocolReply,
|
2018-08-11 20:27:14 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
void AddEntry(Which which, intptr_t lparam = 0, uint32 wparam = 0);
|
|
|
|
|
|
|
|
TunsafeBackend::Delegate *delegate_;
|
|
|
|
std::function<void(void)> callback_;
|
|
|
|
|
|
|
|
struct Entry {
|
|
|
|
uint8 which;
|
|
|
|
uint32 wparam;
|
|
|
|
intptr_t lparam;
|
|
|
|
Entry(uint8 which, uint32 wparam, intptr_t lparam) : which(which), wparam(wparam), lparam(lparam) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
static void FreeEntry(Entry *e);
|
|
|
|
|
|
|
|
Mutex mutex_;
|
|
|
|
std::vector<Entry> incoming_entry_;
|
|
|
|
std::vector<Entry> processing_entry_;
|
|
|
|
};
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// For each adapter, remembers whether the adapter is in use
|
|
|
|
class TunAdaptersInUse {
|
|
|
|
public:
|
|
|
|
TunAdaptersInUse();
|
|
|
|
|
|
|
|
// attempt to acquire the adapter, so it can't be acquired by anyone else
|
|
|
|
bool Acquire(const char guid[ADAPTER_GUID_SIZE], void *context);
|
|
|
|
|
|
|
|
// mark as free
|
|
|
|
void Release(void *context);
|
|
|
|
|
|
|
|
// Lookup a context from a guid
|
|
|
|
void *LookupContextFromGuid(const char guid[ADAPTER_GUID_SIZE]);
|
|
|
|
|
|
|
|
// Lookup a guid from a context
|
|
|
|
bool LookupGuidFromContext(void *context, char guid[ADAPTER_GUID_SIZE]);
|
|
|
|
|
|
|
|
char *GetAllGuid();
|
|
|
|
|
|
|
|
static TunAdaptersInUse *GetInstance();
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum {
|
|
|
|
kMaxAdaptersInUse = 16,
|
|
|
|
};
|
|
|
|
struct Entry {
|
|
|
|
char guid[ADAPTER_GUID_SIZE];
|
|
|
|
void *context;
|
|
|
|
int count;
|
|
|
|
};
|
|
|
|
Mutex mutex_;
|
|
|
|
uint8 num_inuse_;
|
|
|
|
Entry entry_[kMaxAdaptersInUse];
|
|
|
|
};
|
2018-11-17 12:14:05 -06:00
|
|
|
|
|
|
|
static inline void ClearOverlapped(OVERLAPPED *o) {
|
|
|
|
memset(o, 0, sizeof(*o));
|
|
|
|
}
|
|
|
|
|