Skip to content

Commit

Permalink
Merge pull request #606 from Chilledheart/ios_add_packet_tunnel_glue_…
Browse files Browse the repository at this point in the history
…code

Ios add packet tunnel glue code
  • Loading branch information
Chilledheart committed Dec 31, 2023
2 parents 1e516f1 + 9266299 commit f487e95
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 3 deletions.
59 changes: 56 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4094,6 +4094,7 @@ if (GUI)
MACOSX_BUNDLE_BUNDLE_NAME ${PACKAGE_NAME}
MACOSX_BUNDLE_INFO_PLIST ${APP_MACOSX_BUNDLE_INFO}
XCODE_GENERATE_SCHEME "TRUE"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "it.gui.ios.yass"
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
Expand All @@ -4108,14 +4109,66 @@ if (GUI)
set_target_properties(${APP_NAME} PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${XCODE_CODESIGN_IDENTITY}"
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${XCODE_DEPLOYMENT_TEAM}"
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Auto")
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Automatic")
endif()
# Workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/15183
# Apps must have install step enabled
set_target_properties(${APP_NAME} PROPERTIES
XCODE_ATTRIBUTE_SKIP_INSTALL NO
XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)"
)

# =======================
# PacketTunnel extensions
# =======================
find_library(NetworkExtension_LIBRARY NetworkExtension REQUIRED)

set(PLUGIN_SRC
src/ios/tun2proxy.h
src/ios/tun2proxy.mm
src/ios/extensions/PacketTunnelProvider.h
src/ios/extensions/PacketTunnelProvider.mm
src/ios/extensions/PacketTunnel.entitlements
)

add_executable(PacketTunnel MACOSX_BUNDLE ${PLUGIN_SRC})

target_include_directories(PacketTunnel PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/ios/extensions)
target_compile_options(PacketTunnel PRIVATE -fapplication-extension -fmodules -gmodules -fobjc-arc -fobjc-weak)
target_link_libraries(PacketTunnel PRIVATE ${NetworkExtension_LIBRARY})
set_target_properties(PacketTunnel PROPERTIES LINK_OPTIONS -fapplication-extension -e _NSExtensionMain -fobjc-arc -fobjc-link-runtime)

set_target_properties(PacketTunnel PROPERTIES
OUTPUT_NAME "PacketTunnel"
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/ios/extensions/Info.plist
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
XCODE_GENERATE_SCHEME "TRUE"
MACOSX_BUNDLE_GUI_IDENTIFIER "it.gui.ios.yass.PacketTunnel"
XCODE_ATTRIBUTE_PRODUCT_NAME "PacketTunnel"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "it.gui.ios.yass.PacketTunnel"
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES"
XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11"
XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER ""
)

if ((NOT XCODE_CODESIGN_IDENTITY STREQUAL "-") OR XCODE_DEPLOYMENT_TEAM)
set_target_properties(PacketTunnel PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/src/ios/extensions/PacketTunnel.entitlements
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${XCODE_CODESIGN_IDENTITY}"
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${XCODE_DEPLOYMENT_TEAM}"
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Automatic")
endif()

# Workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/15183
# Apps must have install step enabled
set_target_properties(PacketTunnel PROPERTIES
XCODE_ATTRIBUTE_SKIP_INSTALL NO
XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)"
)
endif()

