From 6130e19c62629a45071d8cc7e08e77bb73b3a071 Mon Sep 17 00:00:00 2001 From: Sergey Abramchuk Date: Sun, 26 Feb 2017 15:36:03 +0300 Subject: [PATCH] Store and reset TUN configuration --- OpenVPN Tunnel Provider/OpenVPNAdapter.mm | 104 ++++++++++++++++++++-- 1 file changed, 96 insertions(+), 8 deletions(-) diff --git a/OpenVPN Tunnel Provider/OpenVPNAdapter.mm b/OpenVPN Tunnel Provider/OpenVPNAdapter.mm index fc439a0..6800c34 100644 --- a/OpenVPN Tunnel Provider/OpenVPNAdapter.mm +++ b/OpenVPN Tunnel Provider/OpenVPNAdapter.mm @@ -17,6 +17,7 @@ #import "OpenVPNError.h" #import "OpenVPNEvent.h" #import "OpenVPNClient.h" +#import "TUNConfiguration.h" #import "OpenVPNAdapter.h" #import "OpenVPNAdapter+Client.h" @@ -32,6 +33,8 @@ NSString * const OpenVPNClientErrorEventKey = @"OpenVPNClientErrorEventKey"; @property OpenVPNClient *vpnClient; +@property (strong, nonatomic) TUNConfiguration *tunConfiguration; + @property CFSocketRef tunSocket; @property CFSocketRef vpnSocket; @@ -39,7 +42,6 @@ NSString * const OpenVPNClientErrorEventKey = @"OpenVPNClientErrorEventKey"; @end - @implementation OpenVPNAdapter (Client) #pragma mark Sockets Configuration @@ -82,6 +84,91 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData return YES; } +#pragma mark TUN Configuration + +- (BOOL)setRemoteAddress:(NSString *)address { + NSAssert(self.tunConfiguration != nil, @"TUN configuration should be initialized"); + + if (address == nil) { + return NO; + } + + self.tunConfiguration.remoteAddress = address; + + return YES; +} + +- (BOOL)addLocalAddress:(NSString *)address subnet:(NSString *)subnet gateway:(NSString *)gateway { + NSAssert(self.tunConfiguration != nil, @"TUN configuration should be initialized"); + + if (address == nil || subnet == nil) { + return NO; + } + + [self.tunConfiguration.localAddresses addObject:address]; + [self.tunConfiguration.subnets addObject:subnet]; + + return YES; +} + +- (BOOL)addRoute:(NSString *)route subnet:(NSString *)subnet { + NSAssert(self.tunConfiguration != nil, @"TUN configuration should be initialized"); + + if (route == nil || subnet == nil) { + return NO; + } + + NEIPv4Route *includedRoute = [[NEIPv4Route alloc] initWithDestinationAddress:route subnetMask:subnet]; + [self.tunConfiguration.includedRoutes addObject:includedRoute]; + + return YES; +} + +- (BOOL)excludeRoute:(NSString *)route subnet:(NSString *)subnet { + NSAssert(self.tunConfiguration != nil, @"TUN configuration should be initialized"); + + if (route == nil || subnet == nil) { + return NO; + } + + NEIPv4Route *excludedRoute = [[NEIPv4Route alloc] initWithDestinationAddress:route subnetMask:subnet]; + [self.tunConfiguration.excludedRoutes addObject:excludedRoute]; + + return YES; +} + +- (BOOL)addDNSAddress:(NSString *)address { + NSAssert(self.tunConfiguration != nil, @"TUN configuration should be initialized"); + + if (address == nil) { + return NO; + } + + [self.tunConfiguration.dnsAddresses addObject:address]; + + return YES; +} + +- (BOOL)addSearchDomain:(NSString *)domain { + NSAssert(self.tunConfiguration != nil, @"TUN configuration should be initialized"); + + if (domain == nil) { + return NO; + } + + [self.tunConfiguration.searchDomains addObject:domain]; + + return YES; +} + +- (BOOL)setMTU:(NSInteger)mtu { + NSAssert(self.tunConfiguration != nil, @"TUN configuration should be initialized"); + + self.tunConfiguration.mtu = @(mtu); + + return YES; +} + #pragma mark Event and Log Handlers - (void)handleEvent:(const ClientAPI::Event *)event { @@ -157,7 +244,6 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData @end - @implementation OpenVPNAdapter (Provider) #pragma mark Client Configuration @@ -205,11 +291,13 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData #pragma mark Connection Control - (void)connect { - dispatch_queue_t connectQueue = dispatch_queue_create("me.ss-abramchuk.openvpn-client.tunnel-provider.connection", NULL); + // TODO: Describe why we use async invocation here + dispatch_queue_t connectQueue = dispatch_queue_create("me.ss-abramchuk.openvpn-ios-client.tunnel-provider.connection", NULL); dispatch_async(connectQueue, ^{ + self.tunConfiguration = [TUNConfiguration new]; + OpenVPNClient::init_process(); + try { - OpenVPNClient::init_process(); - ClientAPI::Status status = self.vpnClient->connect(); if (status.error) { NSError *error = [NSError errorWithDomain:OpenVPNClientErrorDomain @@ -219,8 +307,6 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData OpenVPNClientErrorEventKey: @(OpenVPNEventConnectionFailed) }]; [self.delegate handleError:error]; } - - OpenVPNClient::uninit_process(); } catch(const std::exception& e) { NSError *error = [NSError errorWithDomain:OpenVPNClientErrorDomain code:OpenVPNErrorClientFailure @@ -229,6 +315,9 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData OpenVPNClientErrorEventKey: @(OpenVPNEventConnectionFailed) }]; [self.delegate handleError:error]; } + + OpenVPNClient::uninit_process(); + self.tunConfiguration = nil; }); } @@ -238,7 +327,6 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData @end - @implementation OpenVPNAdapter - (void)dealloc {