mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-04-24 00:00:05 +08:00
Refactor implementation of OpenVPNAdapter class
This commit is contained in:
+351
-370
@@ -8,265 +8,42 @@
|
||||
|
||||
#define OPENVPN_EXTERN extern
|
||||
|
||||
#import "OpenVPNAdapter.h"
|
||||
|
||||
#import <NetworkExtension/NetworkExtension.h>
|
||||
#import <client/ovpncli.hpp>
|
||||
#import <openvpn/tun/client/tunbase.hpp>
|
||||
|
||||
#import "OpenVPNClient.h"
|
||||
#import "OpenVPNError.h"
|
||||
#import "OpenVPNAdapterEvent.h"
|
||||
#import "OpenVPNCredentials+Internal.h"
|
||||
#import "OpenVPNConfiguration+Internal.h"
|
||||
#import "OpenVPNConnectionInfo+Internal.h"
|
||||
#import "OpenVPNError.h"
|
||||
#import "OpenVPNInterfaceStats+Internal.h"
|
||||
#import "OpenVPNNetworkSettingsBuilder.h"
|
||||
#import "OpenVPNPacketFlowBridge.h"
|
||||
#import "OpenVPNProperties+Internal.h"
|
||||
#import "OpenVPNSessionToken+Internal.h"
|
||||
#import "OpenVPNTransportStats+Internal.h"
|
||||
#import "OpenVPNAdapter.h"
|
||||
#import "OpenVPNAdapterPacketFlow.h"
|
||||
|
||||
class Client;
|
||||
@interface OpenVPNAdapter () <OpenVPNClientDelegate>
|
||||
|
||||
@interface OpenVPNAdapter ()
|
||||
|
||||
@property (nonatomic) Client *client;
|
||||
|
||||
@property (nonatomic) NSString *sessionName;
|
||||
|
||||
@property (nonatomic) OpenVPNNetworkSettingsBuilder *networkSettingsBuilder;
|
||||
@property (nonatomic) OpenVPNClient *vpnClient;
|
||||
|
||||
@property (nonatomic) OpenVPNPacketFlowBridge *packetFlowBridge;
|
||||
@property (nonatomic) OpenVPNNetworkSettingsBuilder *networkSettingsBuilder;
|
||||
|
||||
- (OpenVPNAdapterEvent)eventByName:(NSString *)eventName;
|
||||
- (OpenVPNAdapterError)errorByName:(NSString *)errorName;
|
||||
- (OpenVPNAdapterEvent)eventByName:(NSString *)errorName;
|
||||
- (NSString *)reasonForError:(OpenVPNAdapterError)error;
|
||||
|
||||
@end
|
||||
|
||||
using namespace openvpn;
|
||||
|
||||
class Client : public ClientAPI::OpenVPNClient {
|
||||
public:
|
||||
Client(OpenVPNAdapter *adapter) {
|
||||
this->adapter = adapter;
|
||||
}
|
||||
|
||||
bool tun_builder_set_remote_address(const std::string& address, bool ipv6) override {
|
||||
NSString *remoteAddress = [[NSString alloc] initWithUTF8String:address.c_str()];
|
||||
adapter.networkSettingsBuilder.remoteAddress = remoteAddress;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_add_address(const std::string& address, int prefix_length, const std::string& gateway, bool ipv6, bool net30) override {
|
||||
NSString *localAddress = [[NSString alloc] initWithUTF8String:address.c_str()];
|
||||
NSString *gatewayAddress = [[NSString alloc] initWithUTF8String:gateway.c_str()];
|
||||
NSString *defaultGateway = gatewayAddress.length == 0 || [gatewayAddress isEqualToString:@"UNSPEC"] ? nil : gatewayAddress;
|
||||
if (ipv6) {
|
||||
adapter.networkSettingsBuilder.ipv6DefaultGateway = defaultGateway;
|
||||
[adapter.networkSettingsBuilder.ipv6LocalAddresses addObject:localAddress];
|
||||
[adapter.networkSettingsBuilder.ipv6NetworkPrefixLengths addObject:@(prefix_length)];
|
||||
} else {
|
||||
NSString *subnetMask = [[NSString alloc] initWithUTF8String:IPv4::Addr::netmask_from_prefix_len(prefix_length).to_string().c_str()];
|
||||
adapter.networkSettingsBuilder.ipv4DefaultGateway = defaultGateway;
|
||||
[adapter.networkSettingsBuilder.ipv4LocalAddresses addObject:localAddress];
|
||||
[adapter.networkSettingsBuilder.ipv4SubnetMasks addObject:subnetMask];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_reroute_gw(bool ipv4, bool ipv6, unsigned int flags) override {
|
||||
if (ipv4) {
|
||||
NEIPv4Route *includedRoute = [NEIPv4Route defaultRoute];
|
||||
includedRoute.gatewayAddress = adapter.networkSettingsBuilder.ipv4DefaultGateway;
|
||||
[adapter.networkSettingsBuilder.ipv4IncludedRoutes addObject:includedRoute];
|
||||
}
|
||||
if (ipv6) {
|
||||
NEIPv6Route *includedRoute = [NEIPv6Route defaultRoute];
|
||||
includedRoute.gatewayAddress = adapter.networkSettingsBuilder.ipv6DefaultGateway;
|
||||
[adapter.networkSettingsBuilder.ipv6IncludedRoutes addObject:includedRoute];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_add_route(const std::string& address, int prefix_length, int metric, bool ipv6) override {
|
||||
NSString *route = [[NSString alloc] initWithUTF8String:address.c_str()];
|
||||
if (ipv6) {
|
||||
NEIPv6Route *includedRoute = [[NEIPv6Route alloc] initWithDestinationAddress:route networkPrefixLength:@(prefix_length)];
|
||||
includedRoute.gatewayAddress = adapter.networkSettingsBuilder.ipv6DefaultGateway;
|
||||
[adapter.networkSettingsBuilder.ipv6IncludedRoutes addObject:includedRoute];
|
||||
} else {
|
||||
NSString *subnetMask = [[NSString alloc] initWithUTF8String:IPv4::Addr::netmask_from_prefix_len(prefix_length).to_string().c_str()];
|
||||
NEIPv4Route *includedRoute = [[NEIPv4Route alloc] initWithDestinationAddress:route subnetMask:subnetMask];
|
||||
includedRoute.gatewayAddress = adapter.networkSettingsBuilder.ipv4DefaultGateway;
|
||||
[adapter.networkSettingsBuilder.ipv4IncludedRoutes addObject:includedRoute];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_exclude_route(const std::string& address, int prefix_length, int metric, bool ipv6) override {
|
||||
NSString *route = [[NSString alloc] initWithUTF8String:address.c_str()];
|
||||
if (ipv6) {
|
||||
NEIPv6Route *excludedRoute = [[NEIPv6Route alloc] initWithDestinationAddress:route networkPrefixLength:@(prefix_length)];
|
||||
[adapter.networkSettingsBuilder.ipv6ExcludedRoutes addObject:excludedRoute];
|
||||
} else {
|
||||
NSString *subnetMask = [[NSString alloc] initWithUTF8String:IPv4::Addr::netmask_from_prefix_len(prefix_length).to_string().c_str()];
|
||||
NEIPv4Route *excludedRoute = [[NEIPv4Route alloc] initWithDestinationAddress:route subnetMask:subnetMask];
|
||||
[adapter.networkSettingsBuilder.ipv4ExcludedRoutes addObject:excludedRoute];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_add_dns_server(const std::string& address, bool ipv6) override {
|
||||
NSString *dnsAddress = [[NSString alloc] initWithUTF8String:address.c_str()];
|
||||
[adapter.networkSettingsBuilder.dnsServers addObject:dnsAddress];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_add_search_domain(const std::string& domain) override {
|
||||
NSString *searchDomain = [[NSString alloc] initWithUTF8String:domain.c_str()];
|
||||
[adapter.networkSettingsBuilder.searchDomains addObject:searchDomain];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_set_mtu(int mtu) override {
|
||||
adapter.networkSettingsBuilder.mtu = @(mtu);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_set_session_name(const std::string& name) override {
|
||||
adapter.sessionName = [[NSString alloc] initWithUTF8String:name.c_str()];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_add_proxy_bypass(const std::string& bypass_host) override {
|
||||
NSString *bypassHost = [[NSString alloc] initWithUTF8String:bypass_host.c_str()];
|
||||
[adapter.networkSettingsBuilder.proxyExceptionList addObject:bypassHost];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_set_proxy_auto_config_url(const std::string& urlString) override {
|
||||
NSURL *url = [[NSURL alloc] initWithString:[[NSString alloc] initWithUTF8String:urlString.c_str()]];
|
||||
adapter.networkSettingsBuilder.autoProxyConfigurationEnabled = url != nil;
|
||||
adapter.networkSettingsBuilder.proxyAutoConfigurationURL = url;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_set_proxy_http(const std::string& host, int port) override {
|
||||
NSString *address = [[NSString alloc] initWithUTF8String:host.c_str()];
|
||||
adapter.networkSettingsBuilder.httpProxyServerEnabled = YES;
|
||||
adapter.networkSettingsBuilder.httpProxyServer = [[NEProxyServer alloc] initWithAddress:address port:port];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_set_proxy_https(const std::string& host, int port) override {
|
||||
NSString *address = [[NSString alloc] initWithUTF8String:host.c_str()];
|
||||
adapter.networkSettingsBuilder.httpsProxyServerEnabled = YES;
|
||||
adapter.networkSettingsBuilder.httpsProxyServer = [[NEProxyServer alloc] initWithAddress:address port:port];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tun_builder_set_block_ipv6(bool block_ipv6) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tun_builder_new() override {
|
||||
reset_tun();
|
||||
return true;
|
||||
}
|
||||
|
||||
int tun_builder_establish() override {
|
||||
NEPacketTunnelNetworkSettings *networkSettings = adapter.networkSettingsBuilder.networkSettings;
|
||||
if (!networkSettings) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
[adapter.delegate openVPNAdapter:adapter configureTunnelWithNetworkSettings:networkSettings completionHandler:^(NEPacketTunnelFlow * _Nullable flow) {
|
||||
adapter.packetFlowBridge = [[OpenVPNPacketFlowBridge alloc] initWithPacketFlow:flow];
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC));
|
||||
|
||||
if (adapter.packetFlowBridge) {
|
||||
return adapter.packetFlowBridge.socketHandle;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void tun_builder_teardown(bool disconnect) override {
|
||||
reset_tun();
|
||||
}
|
||||
|
||||
bool tun_builder_persist() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool socket_protect(int socket) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pause_on_connection_timeout() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void external_pki_cert_request(ClientAPI::ExternalPKICertRequest& certreq) override {
|
||||
|
||||
}
|
||||
|
||||
void external_pki_sign_request(ClientAPI::ExternalPKISignRequest& signreq) override {
|
||||
|
||||
}
|
||||
|
||||
void event(const ClientAPI::Event& event) override {
|
||||
NSString *name = [[NSString alloc] initWithUTF8String:event.name.c_str()];
|
||||
NSString *message = [[NSString alloc] initWithUTF8String:event.info.c_str()];
|
||||
|
||||
if (event.error) {
|
||||
OpenVPNAdapterError errorCode = [adapter errorByName:name];
|
||||
NSString *errorReason = [adapter reasonForError:errorCode];
|
||||
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: @"OpenVPN error occured.",
|
||||
NSLocalizedFailureReasonErrorKey: errorReason,
|
||||
OpenVPNAdapterErrorMessageKey: message != nil ? message : @"",
|
||||
OpenVPNAdapterErrorFatalKey: @(event.fatal) };
|
||||
|
||||
NSError *error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:errorCode userInfo:userInfo];
|
||||
[adapter.delegate openVPNAdapter:adapter handleError:error];
|
||||
} else {
|
||||
OpenVPNAdapterEvent eventIdentifier = [adapter eventByName:name];
|
||||
[adapter.delegate openVPNAdapter:adapter handleEvent:eventIdentifier message:message.length ? message : nil];
|
||||
}
|
||||
}
|
||||
|
||||
void log(const ClientAPI::LogInfo& log) override {
|
||||
if ([adapter.delegate respondsToSelector:@selector(openVPNAdapter:handleLogMessage:)]) {
|
||||
[adapter.delegate openVPNAdapter:adapter handleLogMessage:[[NSString alloc] initWithUTF8String:log.text.c_str()]];
|
||||
}
|
||||
}
|
||||
|
||||
void clock_tick() override {
|
||||
if ([adapter.delegate respondsToSelector:@selector(openVPNAdapterDidReceiveClockTick:)]) {
|
||||
[adapter.delegate openVPNAdapterDidReceiveClockTick:adapter];
|
||||
}
|
||||
}
|
||||
|
||||
void reset_tun() {
|
||||
adapter.packetFlowBridge = nil;
|
||||
adapter.networkSettingsBuilder = nil;
|
||||
adapter.sessionName = nil;
|
||||
}
|
||||
|
||||
private:
|
||||
OpenVPNAdapter *adapter;
|
||||
};
|
||||
|
||||
@implementation OpenVPNAdapter
|
||||
|
||||
#pragma mark - Initialization
|
||||
|
||||
- (instancetype)init {
|
||||
if ((self = [super init])) {
|
||||
self.client = new Client(self);
|
||||
if (self = [super init]) {
|
||||
_vpnClient = new OpenVPNClient(self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -274,16 +51,24 @@ private:
|
||||
#pragma mark - OpenVPNClient Lifecycle
|
||||
|
||||
- (OpenVPNProperties *)applyConfiguration:(OpenVPNConfiguration *)configuration error:(NSError * _Nullable __autoreleasing *)error {
|
||||
ClientAPI::EvalConfig eval = self.client->eval_config(configuration.config);
|
||||
ClientAPI::EvalConfig eval = self.vpnClient->eval_config(configuration.config);
|
||||
|
||||
if (eval.error) {
|
||||
if (error) {
|
||||
NSString *errorReason = [self reasonForError:OpenVPNAdapterErrorConfigurationFailure];
|
||||
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{
|
||||
NSLocalizedDescriptionKey: @"Failed to apply OpenVPN configuration",
|
||||
OpenVPNAdapterErrorFatalKey: @YES
|
||||
}];
|
||||
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: @"Failed to apply OpenVPN configuration.",
|
||||
NSLocalizedFailureReasonErrorKey: errorReason,
|
||||
OpenVPNAdapterErrorMessageKey: [[NSString alloc] initWithUTF8String:eval.message.c_str()],
|
||||
OpenVPNAdapterErrorFatalKey: @YES };
|
||||
NSString *errorReason = [self reasonForError:OpenVPNAdapterErrorConfigurationFailure];
|
||||
if (errorReason) {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = errorReason;
|
||||
}
|
||||
|
||||
NSString *message = [[NSString alloc] initWithUTF8String:eval.message.c_str()];
|
||||
if (message.length) {
|
||||
userInfo[OpenVPNAdapterErrorMessageKey] = message;
|
||||
}
|
||||
|
||||
*error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:OpenVPNAdapterErrorConfigurationFailure userInfo: userInfo];
|
||||
}
|
||||
@@ -294,7 +79,7 @@ private:
|
||||
}
|
||||
|
||||
- (BOOL)provideCredentials:(OpenVPNCredentials *)credentials error:(NSError * _Nullable __autoreleasing *)error {
|
||||
ClientAPI::Status status = self.client->provide_creds(credentials.credentials);
|
||||
ClientAPI::Status status = self.vpnClient->provide_creds(credentials.credentials);
|
||||
|
||||
if (status.error) {
|
||||
if (error) {
|
||||
@@ -302,12 +87,20 @@ private:
|
||||
[self errorByName:[[NSString alloc] initWithUTF8String:status.status.c_str()]] :
|
||||
OpenVPNAdapterErrorCredentialsFailure;
|
||||
|
||||
NSString *errorReason = [self reasonForError:errorCode];
|
||||
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{
|
||||
NSLocalizedDescriptionKey: @"Failed to provide OpenVPN credentials",
|
||||
OpenVPNAdapterErrorFatalKey: @YES
|
||||
}];
|
||||
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: @"Failed to provide OpenVPN credentials.",
|
||||
NSLocalizedFailureReasonErrorKey: errorReason,
|
||||
OpenVPNAdapterErrorMessageKey: [[NSString alloc] initWithUTF8String:status.message.c_str()],
|
||||
OpenVPNAdapterErrorFatalKey: @YES };
|
||||
NSString *errorReason = [self reasonForError:errorCode];
|
||||
if (errorReason) {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = errorReason;
|
||||
}
|
||||
|
||||
NSString *message = [[NSString alloc] initWithUTF8String:status.message.c_str()];
|
||||
if (message.length) {
|
||||
userInfo[OpenVPNAdapterErrorMessageKey] = message;
|
||||
}
|
||||
|
||||
*error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:errorCode userInfo:userInfo];
|
||||
}
|
||||
@@ -320,43 +113,53 @@ private:
|
||||
|
||||
- (void)connect {
|
||||
dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
|
||||
dispatch_queue_t connectQueue = dispatch_queue_create("com.openvpnadapter.connection", attributes);
|
||||
dispatch_queue_t connectQueue = dispatch_queue_create("me.ss-abramchuk.openvpn-adapter.connection", attributes);
|
||||
dispatch_async(connectQueue, ^{
|
||||
Client::init_process();
|
||||
ClientAPI::Status status = self.client->connect();
|
||||
OpenVPNClient::init_process();
|
||||
|
||||
ClientAPI::Status status = self.vpnClient->connect();
|
||||
[self handleConnectionStatus:status];
|
||||
Client::uninit_process();
|
||||
|
||||
OpenVPNClient::uninit_process();
|
||||
});
|
||||
}
|
||||
|
||||
- (void)reconnectAfterTimeInterval:(NSTimeInterval)timeInterval {
|
||||
self.client->reconnect(timeInterval);
|
||||
self.vpnClient->reconnect(timeInterval);
|
||||
}
|
||||
|
||||
- (void)disconnect {
|
||||
self.client->stop();
|
||||
self.vpnClient->stop();
|
||||
}
|
||||
|
||||
- (void)pauseWithReason:(NSString *)reason {
|
||||
self.client->pause(std::string(reason.UTF8String));
|
||||
self.vpnClient->pause(std::string(reason.UTF8String));
|
||||
}
|
||||
|
||||
- (void)resume {
|
||||
self.client->resume();
|
||||
self.vpnClient->resume();
|
||||
}
|
||||
|
||||
- (void)handleConnectionStatus:(ClientAPI::Status)status {
|
||||
if (!status.error) {
|
||||
return;
|
||||
if (!status.error) { return; }
|
||||
|
||||
OpenVPNAdapterError errorCode = !status.status.empty() ?
|
||||
[self errorByName:[[NSString alloc] initWithUTF8String:status.status.c_str()]] : OpenVPNAdapterErrorUnknown;
|
||||
|
||||
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{
|
||||
NSLocalizedDescriptionKey: @"Failed to establish connection with OpenVPN server",
|
||||
OpenVPNAdapterErrorFatalKey: @YES
|
||||
}];
|
||||
|
||||
NSString *errorReason = [self reasonForError:errorCode];
|
||||
if (errorReason) {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = errorReason;
|
||||
}
|
||||
|
||||
OpenVPNAdapterError errorCode = !status.status.empty() ? [self errorByName:[[NSString alloc] initWithUTF8String:status.status.c_str()]] : OpenVPNAdapterErrorUnknown;
|
||||
NSString *errorReason = [self reasonForError:errorCode];
|
||||
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: @"Failed to establish connection with OpenVPN server.",
|
||||
NSLocalizedFailureReasonErrorKey: errorReason,
|
||||
OpenVPNAdapterErrorMessageKey: [[NSString alloc] initWithUTF8String:status.message.c_str()],
|
||||
OpenVPNAdapterErrorFatalKey: @YES };
|
||||
NSString *message = [[NSString alloc] initWithUTF8String:status.message.c_str()];
|
||||
if (message.length) {
|
||||
userInfo[OpenVPNAdapterErrorMessageKey] = message;
|
||||
}
|
||||
|
||||
NSError *error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:errorCode userInfo:userInfo];
|
||||
[self.delegate openVPNAdapter:self handleError:error];
|
||||
@@ -365,50 +168,52 @@ private:
|
||||
#pragma mark - OpenVPNClient Information
|
||||
|
||||
+ (NSString *)copyright {
|
||||
return [[NSString alloc] initWithUTF8String:Client::copyright().c_str()];
|
||||
return [[NSString alloc] initWithUTF8String:OpenVPNClient::copyright().c_str()];
|
||||
}
|
||||
|
||||
+ (NSString *)platform {
|
||||
return [[NSString alloc] initWithUTF8String:Client::platform().c_str()];
|
||||
return [[NSString alloc] initWithUTF8String:OpenVPNClient::platform().c_str()];
|
||||
}
|
||||
|
||||
- (OpenVPNConnectionInfo *)connectionInformation {
|
||||
ClientAPI::ConnectionInfo information = self.client->connection_info();
|
||||
ClientAPI::ConnectionInfo information = self.vpnClient->connection_info();
|
||||
return information.defined ? [[OpenVPNConnectionInfo alloc] initWithConnectionInfo:information] : nil;
|
||||
}
|
||||
|
||||
- (OpenVPNInterfaceStats *)interfaceStatistics {
|
||||
return [[OpenVPNInterfaceStats alloc] initWithInterfaceStats:self.client->tun_stats()];
|
||||
return [[OpenVPNInterfaceStats alloc] initWithInterfaceStats:self.vpnClient->tun_stats()];
|
||||
}
|
||||
|
||||
- (OpenVPNSessionToken *)sessionToken {
|
||||
ClientAPI::SessionToken token;
|
||||
return self.client->session_token(token) ? [[OpenVPNSessionToken alloc] initWithSessionToken:token] : nil;
|
||||
return self.vpnClient->session_token(token) ? [[OpenVPNSessionToken alloc] initWithSessionToken:token] : nil;
|
||||
}
|
||||
|
||||
- (OpenVPNTransportStats *)transportStatistics {
|
||||
return [[OpenVPNTransportStats alloc] initWithTransportStats:self.client->transport_stats()];
|
||||
return [[OpenVPNTransportStats alloc] initWithTransportStats:self.vpnClient->transport_stats()];
|
||||
}
|
||||
|
||||
#pragma mark - OpenVPNAdapterEvent Helpers
|
||||
|
||||
- (OpenVPNAdapterEvent)eventByName:(NSString *)eventName {
|
||||
NSDictionary *events = @{@"DISCONNECTED": @(OpenVPNAdapterEventDisconnected),
|
||||
@"CONNECTED": @(OpenVPNAdapterEventConnected),
|
||||
@"RECONNECTING": @(OpenVPNAdapterEventReconnecting),
|
||||
@"RESOLVE": @(OpenVPNAdapterEventResolve),
|
||||
@"WAIT": @(OpenVPNAdapterEventWait),
|
||||
@"WAIT_PROXY": @(OpenVPNAdapterEventWaitProxy),
|
||||
@"CONNECTING": @(OpenVPNAdapterEventConnecting),
|
||||
@"GET_CONFIG": @(OpenVPNAdapterEventGetConfig),
|
||||
@"ASSIGN_IP": @(OpenVPNAdapterEventAssignIP),
|
||||
@"ADD_ROUTES": @(OpenVPNAdapterEventAddRoutes),
|
||||
@"ECHO": @(OpenVPNAdapterEventEcho),
|
||||
@"INFO": @(OpenVPNAdapterEventInfo),
|
||||
@"PAUSE": @(OpenVPNAdapterEventPause),
|
||||
@"RESUME": @(OpenVPNAdapterEventResume),
|
||||
@"RELAY": @(OpenVPNAdapterEventRelay)};
|
||||
|
||||
NSDictionary *events = @{
|
||||
@"DISCONNECTED": @(OpenVPNAdapterEventDisconnected),
|
||||
@"CONNECTED": @(OpenVPNAdapterEventConnected),
|
||||
@"RECONNECTING": @(OpenVPNAdapterEventReconnecting),
|
||||
@"RESOLVE": @(OpenVPNAdapterEventResolve),
|
||||
@"WAIT": @(OpenVPNAdapterEventWait),
|
||||
@"WAIT_PROXY": @(OpenVPNAdapterEventWaitProxy),
|
||||
@"CONNECTING": @(OpenVPNAdapterEventConnecting),
|
||||
@"GET_CONFIG": @(OpenVPNAdapterEventGetConfig),
|
||||
@"ASSIGN_IP": @(OpenVPNAdapterEventAssignIP),
|
||||
@"ADD_ROUTES": @(OpenVPNAdapterEventAddRoutes),
|
||||
@"ECHO": @(OpenVPNAdapterEventEcho),
|
||||
@"INFO": @(OpenVPNAdapterEventInfo),
|
||||
@"PAUSE": @(OpenVPNAdapterEventPause),
|
||||
@"RESUME": @(OpenVPNAdapterEventResume),
|
||||
@"RELAY": @(OpenVPNAdapterEventRelay)
|
||||
};
|
||||
|
||||
OpenVPNAdapterEvent event = events[eventName] != nil ? (OpenVPNAdapterEvent)[events[eventName] integerValue] : OpenVPNAdapterEventUnknown;
|
||||
return event;
|
||||
}
|
||||
@@ -416,76 +221,79 @@ private:
|
||||
#pragma mark - OpenVPNAdapterError Helpers
|
||||
|
||||
- (OpenVPNAdapterError)errorByName:(NSString *)errorName {
|
||||
NSDictionary *errors = @{@"NETWORK_RECV_ERROR": @(OpenVPNAdapterErrorNetworkRecvError),
|
||||
@"NETWORK_EOF_ERROR": @(OpenVPNAdapterErrorNetworkEOFError),
|
||||
@"NETWORK_SEND_ERROR": @(OpenVPNAdapterErrorNetworkSendError),
|
||||
@"NETWORK_UNAVAILABLE": @(OpenVPNAdapterErrorNetworkUnavailable),
|
||||
@"DECRYPT_ERROR": @(OpenVPNAdapterErrorDecryptError),
|
||||
@"HMAC_ERROR": @(OpenVPNAdapterErrorDecryptError),
|
||||
@"REPLAY_ERROR": @(OpenVPNAdapterErrorReplayError),
|
||||
@"BUFFER_ERROR": @(OpenVPNAdapterErrorBufferError),
|
||||
@"CC_ERROR": @(OpenVPNAdapterErrorCCError),
|
||||
@"BAD_SRC_ADDR": @(OpenVPNAdapterErrorBadSrcAddr),
|
||||
@"COMPRESS_ERROR": @(OpenVPNAdapterErrorCompressError),
|
||||
@"RESOLVE_ERROR": @(OpenVPNAdapterErrorResolveError),
|
||||
@"SOCKET_PROTECT_ERROR": @(OpenVPNAdapterErrorSocketProtectError),
|
||||
@"TUN_READ_ERROR": @(OpenVPNAdapterErrorTUNReadError),
|
||||
@"TUN_WRITE_ERROR": @(OpenVPNAdapterErrorTUNWriteError),
|
||||
@"TUN_FRAMING_ERROR": @(OpenVPNAdapterErrorTUNFramingError),
|
||||
@"TUN_SETUP_FAILED": @(OpenVPNAdapterErrorTUNSetupFailed),
|
||||
@"TUN_IFACE_CREATE": @(OpenVPNAdapterErrorTUNIfaceCreate),
|
||||
@"TUN_IFACE_DISABLED": @(OpenVPNAdapterErrorTUNIfaceDisabled),
|
||||
@"TUN_ERROR": @(OpenVPNAdapterErrorTUNError),
|
||||
@"TAP_NOT_SUPPORTED": @(OpenVPNAdapterErrorTAPNotSupported),
|
||||
@"REROUTE_GW_NO_DNS": @(OpenVPNAdapterErrorRerouteGatewayNoDns),
|
||||
@"TRANSPORT_ERROR": @(OpenVPNAdapterErrorTransportError),
|
||||
@"TCP_OVERFLOW": @(OpenVPNAdapterErrorTCPOverflow),
|
||||
@"TCP_SIZE_ERROR": @(OpenVPNAdapterErrorTCPSizeError),
|
||||
@"TCP_CONNECT_ERROR": @(OpenVPNAdapterErrorTCPConnectError),
|
||||
@"UDP_CONNECT_ERROR": @(OpenVPNAdapterErrorUDPConnectError),
|
||||
@"SSL_ERROR": @(OpenVPNAdapterErrorSSLError),
|
||||
@"SSL_PARTIAL_WRITE": @(OpenVPNAdapterErrorSSLPartialWrite),
|
||||
@"ENCAPSULATION_ERROR": @(OpenVPNAdapterErrorEncapsulationError),
|
||||
@"EPKI_CERT_ERROR": @(OpenVPNAdapterErrorEPKICertError),
|
||||
@"EPKI_SIGN_ERROR": @(OpenVPNAdapterErrorEPKISignError),
|
||||
@"HANDSHAKE_TIMEOUT": @(OpenVPNAdapterErrorHandshakeTimeout),
|
||||
@"KEEPALIVE_TIMEOUT": @(OpenVPNAdapterErrorKeepaliveTimeout),
|
||||
@"INACTIVE_TIMEOUT": @(OpenVPNAdapterErrorInactiveTimeout),
|
||||
@"CONNECTION_TIMEOUT": @(OpenVPNAdapterErrorConnectionTimeout),
|
||||
@"PRIMARY_EXPIRE": @(OpenVPNAdapterErrorPrimaryExpire),
|
||||
@"TLS_VERSION_MIN": @(OpenVPNAdapterErrorTLSVersionMin),
|
||||
@"TLS_AUTH_FAIL": @(OpenVPNAdapterErrorTLSAuthFail),
|
||||
@"CERT_VERIFY_FAIL": @(OpenVPNAdapterErrorCertVerifyFail),
|
||||
@"PEM_PASSWORD_FAIL": @(OpenVPNAdapterErrorPEMPasswordFail),
|
||||
@"AUTH_FAILED": @(OpenVPNAdapterErrorAuthFailed),
|
||||
@"CLIENT_HALT": @(OpenVPNAdapterErrorClientHalt),
|
||||
@"CLIENT_RESTART": @(OpenVPNAdapterErrorClientRestart),
|
||||
@"RELAY": @(OpenVPNAdapterErrorRelay),
|
||||
@"RELAY_ERROR": @(OpenVPNAdapterErrorRelayError),
|
||||
@"N_PAUSE": @(OpenVPNAdapterErrorPauseNumber),
|
||||
@"N_RECONNECT": @(OpenVPNAdapterErrorReconnectNumber),
|
||||
@"N_KEY_LIMIT_RENEG": @(OpenVPNAdapterErrorKeyLimitRenegNumber),
|
||||
@"KEY_STATE_ERROR": @(OpenVPNAdapterErrorKeyStateError),
|
||||
@"PROXY_ERROR": @(OpenVPNAdapterErrorProxyError),
|
||||
@"PROXY_NEED_CREDS": @(OpenVPNAdapterErrorProxyNeedCreds),
|
||||
@"KEV_NEGOTIATE_ERROR": @(OpenVPNAdapterErrorKevNegotiateError),
|
||||
@"KEV_PENDING_ERROR": @(OpenVPNAdapterErrorKevPendingError),
|
||||
@"N_KEV_EXPIRE": @(OpenVPNAdapterErrorKevExpireNumber),
|
||||
@"PKTID_INVALID": @(OpenVPNAdapterErrorPKTIDInvalid),
|
||||
@"PKTID_BACKTRACK": @(OpenVPNAdapterErrorPKTIDBacktrack),
|
||||
@"PKTID_EXPIRE": @(OpenVPNAdapterErrorPKTIDExpire),
|
||||
@"PKTID_REPLAY": @(OpenVPNAdapterErrorPKTIDReplay),
|
||||
@"PKTID_TIME_BACKTRACK": @(OpenVPNAdapterErrorPKTIDTimeBacktrack),
|
||||
@"DYNAMIC_CHALLENGE": @(OpenVPNAdapterErrorDynamicChallenge),
|
||||
@"EPKI_ERROR": @(OpenVPNAdapterErrorEPKIError),
|
||||
@"EPKI_INVALID_ALIAS": @(OpenVPNAdapterErrorEPKIInvalidAlias)};
|
||||
NSDictionary *errors = @{
|
||||
@"NETWORK_RECV_ERROR": @(OpenVPNAdapterErrorNetworkRecvError),
|
||||
@"NETWORK_EOF_ERROR": @(OpenVPNAdapterErrorNetworkEOFError),
|
||||
@"NETWORK_SEND_ERROR": @(OpenVPNAdapterErrorNetworkSendError),
|
||||
@"NETWORK_UNAVAILABLE": @(OpenVPNAdapterErrorNetworkUnavailable),
|
||||
@"DECRYPT_ERROR": @(OpenVPNAdapterErrorDecryptError),
|
||||
@"HMAC_ERROR": @(OpenVPNAdapterErrorDecryptError),
|
||||
@"REPLAY_ERROR": @(OpenVPNAdapterErrorReplayError),
|
||||
@"BUFFER_ERROR": @(OpenVPNAdapterErrorBufferError),
|
||||
@"CC_ERROR": @(OpenVPNAdapterErrorCCError),
|
||||
@"BAD_SRC_ADDR": @(OpenVPNAdapterErrorBadSrcAddr),
|
||||
@"COMPRESS_ERROR": @(OpenVPNAdapterErrorCompressError),
|
||||
@"RESOLVE_ERROR": @(OpenVPNAdapterErrorResolveError),
|
||||
@"SOCKET_PROTECT_ERROR": @(OpenVPNAdapterErrorSocketProtectError),
|
||||
@"TUN_READ_ERROR": @(OpenVPNAdapterErrorTUNReadError),
|
||||
@"TUN_WRITE_ERROR": @(OpenVPNAdapterErrorTUNWriteError),
|
||||
@"TUN_FRAMING_ERROR": @(OpenVPNAdapterErrorTUNFramingError),
|
||||
@"TUN_SETUP_FAILED": @(OpenVPNAdapterErrorTUNSetupFailed),
|
||||
@"TUN_IFACE_CREATE": @(OpenVPNAdapterErrorTUNIfaceCreate),
|
||||
@"TUN_IFACE_DISABLED": @(OpenVPNAdapterErrorTUNIfaceDisabled),
|
||||
@"TUN_ERROR": @(OpenVPNAdapterErrorTUNError),
|
||||
@"TAP_NOT_SUPPORTED": @(OpenVPNAdapterErrorTAPNotSupported),
|
||||
@"REROUTE_GW_NO_DNS": @(OpenVPNAdapterErrorRerouteGatewayNoDns),
|
||||
@"TRANSPORT_ERROR": @(OpenVPNAdapterErrorTransportError),
|
||||
@"TCP_OVERFLOW": @(OpenVPNAdapterErrorTCPOverflow),
|
||||
@"TCP_SIZE_ERROR": @(OpenVPNAdapterErrorTCPSizeError),
|
||||
@"TCP_CONNECT_ERROR": @(OpenVPNAdapterErrorTCPConnectError),
|
||||
@"UDP_CONNECT_ERROR": @(OpenVPNAdapterErrorUDPConnectError),
|
||||
@"SSL_ERROR": @(OpenVPNAdapterErrorSSLError),
|
||||
@"SSL_PARTIAL_WRITE": @(OpenVPNAdapterErrorSSLPartialWrite),
|
||||
@"ENCAPSULATION_ERROR": @(OpenVPNAdapterErrorEncapsulationError),
|
||||
@"EPKI_CERT_ERROR": @(OpenVPNAdapterErrorEPKICertError),
|
||||
@"EPKI_SIGN_ERROR": @(OpenVPNAdapterErrorEPKISignError),
|
||||
@"HANDSHAKE_TIMEOUT": @(OpenVPNAdapterErrorHandshakeTimeout),
|
||||
@"KEEPALIVE_TIMEOUT": @(OpenVPNAdapterErrorKeepaliveTimeout),
|
||||
@"INACTIVE_TIMEOUT": @(OpenVPNAdapterErrorInactiveTimeout),
|
||||
@"CONNECTION_TIMEOUT": @(OpenVPNAdapterErrorConnectionTimeout),
|
||||
@"PRIMARY_EXPIRE": @(OpenVPNAdapterErrorPrimaryExpire),
|
||||
@"TLS_VERSION_MIN": @(OpenVPNAdapterErrorTLSVersionMin),
|
||||
@"TLS_AUTH_FAIL": @(OpenVPNAdapterErrorTLSAuthFail),
|
||||
@"CERT_VERIFY_FAIL": @(OpenVPNAdapterErrorCertVerifyFail),
|
||||
@"PEM_PASSWORD_FAIL": @(OpenVPNAdapterErrorPEMPasswordFail),
|
||||
@"AUTH_FAILED": @(OpenVPNAdapterErrorAuthFailed),
|
||||
@"CLIENT_HALT": @(OpenVPNAdapterErrorClientHalt),
|
||||
@"CLIENT_RESTART": @(OpenVPNAdapterErrorClientRestart),
|
||||
@"RELAY": @(OpenVPNAdapterErrorRelay),
|
||||
@"RELAY_ERROR": @(OpenVPNAdapterErrorRelayError),
|
||||
@"N_PAUSE": @(OpenVPNAdapterErrorPauseNumber),
|
||||
@"N_RECONNECT": @(OpenVPNAdapterErrorReconnectNumber),
|
||||
@"N_KEY_LIMIT_RENEG": @(OpenVPNAdapterErrorKeyLimitRenegNumber),
|
||||
@"KEY_STATE_ERROR": @(OpenVPNAdapterErrorKeyStateError),
|
||||
@"PROXY_ERROR": @(OpenVPNAdapterErrorProxyError),
|
||||
@"PROXY_NEED_CREDS": @(OpenVPNAdapterErrorProxyNeedCreds),
|
||||
@"KEV_NEGOTIATE_ERROR": @(OpenVPNAdapterErrorKevNegotiateError),
|
||||
@"KEV_PENDING_ERROR": @(OpenVPNAdapterErrorKevPendingError),
|
||||
@"N_KEV_EXPIRE": @(OpenVPNAdapterErrorKevExpireNumber),
|
||||
@"PKTID_INVALID": @(OpenVPNAdapterErrorPKTIDInvalid),
|
||||
@"PKTID_BACKTRACK": @(OpenVPNAdapterErrorPKTIDBacktrack),
|
||||
@"PKTID_EXPIRE": @(OpenVPNAdapterErrorPKTIDExpire),
|
||||
@"PKTID_REPLAY": @(OpenVPNAdapterErrorPKTIDReplay),
|
||||
@"PKTID_TIME_BACKTRACK": @(OpenVPNAdapterErrorPKTIDTimeBacktrack),
|
||||
@"DYNAMIC_CHALLENGE": @(OpenVPNAdapterErrorDynamicChallenge),
|
||||
@"EPKI_ERROR": @(OpenVPNAdapterErrorEPKIError),
|
||||
@"EPKI_INVALID_ALIAS": @(OpenVPNAdapterErrorEPKIInvalidAlias)
|
||||
};
|
||||
|
||||
OpenVPNAdapterError error = errors[errorName] != nil ?
|
||||
(OpenVPNAdapterError)[errors[errorName] integerValue] : OpenVPNAdapterErrorUnknown;
|
||||
|
||||
OpenVPNAdapterError error = errors[errorName] != nil ? (OpenVPNAdapterError)[errors[errorName] integerValue] : OpenVPNAdapterErrorUnknown;
|
||||
return error;
|
||||
}
|
||||
|
||||
- (NSString *)reasonForError:(OpenVPNAdapterError)error {
|
||||
// TODO: Add missing error reasons
|
||||
switch (error) {
|
||||
case OpenVPNAdapterErrorConfigurationFailure: return @"See OpenVPN error message for more details.";
|
||||
case OpenVPNAdapterErrorCredentialsFailure: return @"See OpenVPN error message for more details.";
|
||||
@@ -501,6 +309,7 @@ private:
|
||||
case OpenVPNAdapterErrorBadSrcAddr: return @"Packet from unknown source address.";
|
||||
case OpenVPNAdapterErrorCompressError: return @"Compress/Decompress errors on data channel.";
|
||||
case OpenVPNAdapterErrorResolveError: return @"DNS resolution error.";
|
||||
case OpenVPNAdapterErrorSocketSetupFailed: return nil;
|
||||
case OpenVPNAdapterErrorSocketProtectError: return @"Error calling protect() method on socket.";
|
||||
case OpenVPNAdapterErrorTUNReadError: return @"Read errors on TUN/TAP interface.";
|
||||
case OpenVPNAdapterErrorTUNWriteError: return @"Write errors on TUN/TAP interface.";
|
||||
@@ -535,23 +344,23 @@ private:
|
||||
case OpenVPNAdapterErrorClientRestart: return @"RESTART message from server received.";
|
||||
case OpenVPNAdapterErrorRelay: return @"RELAY message from server received.";
|
||||
case OpenVPNAdapterErrorRelayError: return @"RELAY error.";
|
||||
case OpenVPNAdapterErrorPauseNumber: return @"";
|
||||
case OpenVPNAdapterErrorReconnectNumber: return @"";
|
||||
case OpenVPNAdapterErrorKeyLimitRenegNumber: return @"";
|
||||
case OpenVPNAdapterErrorPauseNumber: return nil;
|
||||
case OpenVPNAdapterErrorReconnectNumber: return nil;
|
||||
case OpenVPNAdapterErrorKeyLimitRenegNumber: return nil;
|
||||
case OpenVPNAdapterErrorKeyStateError: return @"Received packet didn't match expected key state.";
|
||||
case OpenVPNAdapterErrorProxyError: return @"HTTP proxy error.";
|
||||
case OpenVPNAdapterErrorProxyNeedCreds: return @"HTTP proxy needs credentials.";
|
||||
case OpenVPNAdapterErrorKevNegotiateError: return @"";
|
||||
case OpenVPNAdapterErrorKevPendingError: return @"";
|
||||
case OpenVPNAdapterErrorKevExpireNumber: return @"";
|
||||
case OpenVPNAdapterErrorPKTIDInvalid: return @"";
|
||||
case OpenVPNAdapterErrorPKTIDBacktrack: return @"";
|
||||
case OpenVPNAdapterErrorPKTIDExpire: return @"";
|
||||
case OpenVPNAdapterErrorPKTIDReplay: return @"";
|
||||
case OpenVPNAdapterErrorPKTIDTimeBacktrack: return @"";
|
||||
case OpenVPNAdapterErrorDynamicChallenge: return @"";
|
||||
case OpenVPNAdapterErrorEPKIError: return @"";
|
||||
case OpenVPNAdapterErrorEPKIInvalidAlias: return @"";
|
||||
case OpenVPNAdapterErrorKevNegotiateError: return nil;
|
||||
case OpenVPNAdapterErrorKevPendingError: return nil;
|
||||
case OpenVPNAdapterErrorKevExpireNumber: return nil;
|
||||
case OpenVPNAdapterErrorPKTIDInvalid: return nil;
|
||||
case OpenVPNAdapterErrorPKTIDBacktrack: return nil;
|
||||
case OpenVPNAdapterErrorPKTIDExpire: return nil;
|
||||
case OpenVPNAdapterErrorPKTIDReplay: return nil;
|
||||
case OpenVPNAdapterErrorPKTIDTimeBacktrack: return nil;
|
||||
case OpenVPNAdapterErrorDynamicChallenge: return nil;
|
||||
case OpenVPNAdapterErrorEPKIError: return nil;
|
||||
case OpenVPNAdapterErrorEPKIInvalidAlias: return nil;
|
||||
case OpenVPNAdapterErrorUnknown: return @"Unknown error.";
|
||||
}
|
||||
}
|
||||
@@ -559,16 +368,188 @@ private:
|
||||
#pragma mark - Lazy Initialization
|
||||
|
||||
- (OpenVPNNetworkSettingsBuilder *)networkSettingsBuilder {
|
||||
if (!_networkSettingsBuilder) {
|
||||
_networkSettingsBuilder = [[OpenVPNNetworkSettingsBuilder alloc] init];
|
||||
}
|
||||
if (!_networkSettingsBuilder) { _networkSettingsBuilder = [[OpenVPNNetworkSettingsBuilder alloc] init]; }
|
||||
return _networkSettingsBuilder;
|
||||
}
|
||||
|
||||
#pragma mark - Dealloc
|
||||
#pragma mark - OpenVPNClientDelegate
|
||||
|
||||
- (BOOL)setRemoteAddress:(NSString *)address {
|
||||
self.networkSettingsBuilder.remoteAddress = address;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)addIPV4Address:(NSString *)address subnetMask:(NSString *)subnetMask gateway:(NSString *)gateway {
|
||||
self.networkSettingsBuilder.ipv4DefaultGateway = gateway;
|
||||
[self.networkSettingsBuilder.ipv4LocalAddresses addObject:address];
|
||||
[self.networkSettingsBuilder.ipv4SubnetMasks addObject:subnetMask];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)addIPV6Address:(NSString *)address prefixLength:(NSNumber *)prefixLength gateway:(NSString *)gateway {
|
||||
self.networkSettingsBuilder.ipv6DefaultGateway = gateway;
|
||||
[self.networkSettingsBuilder.ipv6LocalAddresses addObject:address];
|
||||
[self.networkSettingsBuilder.ipv6NetworkPrefixLengths addObject:prefixLength];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)addIPV4Route:(NEIPv4Route *)route {
|
||||
route.gatewayAddress = self.networkSettingsBuilder.ipv4DefaultGateway;
|
||||
[self.networkSettingsBuilder.ipv4IncludedRoutes addObject:route];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)addIPV6Route:(NEIPv6Route *)route {
|
||||
route.gatewayAddress = self.networkSettingsBuilder.ipv6DefaultGateway;
|
||||
[self.networkSettingsBuilder.ipv6IncludedRoutes addObject:route];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)excludeIPV4Route:(NEIPv4Route *)route {
|
||||
[self.networkSettingsBuilder.ipv4ExcludedRoutes addObject:route];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)excludeIPV6Route:(NEIPv6Route *)route {
|
||||
[self.networkSettingsBuilder.ipv6ExcludedRoutes addObject:route];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)addDNS:(NSString *)dns {
|
||||
[self.networkSettingsBuilder.dnsServers addObject:dns];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)addSearchDomain:(NSString *)domain {
|
||||
[self.networkSettingsBuilder.searchDomains addObject:domain];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)setMTU:(NSNumber *)mtu {
|
||||
self.networkSettingsBuilder.mtu = mtu;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)setSessionName:(NSString *)name {
|
||||
_sessionName = name;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)addProxyBypassHost:(NSString *)bypassHost {
|
||||
[self.networkSettingsBuilder.proxyExceptionList addObject:bypassHost];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)setProxyAutoConfigurationURL:(NSURL *)url {
|
||||
self.networkSettingsBuilder.autoProxyConfigurationEnabled = YES;
|
||||
self.networkSettingsBuilder.proxyAutoConfigurationURL = url;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)setProxyServer:(NEProxyServer *)server protocol:(OpenVPNProxyServerProtocol)protocol {
|
||||
switch (protocol) {
|
||||
case OpenVPNProxyServerProtocolHTTP:
|
||||
self.networkSettingsBuilder.httpProxyServerEnabled = YES;
|
||||
self.networkSettingsBuilder.httpProxyServer = server;
|
||||
break;
|
||||
|
||||
case OpenVPNProxyServerProtocolHTTPS:
|
||||
self.networkSettingsBuilder.httpsProxyServerEnabled = YES;
|
||||
self.networkSettingsBuilder.httpsProxyServer = server;
|
||||
break;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)establishTunnel {
|
||||
NEPacketTunnelNetworkSettings *networkSettings = [self.networkSettingsBuilder networkSettings];
|
||||
if (!networkSettings) { return NO; }
|
||||
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
void (^completionHandler)(id<OpenVPNAdapterPacketFlow> _Nullable) = ^(id<OpenVPNAdapterPacketFlow> flow) {
|
||||
__strong typeof(self) self = weakSelf;
|
||||
|
||||
if (flow) {
|
||||
self.packetFlowBridge = [[OpenVPNPacketFlowBridge alloc] initWithPacketFlow:flow];
|
||||
}
|
||||
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
};
|
||||
|
||||
[self.delegate openVPNAdapter:self configureTunnelWithNetworkSettings:networkSettings completionHandler:completionHandler];
|
||||
|
||||
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC));
|
||||
|
||||
NSError *socketError;
|
||||
if (self.packetFlowBridge && [self.packetFlowBridge configureSocketsWithError:&socketError]) {
|
||||
[self.packetFlowBridge startReading];
|
||||
return YES;
|
||||
} else {
|
||||
if (socketError) { [self.delegate openVPNAdapter:self handleError:socketError]; }
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (CFSocketNativeHandle)socketHandle {
|
||||
return CFSocketGetNative(self.packetFlowBridge.openVPNSocket);
|
||||
}
|
||||
|
||||
- (void)clientEventName:(NSString *)eventName message:(NSString *)message {
|
||||
OpenVPNAdapterEvent eventIdentifier = [self eventByName:eventName];
|
||||
[self.delegate openVPNAdapter:self handleEvent:eventIdentifier message:message];
|
||||
}
|
||||
|
||||
- (void)clientErrorName:(NSString *)errorName fatal:(BOOL)fatal message:(NSString *)message {
|
||||
OpenVPNAdapterError errorCode = [self errorByName:errorName];
|
||||
|
||||
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{
|
||||
NSLocalizedDescriptionKey: fatal ? @"OpenVPN fatal error occured" : @"OpenVPN error occured",
|
||||
OpenVPNAdapterErrorFatalKey: @(fatal)
|
||||
}];
|
||||
|
||||
NSString *errorReason = [self reasonForError:errorCode];
|
||||
if (errorReason) {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = errorReason;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
userInfo[OpenVPNAdapterErrorMessageKey] = message;
|
||||
}
|
||||
|
||||
NSError *error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:errorCode userInfo:userInfo];
|
||||
[self.delegate openVPNAdapter:self handleError:error];
|
||||
}
|
||||
|
||||
- (void)clientLogMessage:(NSString *)logMessage {
|
||||
if ([self.delegate respondsToSelector:@selector(openVPNAdapter:handleLogMessage:)]) {
|
||||
[self.delegate openVPNAdapter:self handleLogMessage:logMessage];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tick {
|
||||
if ([self.delegate respondsToSelector:@selector(openVPNAdapterDidReceiveClockTick:)]) {
|
||||
[self.delegate openVPNAdapterDidReceiveClockTick:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)resetSettings {
|
||||
_sessionName = nil;
|
||||
_packetFlowBridge = nil;
|
||||
_networkSettingsBuilder = nil;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)dealloc {
|
||||
delete _client;
|
||||
delete _vpnClient;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user