if (NOT CMAKE_SKIP_INSTALL_RULES)
Expand Down Expand Up @@ -4210,7 +4263,7 @@ if (BUILD_TESTS)
set_target_properties(yass_test PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${XCODE_CODESIGN_IDENTITY}"
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${XCODE_DEPLOYMENT_TEAM}"
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Auto")
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Automatic")
endif()
else()
add_executable(yass_test ${yass_test_SOURCE})
Expand Down Expand Up @@ -4328,7 +4381,7 @@ if (BUILD_BENCHMARKS)
set_target_properties(yass_benchmark PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${XCODE_CODESIGN_IDENTITY}"
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${XCODE_DEPLOYMENT_TEAM}"
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Auto")
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Automatic")
endif()
else()
add_executable(yass_benchmark
Expand Down
13 changes: 13 additions & 0 deletions src/ios/extensions/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.networkextension.packet-tunnel</string>
<key>NSExtensionPrincipalClass</key>
<string>PacketTunnelProvider</string>
</dict>
</dict>
</plist>
10 changes: 10 additions & 0 deletions src/ios/extensions/PacketTunnel.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.it.gui.ios.yass</string>
</array>
</dict>
</plist>
8 changes: 8 additions & 0 deletions src/ios/extensions/PacketTunnelProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Chilledheart */

#import <NetworkExtension/NetworkExtension.h>

@interface PacketTunnelProvider : NEPacketTunnelProvider

@end
30 changes: 30 additions & 0 deletions src/ios/extensions/PacketTunnelProvider.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Chilledheart */

#import "PacketTunnelProvider.h"

@implementation PacketTunnelProvider

- (void)startTunnelWithOptions:(NSDictionary *)options completionHandler:(void (^)(NSError *))completionHandler {
// Add code here to start the process of connecting the tunnel.
}

- (void)stopTunnelWithReason:(NEProviderStopReason)reason completionHandler:(void (^)(void))completionHandler {
// Add code here to start the process of stopping the tunnel.
completionHandler();
}

- (void)handleAppMessage:(NSData *)messageData completionHandler:(void (^)(NSData *))completionHandler {
// Add code here to handle the message.
}

- (void)sleepWithCompletionHandler:(void (^)(void))completionHandler {
// Add code here to get ready to sleep.
completionHandler();
}

- (void)wake {
// Add code here to wake up.
}

@end
15 changes: 15 additions & 0 deletions src/ios/tun2proxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Chilledheart */
#ifndef YASS_IOS_TUN2PROXY
#define YASS_IOS_TUN2PROXY

#import <Foundation/Foundation.h>

@class NEPacketTunnelFlow;
@class NEPacket;

void Tun2Proxy_Init(NEPacketTunnelFlow *flow);
void Tun2Proxy_ForwardReadPackets(NSArray<NEPacket *> *packets);
void Tun2Proxy_Destroy();

#endif // YASS_IOS_TUN2PROXY
96 changes: 96 additions & 0 deletions src/ios/tun2proxy.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Chilledheart */
#include "ios/tun2proxy.h"

#import <NetworkExtension/NetworkExtension.h>

struct InitContent {
__weak NEPacketTunnelFlow *packetFlow;
};

struct ReadPacketContent {
NSArray<NEPacket *> *packets;
};

static size_t GetPacketCount(void *content, void* packets) {
NSArray<NEPacket *> *array = reinterpret_cast<ReadPacketContent*>(packets)->packets;
return [array count];
}

static const void* GetPacketDataAtIndex(void *content, void* packets, int index) {
NSArray<NEPacket *> *array = reinterpret_cast<ReadPacketContent*>(packets)->packets;
NEPacket *packet = array[index];
uint32_t prefix = CFSwapInt32HostToBig((uint32_t)packet.protocolFamily);
// Prepend data with network protocol. It should be done because on tun2proxy
// uses uint32_t prefixes containing network protocol.
NSMutableData *data = [[NSMutableData alloc] initWithCapacity:sizeof(prefix) + packet.data.length];
[data appendBytes:&prefix length:sizeof(prefix)];
[data appendData:packet.data];

return data.bytes;
}

static size_t GetPacketSizeAtIndex(void *content, void* packets, int index) {
NSArray<NEPacket *> *array = reinterpret_cast<ReadPacketContent*>(packets)->packets;
return sizeof(uint32_t) + [[array[index] data] length];
}

static NEPacket *packetFromData(NSData *data) {
// Get network protocol from prefix
NSUInteger prefixSize = sizeof(uint32_t);

if (data.length < prefixSize) {
return nil;
}

uint32_t protocol = PF_UNSPEC;
[data getBytes:&protocol length:prefixSize];
protocol = CFSwapInt32BigToHost(protocol);

NSRange range = NSMakeRange(prefixSize, data.length - prefixSize);
NSData *packetData = [data subdataWithRange:range];

return [[NEPacket alloc] initWithData:packetData protocolFamily:protocol];
}

static void WritePackets(void* content, void** packets, size_t* packetLengths,
int packetsCount) {
InitContent *c = reinterpret_cast<InitContent*>(content);
NEPacketTunnelFlow* packetFlow = c->packetFlow;;
NSMutableArray *packetsArray = [NSMutableArray array];
for (int i = 0; i < packetsCount; ++i) {
NSData *data = [NSData dataWithBytes:packets[i] length:packetLengths[i]];
NEPacket *packet = packetFromData(data);
[packetsArray addObject:packet];
}
[packetFlow writePacketObjects:packetsArray];
}

extern "C"
void tun2proxy_init(void* content, decltype(WritePackets));

extern "C"
void tun2proxy_read_packets(void* packets, decltype(GetPacketCount),
decltype(GetPacketDataAtIndex),
decltype(GetPacketSizeAtIndex));

extern "C"
void* tun2proxy_destroy();

void Tun2Proxy_Init(NEPacketTunnelFlow *packetFlow) {
InitContent *c = new InitContent;
c->packetFlow = packetFlow;
tun2proxy_init(c, WritePackets);
}

void Tun2Proxy_ForwardReadPackets(NSArray<NEPacket *> *packets) {
ReadPacketContent p;
p.packets = packets;
tun2proxy_read_packets(&p, GetPacketCount, GetPacketDataAtIndex,
GetPacketSizeAtIndex);
}

void Tun2Proxy_Destroy() {
InitContent *c = reinterpret_cast<InitContent*>(tun2proxy_destroy());
delete c;
}

0 comments on commit f487e95

Please sign in to comment.