From b0756eae4cbd8c629396f7c3dcea2077ddfdb255 Mon Sep 17 00:00:00 2001 From: Sergey Abramchuk Date: Thu, 22 Jun 2017 20:02:52 +0300 Subject: [PATCH 1/4] Don't add protocol prefix if a target other than iPhone --- OpenVPN Adapter/OpenVPNAdapter.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenVPN Adapter/OpenVPNAdapter.mm b/OpenVPN Adapter/OpenVPNAdapter.mm index c2f77c1..c5d88e4 100644 --- a/OpenVPN Adapter/OpenVPNAdapter.mm +++ b/OpenVPN Adapter/OpenVPNAdapter.mm @@ -560,12 +560,16 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData - (void)readTUNPackets { [self.packetFlow readPacketsWithCompletionHandler:^(NSArray * _Nonnull packets, NSArray * _Nonnull protocols) { [packets enumerateObjectsUsingBlock:^(NSData * data, NSUInteger idx, BOOL * stop) { - // Prepend data with network protocol. It should be done because OpenVPN uses uint32_t prefixes containing network protocol. + NSMutableData *packet = [NSMutableData new]; + +#if TARGET_OS_IPHONE + // Prepend data with network protocol. It should be done because OpenVPN on iOS uses uint32_t prefixes containing network protocol. NSNumber *protocol = protocols[idx]; uint32_t prefix = CFSwapInt32HostToBig((uint32_t)[protocol unsignedIntegerValue]); - NSMutableData *packet = [NSMutableData new]; [packet appendBytes:&prefix length:sizeof(prefix)]; +#endif + [packet appendData:data]; // Send data to the VPN server From 76413feea75b341909f48d1cb9de10426418849d Mon Sep 17 00:00:00 2001 From: Sergey Abramchuk Date: Thu, 22 Jun 2017 20:50:23 +0300 Subject: [PATCH 2/4] Get protocol version from header if a target is macOS --- OpenVPN Adapter/OpenVPNAdapter.mm | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/OpenVPN Adapter/OpenVPNAdapter.mm b/OpenVPN Adapter/OpenVPNAdapter.mm index c5d88e4..def79d1 100644 --- a/OpenVPN Adapter/OpenVPNAdapter.mm +++ b/OpenVPN Adapter/OpenVPNAdapter.mm @@ -14,6 +14,7 @@ #import +#import #import #import "OpenVPNTunnelSettings.h" @@ -583,7 +584,8 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData #pragma mark OpenVPN -> TUN - (void)readVPNData:(NSData *)data { - // Get network protocol from data +#if TARGET_OS_IPHONE + // Get network protocol from prefix NSUInteger prefixSize = sizeof(uint32_t); if (data.length < prefixSize) { @@ -593,11 +595,20 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData uint32_t protocol = UINT32_MAX; [data getBytes:&protocol length:prefixSize]; - + protocol = CFSwapInt32BigToHost(protocol); - // Send the packet to the TUN interface NSData *packet = [data subdataWithRange:NSMakeRange(prefixSize, data.length - prefixSize)]; +#elif TARGET_OS_MAC + // Get network protocol from header + uint8_t header = 0; + [data getBytes:&header length:1]; + + uint32_t protocol = openvpn::IPHeader::version(header); + NSData *packet = data; +#endif + + // Send the packet to the TUN interface if (![self.packetFlow writePackets:@[packet] withProtocols:@[@(protocol)]]) { NSLog(@"Failed to send OpenVPN packet to the TUN interface"); } From 6d2de5cb4e6e6a6ad9fadbabbd2ddf9d1b1ec34c Mon Sep 17 00:00:00 2001 From: Sergey Abramchuk Date: Thu, 22 Jun 2017 20:55:34 +0300 Subject: [PATCH 3/4] Fix incorrect macro --- OpenVPN Adapter/OpenVPNAdapter.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenVPN Adapter/OpenVPNAdapter.mm b/OpenVPN Adapter/OpenVPNAdapter.mm index def79d1..eba038d 100644 --- a/OpenVPN Adapter/OpenVPNAdapter.mm +++ b/OpenVPN Adapter/OpenVPNAdapter.mm @@ -599,7 +599,7 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData protocol = CFSwapInt32BigToHost(protocol); NSData *packet = [data subdataWithRange:NSMakeRange(prefixSize, data.length - prefixSize)]; -#elif TARGET_OS_MAC +#else // Get network protocol from header uint8_t header = 0; [data getBytes:&header length:1]; From 0714a6d0f6de7353983ce07019681ac7ed9d5d42 Mon Sep 17 00:00:00 2001 From: Sergey Abramchuk Date: Thu, 22 Jun 2017 21:19:19 +0300 Subject: [PATCH 4/4] Return protocol family depending on version --- OpenVPN Adapter/OpenVPNAdapter.mm | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/OpenVPN Adapter/OpenVPNAdapter.mm b/OpenVPN Adapter/OpenVPNAdapter.mm index eba038d..f208fd8 100644 --- a/OpenVPN Adapter/OpenVPNAdapter.mm +++ b/OpenVPN Adapter/OpenVPNAdapter.mm @@ -593,10 +593,11 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData return; } - uint32_t protocol = UINT32_MAX; - [data getBytes:&protocol length:prefixSize]; - - protocol = CFSwapInt32BigToHost(protocol); + uint32_t version = UINT32_MAX; + [data getBytes:&version length:prefixSize]; + version = CFSwapInt32BigToHost(version); + + uint8_t protocol = [self getProtocolFamily:version]; NSData *packet = [data subdataWithRange:NSMakeRange(prefixSize, data.length - prefixSize)]; #else @@ -604,7 +605,10 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData uint8_t header = 0; [data getBytes:&header length:1]; - uint32_t protocol = openvpn::IPHeader::version(header); + uint32_t version = openvpn::IPHeader::version(header); + + uint8_t protocol = [self getProtocolFamily:version]; + NSData *packet = data; #endif @@ -684,6 +688,14 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData return [NSString stringWithUTF8String:subnet.c_str()]; } +- (uint8_t)getProtocolFamily:(uint32_t)version { + switch (version) { + case 4: return PF_INET; + case 6: return PF_INET6; + default: return PF_UNSPEC; + } +} + - (void)performAsyncBlock:(void (^)())block { dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_async(mainQueue, block);