├── .github └── workflows │ ├── build.yml │ ├── compatibility.yml │ ├── lint.yml │ └── release.yml ├── .gitignore ├── HevSocks5Tunnel.xcframework ├── .DS_Store ├── Info.plist ├── ios-arm64 │ ├── Headers │ │ ├── hev-main.h │ │ └── module.modulemap │ └── libhev-socks5-tunnel.a ├── ios-arm64_x86_64-simulator │ ├── Headers │ │ ├── hev-main.h │ │ └── module.modulemap │ └── libhev-socks5-tunnel.a ├── macos-arm64_x86_64 │ ├── Headers │ │ ├── hev-main.h │ │ └── module.modulemap │ └── libhev-socks5-tunnel.a ├── tvos-arm64 │ ├── Headers │ │ ├── hev-main.h │ │ └── module.modulemap │ └── libhev-socks5-tunnel.a └── tvos-arm64_x86_64-simulator │ ├── Headers │ ├── hev-main.h │ └── module.modulemap │ └── libhev-socks5-tunnel.a ├── PacketTunnelProvider copy-Info.plist ├── PacketTunnelProvider ├── Info.plist ├── PacketTunnelProvider.entitlements └── PacketTunnelProvider.swift ├── README.md ├── VPNclientEngine.podspec ├── VPNclientEngineIOS ├── VPNclientEngineIOS.docc │ └── VPNclientEngineIOS.md └── VPNclientEngineIOS.h ├── VPNclientTunnel.podspec ├── cntrlr.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ ├── anton.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── ginter.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ └── xcschemes │ │ ├── PackageTunnelProvider.xcscheme │ │ └── cntrlr.xcscheme └── xcuserdata │ ├── anton.xcuserdatad │ └── xcschemes │ │ └── xcschememanagement.plist │ └── ginter.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist └── cntrlr ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── ContentView.swift ├── Preview Content └── Preview Assets.xcassets │ └── Contents.json ├── VPNManager.swift ├── cntrlr.entitlements └── cntrlrApp.swift /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | push: 5 | branches: [ main, develop ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: macos-latest 12 | 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Set up Xcode 18 | uses: maxim-lobanov/setup-xcode@v1 19 | with: 20 | xcode-version: latest-stable 21 | 22 | - name: Cache CocoaPods 23 | uses: actions/cache@v3 24 | with: 25 | path: ~/Library/Caches/CocoaPods 26 | key: ${{ runner.os }}-cocoapods-${{ hashFiles('**/Podfile.lock') }} 27 | restore-keys: | 28 | ${{ runner.os }}-cocoapods- 29 | 30 | - name: Install CocoaPods 31 | run: pod install --repo-update 32 | 33 | - name: Build project 34 | run: xcodebuild build -workspace VPNclientEngineIOS.xcworkspace -scheme VPNclientEngineIOS -destination 'generic/platform=iOS' CODE_SIGNING_ALLOWED=NO 35 | 36 | - name: Run tests 37 | run: xcodebuild test -workspace VPNclientEngineIOS.xcworkspace -scheme VPNclientEngineIOS -destination 'platform=iOS Simulator,name=iPhone 15' CODE_SIGNING_ALLOWED=NO 38 | -------------------------------------------------------------------------------- /.github/workflows/compatibility.yml: -------------------------------------------------------------------------------- 1 | name: Compatibility Check 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * 0' # Weekly 6 | workflow_dispatch: 7 | 8 | jobs: 9 | check: 10 | runs-on: macos-latest 11 | strategy: 12 | matrix: 13 | xcode: ['14.3', '15.0'] 14 | name: Xcode ${{ matrix.xcode }} 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Setup Xcode ${{ matrix.xcode }} 20 | uses: maxim-lobanov/setup-xcode@v1 21 | with: 22 | xcode-version: ${{ matrix.xcode }} 23 | 24 | - name: Build 25 | run: | 26 | pod install 27 | xcodebuild build -workspace VPNclientEngineIOS.xcworkspace -scheme VPNclientEngineIOS -destination 'generic/platform=iOS' 28 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | swiftlint: 7 | runs-on: macos-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | 12 | - name: Install SwiftLint 13 | run: brew install swiftlint 14 | 15 | - name: Run SwiftLint 16 | run: swiftlint --strict -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | tags: 7 | - 'v*' 8 | 9 | jobs: 10 | release: 11 | runs-on: macos-latest 12 | 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Setup Xcode 18 | uses: maxim-lobanov/setup-xcode@v1 19 | with: 20 | xcode-version: latest-stable 21 | 22 | - name: Install CocoaPods 23 | run: pod install --repo-update 24 | 25 | - name: Create XCFramework 26 | run: | 27 | xcodebuild archive \ 28 | -workspace VPNclientEngine.xcworkspace \ 29 | -scheme VPNclientEngine \ 30 | -destination "generic/platform=iOS" \ 31 | -archivePath "build/VPNclientEngineIOS" \ 32 | SKIP_INSTALL=NO \ 33 | BUILD_LIBRARY_FOR_DISTRIBUTION=YES 34 | 35 | xcodebuild archive \ 36 | -workspace VPNclientEngine.xcworkspace \ 37 | -scheme VPNclientEngine \ 38 | -destination "generic/platform=iOS Simulator" \ 39 | -archivePath "build/VPNclientEngine-Simulator" \ 40 | SKIP_INSTALL=NO \ 41 | BUILD_LIBRARY_FOR_DISTRIBUTION=YES 42 | 43 | xcodebuild -create-xcframework \ 44 | -framework "build/VPNclientEngineIOS.xcarchive/Products/Library/Frameworks/VPNclientEngineIOS.framework" \ 45 | -framework "build/VPNclientEngineSimulator.xcarchive/Products/Library/Frameworks/VPNclientEngineIOS.framework" \ 46 | -output "VPNclientEngineIOS.xcframework" 47 | 48 | - name: Zip XCFramework 49 | run: zip -r VPNclientEngineIOS.xcframework.zip VPNclientEngine.xcframework 50 | 51 | - name: Create GitHub Release 52 | uses: softprops/action-gh-release@v1 53 | with: 54 | files: VPNclientEngine.xcframework.zip 55 | env: 56 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/HevSocks5Tunnel.xcframework/.DS_Store -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AvailableLibraries 6 | 7 | 8 | BinaryPath 9 | libhev-socks5-tunnel.a 10 | HeadersPath 11 | Headers 12 | LibraryIdentifier 13 | tvos-arm64 14 | LibraryPath 15 | libhev-socks5-tunnel.a 16 | SupportedArchitectures 17 | 18 | arm64 19 | 20 | SupportedPlatform 21 | tvos 22 | 23 | 24 | BinaryPath 25 | libhev-socks5-tunnel.a 26 | HeadersPath 27 | Headers 28 | LibraryIdentifier 29 | macos-arm64_x86_64 30 | LibraryPath 31 | libhev-socks5-tunnel.a 32 | SupportedArchitectures 33 | 34 | arm64 35 | x86_64 36 | 37 | SupportedPlatform 38 | macos 39 | 40 | 41 | BinaryPath 42 | libhev-socks5-tunnel.a 43 | HeadersPath 44 | Headers 45 | LibraryIdentifier 46 | tvos-arm64_x86_64-simulator 47 | LibraryPath 48 | libhev-socks5-tunnel.a 49 | SupportedArchitectures 50 | 51 | arm64 52 | x86_64 53 | 54 | SupportedPlatform 55 | tvos 56 | SupportedPlatformVariant 57 | simulator 58 | 59 | 60 | BinaryPath 61 | libhev-socks5-tunnel.a 62 | HeadersPath 63 | Headers 64 | LibraryIdentifier 65 | ios-arm64 66 | LibraryPath 67 | libhev-socks5-tunnel.a 68 | SupportedArchitectures 69 | 70 | arm64 71 | 72 | SupportedPlatform 73 | ios 74 | 75 | 76 | BinaryPath 77 | libhev-socks5-tunnel.a 78 | HeadersPath 79 | Headers 80 | LibraryIdentifier 81 | ios-arm64_x86_64-simulator 82 | LibraryPath 83 | libhev-socks5-tunnel.a 84 | SupportedArchitectures 85 | 86 | arm64 87 | x86_64 88 | 89 | SupportedPlatform 90 | ios 91 | SupportedPlatformVariant 92 | simulator 93 | 94 | 95 | CFBundlePackageType 96 | XFWK 97 | XCFrameworkFormatVersion 98 | 1.0 99 | 100 | 101 | -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/ios-arm64/Headers/hev-main.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-main.h 4 | Author : hev 5 | Copyright : Copyright (c) 2019 - 2023 hev 6 | Description : Main 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_MAIN_H__ 11 | #define __HEV_MAIN_H__ 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /** 20 | * hev_socks5_tunnel_main: 21 | * @config_path: config file path 22 | * @tun_fd: tunnel file descriptor 23 | * 24 | * Start and run the socks5 tunnel, this function will blocks until the 25 | * hev_socks5_tunnel_quit is called or an error occurs. 26 | * 27 | * Returns: returns zero on successful, otherwise returns -1. 28 | * 29 | * Since: 2.4.6 30 | */ 31 | int hev_socks5_tunnel_main (const char *config_path, int tun_fd); 32 | 33 | /** 34 | * hev_socks5_tunnel_main_from_file: 35 | * @config_path: config file path 36 | * @tun_fd: tunnel file descriptor 37 | * 38 | * Start and run the socks5 tunnel, this function will blocks until the 39 | * hev_socks5_tunnel_quit is called or an error occurs. 40 | * 41 | * Returns: returns zero on successful, otherwise returns -1. 42 | * 43 | * Since: 2.6.7 44 | */ 45 | int hev_socks5_tunnel_main_from_file (const char *config_path, int tun_fd); 46 | 47 | /** 48 | * hev_socks5_tunnel_main_from_str: 49 | * @config_str: string config 50 | * @config_len: the byte length of string config 51 | * @tun_fd: tunnel file descriptor 52 | * 53 | * Start and run the socks5 tunnel, this function will blocks until the 54 | * hev_socks5_tunnel_quit is called or an error occurs. 55 | * 56 | * Returns: returns zero on successful, otherwise returns -1. 57 | * 58 | * Since: 2.6.7 59 | */ 60 | int hev_socks5_tunnel_main_from_str (const unsigned char *config_str, 61 | unsigned int config_len, int tun_fd); 62 | 63 | /** 64 | * hev_socks5_tunnel_quit: 65 | * 66 | * Stop the socks5 tunnel. 67 | * 68 | * Since: 2.4.6 69 | */ 70 | void hev_socks5_tunnel_quit (void); 71 | 72 | /** 73 | * hev_socks5_tunnel_stats: 74 | * @tx_packets (out): transmitted packets 75 | * @tx_bytes (out): transmitted bytes 76 | * @rx_packets (out): received packets 77 | * @rx_bytes (out): received bytes 78 | * 79 | * Retrieve tunnel interface traffic statistics. 80 | * 81 | * Since: 2.6.5 82 | */ 83 | void hev_socks5_tunnel_stats (size_t *tx_packets, size_t *tx_bytes, 84 | size_t *rx_packets, size_t *rx_bytes); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* __HEV_MAIN_H__ */ 91 | -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/ios-arm64/Headers/module.modulemap: -------------------------------------------------------------------------------- 1 | module HevSocks5Tunnel { 2 | umbrella header "hev-main.h" 3 | export * 4 | } -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/ios-arm64/libhev-socks5-tunnel.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/HevSocks5Tunnel.xcframework/ios-arm64/libhev-socks5-tunnel.a -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/ios-arm64_x86_64-simulator/Headers/hev-main.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-main.h 4 | Author : hev 5 | Copyright : Copyright (c) 2019 - 2023 hev 6 | Description : Main 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_MAIN_H__ 11 | #define __HEV_MAIN_H__ 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /** 20 | * hev_socks5_tunnel_main: 21 | * @config_path: config file path 22 | * @tun_fd: tunnel file descriptor 23 | * 24 | * Start and run the socks5 tunnel, this function will blocks until the 25 | * hev_socks5_tunnel_quit is called or an error occurs. 26 | * 27 | * Returns: returns zero on successful, otherwise returns -1. 28 | * 29 | * Since: 2.4.6 30 | */ 31 | int hev_socks5_tunnel_main (const char *config_path, int tun_fd); 32 | 33 | /** 34 | * hev_socks5_tunnel_main_from_file: 35 | * @config_path: config file path 36 | * @tun_fd: tunnel file descriptor 37 | * 38 | * Start and run the socks5 tunnel, this function will blocks until the 39 | * hev_socks5_tunnel_quit is called or an error occurs. 40 | * 41 | * Returns: returns zero on successful, otherwise returns -1. 42 | * 43 | * Since: 2.6.7 44 | */ 45 | int hev_socks5_tunnel_main_from_file (const char *config_path, int tun_fd); 46 | 47 | /** 48 | * hev_socks5_tunnel_main_from_str: 49 | * @config_str: string config 50 | * @config_len: the byte length of string config 51 | * @tun_fd: tunnel file descriptor 52 | * 53 | * Start and run the socks5 tunnel, this function will blocks until the 54 | * hev_socks5_tunnel_quit is called or an error occurs. 55 | * 56 | * Returns: returns zero on successful, otherwise returns -1. 57 | * 58 | * Since: 2.6.7 59 | */ 60 | int hev_socks5_tunnel_main_from_str (const unsigned char *config_str, 61 | unsigned int config_len, int tun_fd); 62 | 63 | /** 64 | * hev_socks5_tunnel_quit: 65 | * 66 | * Stop the socks5 tunnel. 67 | * 68 | * Since: 2.4.6 69 | */ 70 | void hev_socks5_tunnel_quit (void); 71 | 72 | /** 73 | * hev_socks5_tunnel_stats: 74 | * @tx_packets (out): transmitted packets 75 | * @tx_bytes (out): transmitted bytes 76 | * @rx_packets (out): received packets 77 | * @rx_bytes (out): received bytes 78 | * 79 | * Retrieve tunnel interface traffic statistics. 80 | * 81 | * Since: 2.6.5 82 | */ 83 | void hev_socks5_tunnel_stats (size_t *tx_packets, size_t *tx_bytes, 84 | size_t *rx_packets, size_t *rx_bytes); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* __HEV_MAIN_H__ */ 91 | -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/ios-arm64_x86_64-simulator/Headers/module.modulemap: -------------------------------------------------------------------------------- 1 | module HevSocks5Tunnel { 2 | umbrella header "hev-main.h" 3 | export * 4 | } -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/ios-arm64_x86_64-simulator/libhev-socks5-tunnel.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/HevSocks5Tunnel.xcframework/ios-arm64_x86_64-simulator/libhev-socks5-tunnel.a -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers/hev-main.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-main.h 4 | Author : hev 5 | Copyright : Copyright (c) 2019 - 2023 hev 6 | Description : Main 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_MAIN_H__ 11 | #define __HEV_MAIN_H__ 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /** 20 | * hev_socks5_tunnel_main: 21 | * @config_path: config file path 22 | * @tun_fd: tunnel file descriptor 23 | * 24 | * Start and run the socks5 tunnel, this function will blocks until the 25 | * hev_socks5_tunnel_quit is called or an error occurs. 26 | * 27 | * Returns: returns zero on successful, otherwise returns -1. 28 | * 29 | * Since: 2.4.6 30 | */ 31 | int hev_socks5_tunnel_main (const char *config_path, int tun_fd); 32 | 33 | /** 34 | * hev_socks5_tunnel_main_from_file: 35 | * @config_path: config file path 36 | * @tun_fd: tunnel file descriptor 37 | * 38 | * Start and run the socks5 tunnel, this function will blocks until the 39 | * hev_socks5_tunnel_quit is called or an error occurs. 40 | * 41 | * Returns: returns zero on successful, otherwise returns -1. 42 | * 43 | * Since: 2.6.7 44 | */ 45 | int hev_socks5_tunnel_main_from_file (const char *config_path, int tun_fd); 46 | 47 | /** 48 | * hev_socks5_tunnel_main_from_str: 49 | * @config_str: string config 50 | * @config_len: the byte length of string config 51 | * @tun_fd: tunnel file descriptor 52 | * 53 | * Start and run the socks5 tunnel, this function will blocks until the 54 | * hev_socks5_tunnel_quit is called or an error occurs. 55 | * 56 | * Returns: returns zero on successful, otherwise returns -1. 57 | * 58 | * Since: 2.6.7 59 | */ 60 | int hev_socks5_tunnel_main_from_str (const unsigned char *config_str, 61 | unsigned int config_len, int tun_fd); 62 | 63 | /** 64 | * hev_socks5_tunnel_quit: 65 | * 66 | * Stop the socks5 tunnel. 67 | * 68 | * Since: 2.4.6 69 | */ 70 | void hev_socks5_tunnel_quit (void); 71 | 72 | /** 73 | * hev_socks5_tunnel_stats: 74 | * @tx_packets (out): transmitted packets 75 | * @tx_bytes (out): transmitted bytes 76 | * @rx_packets (out): received packets 77 | * @rx_bytes (out): received bytes 78 | * 79 | * Retrieve tunnel interface traffic statistics. 80 | * 81 | * Since: 2.6.5 82 | */ 83 | void hev_socks5_tunnel_stats (size_t *tx_packets, size_t *tx_bytes, 84 | size_t *rx_packets, size_t *rx_bytes); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* __HEV_MAIN_H__ */ 91 | -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers/module.modulemap: -------------------------------------------------------------------------------- 1 | module HevSocks5Tunnel { 2 | umbrella header "hev-main.h" 3 | export * 4 | } -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/tvos-arm64/Headers/hev-main.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-main.h 4 | Author : hev 5 | Copyright : Copyright (c) 2019 - 2023 hev 6 | Description : Main 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_MAIN_H__ 11 | #define __HEV_MAIN_H__ 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /** 20 | * hev_socks5_tunnel_main: 21 | * @config_path: config file path 22 | * @tun_fd: tunnel file descriptor 23 | * 24 | * Start and run the socks5 tunnel, this function will blocks until the 25 | * hev_socks5_tunnel_quit is called or an error occurs. 26 | * 27 | * Returns: returns zero on successful, otherwise returns -1. 28 | * 29 | * Since: 2.4.6 30 | */ 31 | int hev_socks5_tunnel_main (const char *config_path, int tun_fd); 32 | 33 | /** 34 | * hev_socks5_tunnel_main_from_file: 35 | * @config_path: config file path 36 | * @tun_fd: tunnel file descriptor 37 | * 38 | * Start and run the socks5 tunnel, this function will blocks until the 39 | * hev_socks5_tunnel_quit is called or an error occurs. 40 | * 41 | * Returns: returns zero on successful, otherwise returns -1. 42 | * 43 | * Since: 2.6.7 44 | */ 45 | int hev_socks5_tunnel_main_from_file (const char *config_path, int tun_fd); 46 | 47 | /** 48 | * hev_socks5_tunnel_main_from_str: 49 | * @config_str: string config 50 | * @config_len: the byte length of string config 51 | * @tun_fd: tunnel file descriptor 52 | * 53 | * Start and run the socks5 tunnel, this function will blocks until the 54 | * hev_socks5_tunnel_quit is called or an error occurs. 55 | * 56 | * Returns: returns zero on successful, otherwise returns -1. 57 | * 58 | * Since: 2.6.7 59 | */ 60 | int hev_socks5_tunnel_main_from_str (const unsigned char *config_str, 61 | unsigned int config_len, int tun_fd); 62 | 63 | /** 64 | * hev_socks5_tunnel_quit: 65 | * 66 | * Stop the socks5 tunnel. 67 | * 68 | * Since: 2.4.6 69 | */ 70 | void hev_socks5_tunnel_quit (void); 71 | 72 | /** 73 | * hev_socks5_tunnel_stats: 74 | * @tx_packets (out): transmitted packets 75 | * @tx_bytes (out): transmitted bytes 76 | * @rx_packets (out): received packets 77 | * @rx_bytes (out): received bytes 78 | * 79 | * Retrieve tunnel interface traffic statistics. 80 | * 81 | * Since: 2.6.5 82 | */ 83 | void hev_socks5_tunnel_stats (size_t *tx_packets, size_t *tx_bytes, 84 | size_t *rx_packets, size_t *rx_bytes); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* __HEV_MAIN_H__ */ 91 | -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/tvos-arm64/Headers/module.modulemap: -------------------------------------------------------------------------------- 1 | module HevSocks5Tunnel { 2 | umbrella header "hev-main.h" 3 | export * 4 | } -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/tvos-arm64/libhev-socks5-tunnel.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/HevSocks5Tunnel.xcframework/tvos-arm64/libhev-socks5-tunnel.a -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/tvos-arm64_x86_64-simulator/Headers/hev-main.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-main.h 4 | Author : hev 5 | Copyright : Copyright (c) 2019 - 2023 hev 6 | Description : Main 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_MAIN_H__ 11 | #define __HEV_MAIN_H__ 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /** 20 | * hev_socks5_tunnel_main: 21 | * @config_path: config file path 22 | * @tun_fd: tunnel file descriptor 23 | * 24 | * Start and run the socks5 tunnel, this function will blocks until the 25 | * hev_socks5_tunnel_quit is called or an error occurs. 26 | * 27 | * Returns: returns zero on successful, otherwise returns -1. 28 | * 29 | * Since: 2.4.6 30 | */ 31 | int hev_socks5_tunnel_main (const char *config_path, int tun_fd); 32 | 33 | /** 34 | * hev_socks5_tunnel_main_from_file: 35 | * @config_path: config file path 36 | * @tun_fd: tunnel file descriptor 37 | * 38 | * Start and run the socks5 tunnel, this function will blocks until the 39 | * hev_socks5_tunnel_quit is called or an error occurs. 40 | * 41 | * Returns: returns zero on successful, otherwise returns -1. 42 | * 43 | * Since: 2.6.7 44 | */ 45 | int hev_socks5_tunnel_main_from_file (const char *config_path, int tun_fd); 46 | 47 | /** 48 | * hev_socks5_tunnel_main_from_str: 49 | * @config_str: string config 50 | * @config_len: the byte length of string config 51 | * @tun_fd: tunnel file descriptor 52 | * 53 | * Start and run the socks5 tunnel, this function will blocks until the 54 | * hev_socks5_tunnel_quit is called or an error occurs. 55 | * 56 | * Returns: returns zero on successful, otherwise returns -1. 57 | * 58 | * Since: 2.6.7 59 | */ 60 | int hev_socks5_tunnel_main_from_str (const unsigned char *config_str, 61 | unsigned int config_len, int tun_fd); 62 | 63 | /** 64 | * hev_socks5_tunnel_quit: 65 | * 66 | * Stop the socks5 tunnel. 67 | * 68 | * Since: 2.4.6 69 | */ 70 | void hev_socks5_tunnel_quit (void); 71 | 72 | /** 73 | * hev_socks5_tunnel_stats: 74 | * @tx_packets (out): transmitted packets 75 | * @tx_bytes (out): transmitted bytes 76 | * @rx_packets (out): received packets 77 | * @rx_bytes (out): received bytes 78 | * 79 | * Retrieve tunnel interface traffic statistics. 80 | * 81 | * Since: 2.6.5 82 | */ 83 | void hev_socks5_tunnel_stats (size_t *tx_packets, size_t *tx_bytes, 84 | size_t *rx_packets, size_t *rx_bytes); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* __HEV_MAIN_H__ */ 91 | -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/tvos-arm64_x86_64-simulator/Headers/module.modulemap: -------------------------------------------------------------------------------- 1 | module HevSocks5Tunnel { 2 | umbrella header "hev-main.h" 3 | export * 4 | } -------------------------------------------------------------------------------- /HevSocks5Tunnel.xcframework/tvos-arm64_x86_64-simulator/libhev-socks5-tunnel.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/HevSocks5Tunnel.xcframework/tvos-arm64_x86_64-simulator/libhev-socks5-tunnel.a -------------------------------------------------------------------------------- /PacketTunnelProvider copy-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.networkextension.packet-tunnel 9 | NSExtensionPrincipalClass 10 | $(PRODUCT_MODULE_NAME).PacketTunnelProvider 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /PacketTunnelProvider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.networkextension.packet-tunnel 9 | NSExtensionPrincipalClass 10 | $(PRODUCT_MODULE_NAME).PacketTunnelProvider 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /PacketTunnelProvider/PacketTunnelProvider.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | packet-tunnel-provider 8 | 9 | com.apple.security.application-groups 10 | 11 | group.click.vpnclient 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PacketTunnelProvider/PacketTunnelProvider.swift: -------------------------------------------------------------------------------- 1 | import NetworkExtension 2 | import HevSocks5Tunnel 3 | import os.log 4 | 5 | class PacketTunnelProvider: NEPacketTunnelProvider { 6 | private var tunnelRunning = false 7 | 8 | override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { 9 | os_log(.debug, "PacketTunnelProvider: Starting tunnel with options: %@", String(describing: options)) 10 | 11 | guard let protocolConfiguration = protocolConfiguration as? NETunnelProviderProtocol, 12 | let providerConfig = protocolConfiguration.providerConfiguration, 13 | let tunAddr = providerConfig["tunAddr"] as? String, 14 | let tunMask = providerConfig["tunMask"] as? String, 15 | let tunDns = providerConfig["tunDns"] as? String, 16 | let socks5Proxy = providerConfig["socks5Proxy"] as? String else { 17 | os_log(.error, "PacketTunnelProvider: Failed to load provider configuration") 18 | completionHandler(NSError(domain: "PacketTunnelProvider", code: -1, userInfo: [NSLocalizedDescriptionKey: "Missing provider configuration"])) 19 | return 20 | } 21 | 22 | os_log(.debug, "PacketTunnelProvider: Config - tunAddr: %@, tunMask: %@, tunDns: %@, socks5Proxy: %@", tunAddr, tunMask, tunDns, socks5Proxy) 23 | 24 | let proxyComponents = socks5Proxy.components(separatedBy: ":") 25 | guard proxyComponents.count == 2, 26 | let socks5Address = proxyComponents.first, 27 | let socks5Port = UInt16(proxyComponents.last ?? "1080") else { 28 | os_log(.error, "PacketTunnelProvider: Invalid SOCKS5 proxy format: %@", socks5Proxy) 29 | completionHandler(NSError(domain: "PacketTunnelProvider", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid SOCKS5 proxy format"])) 30 | return 31 | } 32 | 33 | let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: socks5Address) 34 | settings.mtu = 1500 35 | 36 | let ipv4Settings = NEIPv4Settings(addresses: [tunAddr], subnetMasks: [tunMask]) 37 | ipv4Settings.includedRoutes = [NEIPv4Route.default()] 38 | settings.ipv4Settings = ipv4Settings 39 | 40 | let dnsSettings = NEDNSSettings(servers: [tunDns]) 41 | settings.dnsSettings = dnsSettings 42 | 43 | os_log(.debug, "PacketTunnelProvider: Applying tunnel network settings...") 44 | setTunnelNetworkSettings(settings) { error in 45 | if let error = error { 46 | os_log(.error, "PacketTunnelProvider: Failed to set tunnel network settings: %@", error.localizedDescription) 47 | completionHandler(error) 48 | return 49 | } 50 | 51 | os_log(.info, "PacketTunnelProvider: Tunnel network settings applied successfully") 52 | 53 | let config = """ 54 | tunnel: 55 | name: tun0 56 | mtu: 8500 57 | socks5: 58 | address: "\(socks5Address)" 59 | port: \(socks5Port) 60 | """ 61 | 62 | os_log(.debug, "PacketTunnelProvider: Starting hev-socks5-tunnel with config: %@", config) 63 | DispatchQueue.global().async { 64 | self.startHevSocks5Tunnel(withConfig: config) 65 | } 66 | 67 | self.monitorTunnelActivity() 68 | 69 | os_log(.debug, "PacketTunnelProvider: Calling completion handler with success") 70 | completionHandler(nil) 71 | } 72 | } 73 | 74 | func startHevSocks5Tunnel(withConfig config: String) { 75 | os_log(.debug, "PacketTunnelProvider: Starting hev-socks5-tunnel...") 76 | 77 | guard let configData = config.data(using: .utf8) else { 78 | os_log(.error, "PacketTunnelProvider: Failed to convert config to UTF-8 data") 79 | return 80 | } 81 | let configLen = UInt32(configData.count) 82 | 83 | 84 | os_log(.debug, "PacketTunnelProvider: Using packetFlow instead of tun_fd") 85 | 86 | 87 | tunnelRunning = true 88 | DispatchQueue.global().async { 89 | 90 | self.handlePackets() 91 | } 92 | } 93 | 94 | func handlePackets() { 95 | let flow = self.packetFlow 96 | /* 97 | guard let flow = self.packetFlow else { 98 | os_log(.error, "PacketTunnelProvider: Packet flow is nil") 99 | tunnelRunning = false 100 | return 101 | } 102 | */ 103 | flow.readPackets { packets, protocols in 104 | if !self.tunnelRunning { 105 | os_log(.info, "PacketTunnelProvider: Stopping packet handling") 106 | return 107 | } 108 | 109 | for (packet, proto) in zip(packets, protocols) { 110 | os_log(.debug, "PacketTunnelProvider: Received packet of size %d, protocol: %@", packet.count, proto.description) 111 | 112 | 113 | } 114 | 115 | 116 | self.handlePackets() 117 | } 118 | } 119 | 120 | func monitorTunnelActivity() { 121 | DispatchQueue.global().async { 122 | while self.tunnelRunning { 123 | usleep(1000000) 124 | os_log(.debug, "PacketTunnelProvider: Tunnel still active, checking packets...") 125 | } 126 | } 127 | } 128 | 129 | func checkTunnelStatus() { 130 | os_log(.debug, "PacketTunnelProvider: Checking tunnel status...") 131 | if self.packetFlow == nil { 132 | os_log(.error, "PacketTunnelProvider: Tunnel flow is nil, possible disconnection") 133 | } else { 134 | os_log(.info, "PacketTunnelProvider: Tunnel flow is active") 135 | } 136 | } 137 | 138 | override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 139 | os_log(.debug, "PacketTunnelProvider: Stopping tunnel with reason: %@", reason.rawValue.description) 140 | tunnelRunning = false 141 | hev_socks5_tunnel_quit() 142 | completionHandler() 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VPNclient-wrapper 2 | 3 | Идея заключается в создании кроссплатформенного враппера из драйвера туннеля плюс ядра для VPN клиентов. 4 | В качестве ядра могут выступать XRAY, Sign-box и/или другие opensource решения. 5 | В качестве драйвера туннеля могут выступать tun2socks, hevsocks5 и другие открытые решения. 6 | 7 | Wrapper предоставит простой доступ для клиентского интерфейса. 8 | -------------------------------------------------------------------------------- /VPNclientEngine.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint vpnclient_engine_flutter.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'vpnclient_engine_flutter' 7 | s.version = '0.0.1' 8 | s.summary = 'VPNclient Engine Flutter plugin project.' 9 | s.description = <<-DESC 10 | VPNclient Engine Flutter plugin project. 11 | DESC 12 | s.homepage = 'http://vpnclient.click' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'admin@nativemind.net' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | #s.dependency 'VPNclientEngineIOS', :path => '../1/VPNclient-engine-ios' 19 | s.platform = :ios, '12.0' 20 | 21 | # Flutter.framework does not contain a i386 slice. 22 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 23 | s.swift_version = '5.0' 24 | 25 | # If your plugin requires a privacy manifest, for example if it uses any 26 | # required reason APIs, update the PrivacyInfo.xcprivacy file to describe your 27 | # plugin's privacy impact, and then uncomment this line. For more information, 28 | # see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files 29 | # s.resource_bundles = {'vpnclient_engine_flutter_privacy' => ['Resources/PrivacyInfo.xcprivacy']} 30 | end 31 | -------------------------------------------------------------------------------- /VPNclientEngineIOS/VPNclientEngineIOS.docc/VPNclientEngineIOS.md: -------------------------------------------------------------------------------- 1 | # ``VPNclientEngineIOS`` 2 | 3 | Summary 4 | 5 | ## Overview 6 | 7 | Text 8 | 9 | ## Topics 10 | 11 | ### Group 12 | 13 | - ``Symbol`` -------------------------------------------------------------------------------- /VPNclientEngineIOS/VPNclientEngineIOS.h: -------------------------------------------------------------------------------- 1 | // 2 | // VPNclientEngineIOS.h 3 | // VPNclientEngineIOS 4 | // 5 | // Created by Anton Dodonov on 27/3/25. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for VPNclientEngineIOS. 11 | FOUNDATION_EXPORT double VPNclientEngineIOSVersionNumber; 12 | 13 | //! Project version string for VPNclientEngineIOS. 14 | FOUNDATION_EXPORT const unsigned char VPNclientEngineIOSVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /VPNclientTunnel.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'VPNclientTunnel' 3 | s.version = '0.1.0' 4 | s.summary = 'Packet Tunnel Network Extension for VPNclient' 5 | s.description = 'Provides NEPacketTunnelProvider implementation.' 6 | s.homepage = 'https://github.com/VPNclient/VPNclient-engine-ios' 7 | s.license = { :type => 'Extended GPLv3', :file => 'LICENSE' } 8 | s.author = { 'NativeMind' => 'info@nativemind.net' } 9 | s.source = { :git => 'https://github.com/VPNclient/VPNclient-engine-ios.git', :tag => s.version.to_s } 10 | 11 | s.ios.deployment_target = '11.0' 12 | s.source_files = 'VPNclientTunnel/**/*.{swift}' 13 | 14 | s.preserve_paths = 'VPNclientTunnel/*' 15 | s.frameworks = ['NetworkExtension'] 16 | s.requires_arc = true 17 | 18 | s.platform = :ios, '12.0' 19 | end -------------------------------------------------------------------------------- /cntrlr.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 77; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3A25C0BB2D958AC000955407 /* VPNclientEngineIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A25C0B32D958AC000955407 /* VPNclientEngineIOS.framework */; }; 11 | 3A25C0BC2D958AC000955407 /* VPNclientEngineIOS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3A25C0B32D958AC000955407 /* VPNclientEngineIOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 12 | D8020B9C2D838FAA008F36CF /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8020B702D838F20008F36CF /* NetworkExtension.framework */; }; 13 | D8020BA42D838FAA008F36CF /* PacketTunnelProvider.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D8020B9B2D838FAA008F36CF /* PacketTunnelProvider.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 14 | D8020BCB2D839405008F36CF /* HevSocks5Tunnel.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8020BCA2D839405008F36CF /* HevSocks5Tunnel.xcframework */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXContainerItemProxy section */ 18 | 3A25C0B92D958AC000955407 /* PBXContainerItemProxy */ = { 19 | isa = PBXContainerItemProxy; 20 | containerPortal = D8020B4E2D838DF0008F36CF /* Project object */; 21 | proxyType = 1; 22 | remoteGlobalIDString = 3A25C0B22D958AC000955407; 23 | remoteInfo = VPNclientEngineIOS; 24 | }; 25 | D8020BA22D838FAA008F36CF /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = D8020B4E2D838DF0008F36CF /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = D8020B9A2D838FAA008F36CF; 30 | remoteInfo = PacketTunnelProvider; 31 | }; 32 | /* End PBXContainerItemProxy section */ 33 | 34 | /* Begin PBXCopyFilesBuildPhase section */ 35 | 3A25C0BD2D958AC000955407 /* Embed Frameworks */ = { 36 | isa = PBXCopyFilesBuildPhase; 37 | buildActionMask = 2147483647; 38 | dstPath = ""; 39 | dstSubfolderSpec = 10; 40 | files = ( 41 | 3A25C0BC2D958AC000955407 /* VPNclientEngineIOS.framework in Embed Frameworks */, 42 | ); 43 | name = "Embed Frameworks"; 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | D8020B7E2D838F20008F36CF /* Embed Foundation Extensions */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 2147483647; 49 | dstPath = ""; 50 | dstSubfolderSpec = 13; 51 | files = ( 52 | D8020BA42D838FAA008F36CF /* PacketTunnelProvider.appex in Embed Foundation Extensions */, 53 | ); 54 | name = "Embed Foundation Extensions"; 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXCopyFilesBuildPhase section */ 58 | 59 | /* Begin PBXFileReference section */ 60 | 3A1EF5DE2D9E7AD4000C3C51 /* PacketTunnelProvider copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "PacketTunnelProvider copy-Info.plist"; path = "/Users/anton/proj/VPNclient/VPNclient-engine-ios/PacketTunnelProvider copy-Info.plist"; sourceTree = ""; }; 61 | 3A25C0B32D958AC000955407 /* VPNclientEngineIOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = VPNclientEngineIOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | D8020B562D838DF0008F36CF /* VPNclientEngine.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VPNclientEngine.app; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | D8020B702D838F20008F36CF /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; 64 | D8020B9B2D838FAA008F36CF /* PacketTunnelProvider.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PacketTunnelProvider.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | D8020BCA2D839405008F36CF /* HevSocks5Tunnel.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = HevSocks5Tunnel.xcframework; sourceTree = ""; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ 69 | 3A25C0C02D958AC000955407 /* Exceptions for "VPNclientEngineIOS" folder in "VPNclientEngineIOS" target */ = { 70 | isa = PBXFileSystemSynchronizedBuildFileExceptionSet; 71 | publicHeaders = ( 72 | VPNclientEngineIOS.h, 73 | ); 74 | target = 3A25C0B22D958AC000955407 /* VPNclientEngineIOS */; 75 | }; 76 | D8020BA52D838FAA008F36CF /* Exceptions for "PacketTunnelProvider" folder in "PacketTunnelProvider" target */ = { 77 | isa = PBXFileSystemSynchronizedBuildFileExceptionSet; 78 | membershipExceptions = ( 79 | Info.plist, 80 | ); 81 | target = D8020B9A2D838FAA008F36CF /* PacketTunnelProvider */; 82 | }; 83 | /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ 84 | 85 | /* Begin PBXFileSystemSynchronizedRootGroup section */ 86 | 3A25C0B42D958AC000955407 /* VPNclientEngineIOS */ = { 87 | isa = PBXFileSystemSynchronizedRootGroup; 88 | exceptions = ( 89 | 3A25C0C02D958AC000955407 /* Exceptions for "VPNclientEngineIOS" folder in "VPNclientEngineIOS" target */, 90 | ); 91 | path = VPNclientEngineIOS; 92 | sourceTree = ""; 93 | }; 94 | D8020B582D838DF0008F36CF /* cntrlr */ = { 95 | isa = PBXFileSystemSynchronizedRootGroup; 96 | path = cntrlr; 97 | sourceTree = ""; 98 | }; 99 | D8020B9D2D838FAA008F36CF /* PacketTunnelProvider */ = { 100 | isa = PBXFileSystemSynchronizedRootGroup; 101 | exceptions = ( 102 | D8020BA52D838FAA008F36CF /* Exceptions for "PacketTunnelProvider" folder in "PacketTunnelProvider" target */, 103 | ); 104 | path = PacketTunnelProvider; 105 | sourceTree = ""; 106 | }; 107 | /* End PBXFileSystemSynchronizedRootGroup section */ 108 | 109 | /* Begin PBXFrameworksBuildPhase section */ 110 | 3A25C0B02D958AC000955407 /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | ); 115 | runOnlyForDeploymentPostprocessing = 0; 116 | }; 117 | D8020B532D838DF0008F36CF /* Frameworks */ = { 118 | isa = PBXFrameworksBuildPhase; 119 | buildActionMask = 2147483647; 120 | files = ( 121 | 3A25C0BB2D958AC000955407 /* VPNclientEngineIOS.framework in Frameworks */, 122 | ); 123 | runOnlyForDeploymentPostprocessing = 0; 124 | }; 125 | D8020B982D838FAA008F36CF /* Frameworks */ = { 126 | isa = PBXFrameworksBuildPhase; 127 | buildActionMask = 2147483647; 128 | files = ( 129 | D8020B9C2D838FAA008F36CF /* NetworkExtension.framework in Frameworks */, 130 | D8020BCB2D839405008F36CF /* HevSocks5Tunnel.xcframework in Frameworks */, 131 | ); 132 | runOnlyForDeploymentPostprocessing = 0; 133 | }; 134 | /* End PBXFrameworksBuildPhase section */ 135 | 136 | /* Begin PBXGroup section */ 137 | D8020B4D2D838DF0008F36CF = { 138 | isa = PBXGroup; 139 | children = ( 140 | D8020B582D838DF0008F36CF /* cntrlr */, 141 | D8020B9D2D838FAA008F36CF /* PacketTunnelProvider */, 142 | 3A25C0B42D958AC000955407 /* VPNclientEngineIOS */, 143 | D8020B6F2D838F20008F36CF /* Frameworks */, 144 | 3A1EF5DE2D9E7AD4000C3C51 /* PacketTunnelProvider copy-Info.plist */, 145 | D8020B572D838DF0008F36CF /* Products */, 146 | ); 147 | sourceTree = ""; 148 | }; 149 | D8020B572D838DF0008F36CF /* Products */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | D8020B562D838DF0008F36CF /* VPNclientEngine.app */, 153 | D8020B9B2D838FAA008F36CF /* PacketTunnelProvider.appex */, 154 | 3A25C0B32D958AC000955407 /* VPNclientEngineIOS.framework */, 155 | ); 156 | name = Products; 157 | sourceTree = ""; 158 | }; 159 | D8020B6F2D838F20008F36CF /* Frameworks */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | D8020BCA2D839405008F36CF /* HevSocks5Tunnel.xcframework */, 163 | D8020B702D838F20008F36CF /* NetworkExtension.framework */, 164 | ); 165 | name = Frameworks; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXHeadersBuildPhase section */ 171 | 3A25C0AE2D958AC000955407 /* Headers */ = { 172 | isa = PBXHeadersBuildPhase; 173 | buildActionMask = 2147483647; 174 | files = ( 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXHeadersBuildPhase section */ 179 | 180 | /* Begin PBXNativeTarget section */ 181 | 3A25C0B22D958AC000955407 /* VPNclientEngineIOS */ = { 182 | isa = PBXNativeTarget; 183 | buildConfigurationList = 3A25C0C12D958AC000955407 /* Build configuration list for PBXNativeTarget "VPNclientEngineIOS" */; 184 | buildPhases = ( 185 | 3A25C0AE2D958AC000955407 /* Headers */, 186 | 3A25C0AF2D958AC000955407 /* Sources */, 187 | 3A25C0B02D958AC000955407 /* Frameworks */, 188 | 3A25C0B12D958AC000955407 /* Resources */, 189 | ); 190 | buildRules = ( 191 | ); 192 | dependencies = ( 193 | ); 194 | fileSystemSynchronizedGroups = ( 195 | 3A25C0B42D958AC000955407 /* VPNclientEngineIOS */, 196 | ); 197 | name = VPNclientEngineIOS; 198 | packageProductDependencies = ( 199 | ); 200 | productName = VPNclientEngineIOS; 201 | productReference = 3A25C0B32D958AC000955407 /* VPNclientEngineIOS.framework */; 202 | productType = "com.apple.product-type.framework"; 203 | }; 204 | D8020B552D838DF0008F36CF /* VPNclientEngine */ = { 205 | isa = PBXNativeTarget; 206 | buildConfigurationList = D8020B662D838DF1008F36CF /* Build configuration list for PBXNativeTarget "VPNclientEngine" */; 207 | buildPhases = ( 208 | D8020B522D838DF0008F36CF /* Sources */, 209 | D8020B532D838DF0008F36CF /* Frameworks */, 210 | D8020B542D838DF0008F36CF /* Resources */, 211 | D8020B7E2D838F20008F36CF /* Embed Foundation Extensions */, 212 | 3A25C0BD2D958AC000955407 /* Embed Frameworks */, 213 | ); 214 | buildRules = ( 215 | ); 216 | dependencies = ( 217 | D8020BA32D838FAA008F36CF /* PBXTargetDependency */, 218 | 3A25C0BA2D958AC000955407 /* PBXTargetDependency */, 219 | ); 220 | fileSystemSynchronizedGroups = ( 221 | D8020B582D838DF0008F36CF /* cntrlr */, 222 | ); 223 | name = VPNclientEngine; 224 | packageProductDependencies = ( 225 | ); 226 | productName = cntrlr; 227 | productReference = D8020B562D838DF0008F36CF /* VPNclientEngine.app */; 228 | productType = "com.apple.product-type.application"; 229 | }; 230 | D8020B9A2D838FAA008F36CF /* PacketTunnelProvider */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = D8020BA62D838FAA008F36CF /* Build configuration list for PBXNativeTarget "PacketTunnelProvider" */; 233 | buildPhases = ( 234 | D8020B972D838FAA008F36CF /* Sources */, 235 | D8020B982D838FAA008F36CF /* Frameworks */, 236 | D8020B992D838FAA008F36CF /* Resources */, 237 | ); 238 | buildRules = ( 239 | ); 240 | dependencies = ( 241 | ); 242 | fileSystemSynchronizedGroups = ( 243 | D8020B9D2D838FAA008F36CF /* PacketTunnelProvider */, 244 | ); 245 | name = PacketTunnelProvider; 246 | packageProductDependencies = ( 247 | ); 248 | productName = PacketTunnelProvider; 249 | productReference = D8020B9B2D838FAA008F36CF /* PacketTunnelProvider.appex */; 250 | productType = "com.apple.product-type.app-extension"; 251 | }; 252 | /* End PBXNativeTarget section */ 253 | 254 | /* Begin PBXProject section */ 255 | D8020B4E2D838DF0008F36CF /* Project object */ = { 256 | isa = PBXProject; 257 | attributes = { 258 | BuildIndependentTargetsInParallel = 1; 259 | LastSwiftUpdateCheck = 1620; 260 | LastUpgradeCheck = 1620; 261 | TargetAttributes = { 262 | 3A25C0B22D958AC000955407 = { 263 | CreatedOnToolsVersion = 16.2; 264 | }; 265 | D8020B552D838DF0008F36CF = { 266 | CreatedOnToolsVersion = 16.2; 267 | }; 268 | D8020B9A2D838FAA008F36CF = { 269 | CreatedOnToolsVersion = 16.2; 270 | }; 271 | }; 272 | }; 273 | buildConfigurationList = D8020B512D838DF0008F36CF /* Build configuration list for PBXProject "cntrlr" */; 274 | developmentRegion = en; 275 | hasScannedForEncodings = 0; 276 | knownRegions = ( 277 | en, 278 | Base, 279 | ); 280 | mainGroup = D8020B4D2D838DF0008F36CF; 281 | minimizedProjectReferenceProxies = 1; 282 | preferredProjectObjectVersion = 77; 283 | productRefGroup = D8020B572D838DF0008F36CF /* Products */; 284 | projectDirPath = ""; 285 | projectRoot = ""; 286 | targets = ( 287 | D8020B552D838DF0008F36CF /* VPNclientEngine */, 288 | D8020B9A2D838FAA008F36CF /* PacketTunnelProvider */, 289 | 3A25C0B22D958AC000955407 /* VPNclientEngineIOS */, 290 | ); 291 | }; 292 | /* End PBXProject section */ 293 | 294 | /* Begin PBXResourcesBuildPhase section */ 295 | 3A25C0B12D958AC000955407 /* Resources */ = { 296 | isa = PBXResourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | D8020B542D838DF0008F36CF /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | D8020B992D838FAA008F36CF /* Resources */ = { 310 | isa = PBXResourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | /* End PBXResourcesBuildPhase section */ 317 | 318 | /* Begin PBXSourcesBuildPhase section */ 319 | 3A25C0AF2D958AC000955407 /* Sources */ = { 320 | isa = PBXSourcesBuildPhase; 321 | buildActionMask = 2147483647; 322 | files = ( 323 | ); 324 | runOnlyForDeploymentPostprocessing = 0; 325 | }; 326 | D8020B522D838DF0008F36CF /* Sources */ = { 327 | isa = PBXSourcesBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | ); 331 | runOnlyForDeploymentPostprocessing = 0; 332 | }; 333 | D8020B972D838FAA008F36CF /* Sources */ = { 334 | isa = PBXSourcesBuildPhase; 335 | buildActionMask = 2147483647; 336 | files = ( 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | }; 340 | /* End PBXSourcesBuildPhase section */ 341 | 342 | /* Begin PBXTargetDependency section */ 343 | 3A25C0BA2D958AC000955407 /* PBXTargetDependency */ = { 344 | isa = PBXTargetDependency; 345 | target = 3A25C0B22D958AC000955407 /* VPNclientEngineIOS */; 346 | targetProxy = 3A25C0B92D958AC000955407 /* PBXContainerItemProxy */; 347 | }; 348 | D8020BA32D838FAA008F36CF /* PBXTargetDependency */ = { 349 | isa = PBXTargetDependency; 350 | target = D8020B9A2D838FAA008F36CF /* PacketTunnelProvider */; 351 | targetProxy = D8020BA22D838FAA008F36CF /* PBXContainerItemProxy */; 352 | }; 353 | /* End PBXTargetDependency section */ 354 | 355 | /* Begin XCBuildConfiguration section */ 356 | 3A25C0BE2D958AC000955407 /* Debug */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; 360 | BUILD_LIBRARY_FOR_DISTRIBUTION = YES; 361 | CODE_SIGN_STYLE = Automatic; 362 | CURRENT_PROJECT_VERSION = 1; 363 | DEFINES_MODULE = YES; 364 | DEVELOPMENT_TEAM = 6XT4R7V83F; 365 | DYLIB_COMPATIBILITY_VERSION = 1; 366 | DYLIB_CURRENT_VERSION = 1; 367 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 368 | ENABLE_MODULE_VERIFIER = YES; 369 | GENERATE_INFOPLIST_FILE = YES; 370 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 371 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 372 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 373 | LD_RUNPATH_SEARCH_PATHS = ( 374 | "@executable_path/Frameworks", 375 | "@loader_path/Frameworks", 376 | ); 377 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( 378 | "@executable_path/../Frameworks", 379 | "@loader_path/Frameworks", 380 | ); 381 | MACOSX_DEPLOYMENT_TARGET = 11.5; 382 | MARKETING_VERSION = 1.0; 383 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 384 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 385 | PRODUCT_BUNDLE_IDENTIFIER = click.vpnclient.engine.ios; 386 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 387 | SDKROOT = auto; 388 | SKIP_INSTALL = YES; 389 | SUPPORTED_PLATFORMS = "xrsimulator xros watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; 390 | SUPPORTS_MACCATALYST = YES; 391 | SWIFT_EMIT_LOC_STRINGS = YES; 392 | SWIFT_INSTALL_OBJC_HEADER = NO; 393 | SWIFT_VERSION = 5.0; 394 | TARGETED_DEVICE_FAMILY = "1,2,7"; 395 | VERSIONING_SYSTEM = "apple-generic"; 396 | VERSION_INFO_PREFIX = ""; 397 | XROS_DEPLOYMENT_TARGET = 2.2; 398 | }; 399 | name = Debug; 400 | }; 401 | 3A25C0BF2D958AC000955407 /* Release */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; 405 | BUILD_LIBRARY_FOR_DISTRIBUTION = YES; 406 | CODE_SIGN_STYLE = Automatic; 407 | CURRENT_PROJECT_VERSION = 1; 408 | DEFINES_MODULE = YES; 409 | DEVELOPMENT_TEAM = 6XT4R7V83F; 410 | DYLIB_COMPATIBILITY_VERSION = 1; 411 | DYLIB_CURRENT_VERSION = 1; 412 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 413 | ENABLE_MODULE_VERIFIER = YES; 414 | GENERATE_INFOPLIST_FILE = YES; 415 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 416 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 417 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 418 | LD_RUNPATH_SEARCH_PATHS = ( 419 | "@executable_path/Frameworks", 420 | "@loader_path/Frameworks", 421 | ); 422 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( 423 | "@executable_path/../Frameworks", 424 | "@loader_path/Frameworks", 425 | ); 426 | MACOSX_DEPLOYMENT_TARGET = 11.5; 427 | MARKETING_VERSION = 1.0; 428 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 429 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 430 | PRODUCT_BUNDLE_IDENTIFIER = click.vpnclient.engine.ios; 431 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 432 | SDKROOT = auto; 433 | SKIP_INSTALL = YES; 434 | SUPPORTED_PLATFORMS = "xrsimulator xros watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; 435 | SUPPORTS_MACCATALYST = YES; 436 | SWIFT_EMIT_LOC_STRINGS = YES; 437 | SWIFT_INSTALL_OBJC_HEADER = NO; 438 | SWIFT_VERSION = 5.0; 439 | TARGETED_DEVICE_FAMILY = "1,2,7"; 440 | VERSIONING_SYSTEM = "apple-generic"; 441 | VERSION_INFO_PREFIX = ""; 442 | XROS_DEPLOYMENT_TARGET = 2.2; 443 | }; 444 | name = Release; 445 | }; 446 | D8020B642D838DF1008F36CF /* Debug */ = { 447 | isa = XCBuildConfiguration; 448 | buildSettings = { 449 | ALWAYS_SEARCH_USER_PATHS = NO; 450 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 451 | CLANG_ANALYZER_NONNULL = YES; 452 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 453 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 454 | CLANG_ENABLE_MODULES = YES; 455 | CLANG_ENABLE_OBJC_ARC = YES; 456 | CLANG_ENABLE_OBJC_WEAK = YES; 457 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 458 | CLANG_WARN_BOOL_CONVERSION = YES; 459 | CLANG_WARN_COMMA = YES; 460 | CLANG_WARN_CONSTANT_CONVERSION = YES; 461 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 462 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 463 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 464 | CLANG_WARN_EMPTY_BODY = YES; 465 | CLANG_WARN_ENUM_CONVERSION = YES; 466 | CLANG_WARN_INFINITE_RECURSION = YES; 467 | CLANG_WARN_INT_CONVERSION = YES; 468 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 469 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 470 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 471 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 472 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 473 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 474 | CLANG_WARN_STRICT_PROTOTYPES = YES; 475 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 476 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 477 | CLANG_WARN_UNREACHABLE_CODE = YES; 478 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 479 | COPY_PHASE_STRIP = NO; 480 | DEBUG_INFORMATION_FORMAT = dwarf; 481 | ENABLE_STRICT_OBJC_MSGSEND = YES; 482 | ENABLE_TESTABILITY = YES; 483 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 484 | GCC_C_LANGUAGE_STANDARD = gnu17; 485 | GCC_DYNAMIC_NO_PIC = NO; 486 | GCC_NO_COMMON_BLOCKS = YES; 487 | GCC_OPTIMIZATION_LEVEL = 0; 488 | GCC_PREPROCESSOR_DEFINITIONS = ( 489 | "DEBUG=1", 490 | "$(inherited)", 491 | ); 492 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 493 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 494 | GCC_WARN_UNDECLARED_SELECTOR = YES; 495 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 496 | GCC_WARN_UNUSED_FUNCTION = YES; 497 | GCC_WARN_UNUSED_VARIABLE = YES; 498 | IPHONEOS_DEPLOYMENT_TARGET = 18.2; 499 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 500 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 501 | MTL_FAST_MATH = YES; 502 | ONLY_ACTIVE_ARCH = YES; 503 | SDKROOT = iphoneos; 504 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 505 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 506 | }; 507 | name = Debug; 508 | }; 509 | D8020B652D838DF1008F36CF /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ALWAYS_SEARCH_USER_PATHS = NO; 513 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 514 | CLANG_ANALYZER_NONNULL = YES; 515 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 516 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 517 | CLANG_ENABLE_MODULES = YES; 518 | CLANG_ENABLE_OBJC_ARC = YES; 519 | CLANG_ENABLE_OBJC_WEAK = YES; 520 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 521 | CLANG_WARN_BOOL_CONVERSION = YES; 522 | CLANG_WARN_COMMA = YES; 523 | CLANG_WARN_CONSTANT_CONVERSION = YES; 524 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 525 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 526 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 527 | CLANG_WARN_EMPTY_BODY = YES; 528 | CLANG_WARN_ENUM_CONVERSION = YES; 529 | CLANG_WARN_INFINITE_RECURSION = YES; 530 | CLANG_WARN_INT_CONVERSION = YES; 531 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 532 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 533 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 534 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 535 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 536 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 537 | CLANG_WARN_STRICT_PROTOTYPES = YES; 538 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 539 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 540 | CLANG_WARN_UNREACHABLE_CODE = YES; 541 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 542 | COPY_PHASE_STRIP = NO; 543 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 544 | ENABLE_NS_ASSERTIONS = NO; 545 | ENABLE_STRICT_OBJC_MSGSEND = YES; 546 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 547 | GCC_C_LANGUAGE_STANDARD = gnu17; 548 | GCC_NO_COMMON_BLOCKS = YES; 549 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 550 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 551 | GCC_WARN_UNDECLARED_SELECTOR = YES; 552 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 553 | GCC_WARN_UNUSED_FUNCTION = YES; 554 | GCC_WARN_UNUSED_VARIABLE = YES; 555 | IPHONEOS_DEPLOYMENT_TARGET = 18.2; 556 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 557 | MTL_ENABLE_DEBUG_INFO = NO; 558 | MTL_FAST_MATH = YES; 559 | SDKROOT = iphoneos; 560 | SWIFT_COMPILATION_MODE = wholemodule; 561 | VALIDATE_PRODUCT = YES; 562 | }; 563 | name = Release; 564 | }; 565 | D8020B672D838DF1008F36CF /* Debug */ = { 566 | isa = XCBuildConfiguration; 567 | buildSettings = { 568 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 569 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 570 | CODE_SIGN_ENTITLEMENTS = cntrlr/cntrlr.entitlements; 571 | CODE_SIGN_STYLE = Automatic; 572 | CURRENT_PROJECT_VERSION = 1; 573 | DEVELOPMENT_ASSET_PATHS = "\"cntrlr/Preview Content\""; 574 | DEVELOPMENT_TEAM = 6XT4R7V83F; 575 | ENABLE_PREVIEWS = YES; 576 | GENERATE_INFOPLIST_FILE = YES; 577 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 578 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 579 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 580 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 581 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 582 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 583 | LD_RUNPATH_SEARCH_PATHS = ( 584 | "$(inherited)", 585 | "@executable_path/Frameworks", 586 | ); 587 | MARKETING_VERSION = 1.0; 588 | PRODUCT_BUNDLE_IDENTIFIER = click.vpnclient.engine; 589 | PRODUCT_NAME = "$(TARGET_NAME)"; 590 | SWIFT_EMIT_LOC_STRINGS = YES; 591 | SWIFT_VERSION = 5.0; 592 | TARGETED_DEVICE_FAMILY = "1,2"; 593 | }; 594 | name = Debug; 595 | }; 596 | D8020B682D838DF1008F36CF /* Release */ = { 597 | isa = XCBuildConfiguration; 598 | buildSettings = { 599 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 600 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 601 | CODE_SIGN_ENTITLEMENTS = cntrlr/cntrlr.entitlements; 602 | CODE_SIGN_STYLE = Automatic; 603 | CURRENT_PROJECT_VERSION = 1; 604 | DEVELOPMENT_ASSET_PATHS = "\"cntrlr/Preview Content\""; 605 | DEVELOPMENT_TEAM = 6XT4R7V83F; 606 | ENABLE_PREVIEWS = YES; 607 | GENERATE_INFOPLIST_FILE = YES; 608 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 609 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 610 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 611 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 612 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 613 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 614 | LD_RUNPATH_SEARCH_PATHS = ( 615 | "$(inherited)", 616 | "@executable_path/Frameworks", 617 | ); 618 | MARKETING_VERSION = 1.0; 619 | PRODUCT_BUNDLE_IDENTIFIER = click.vpnclient.engine; 620 | PRODUCT_NAME = "$(TARGET_NAME)"; 621 | SWIFT_EMIT_LOC_STRINGS = YES; 622 | SWIFT_VERSION = 5.0; 623 | TARGETED_DEVICE_FAMILY = "1,2"; 624 | }; 625 | name = Release; 626 | }; 627 | D8020BA72D838FAA008F36CF /* Debug */ = { 628 | isa = XCBuildConfiguration; 629 | buildSettings = { 630 | CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProvider.entitlements; 631 | CODE_SIGN_STYLE = Automatic; 632 | CURRENT_PROJECT_VERSION = 1; 633 | DEVELOPMENT_TEAM = 6XT4R7V83F; 634 | GENERATE_INFOPLIST_FILE = YES; 635 | INFOPLIST_FILE = PacketTunnelProvider/Info.plist; 636 | INFOPLIST_KEY_CFBundleDisplayName = PacketTunnelProvider; 637 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 638 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 639 | LD_RUNPATH_SEARCH_PATHS = ( 640 | "$(inherited)", 641 | "@executable_path/Frameworks", 642 | "@executable_path/../../Frameworks", 643 | ); 644 | MARKETING_VERSION = 1.0; 645 | PRODUCT_BUNDLE_IDENTIFIER = click.vpnclient.engine.PacketTunnelProvider; 646 | PRODUCT_NAME = "$(TARGET_NAME)"; 647 | SKIP_INSTALL = YES; 648 | SWIFT_EMIT_LOC_STRINGS = YES; 649 | SWIFT_VERSION = 5.0; 650 | TARGETED_DEVICE_FAMILY = "1,2"; 651 | }; 652 | name = Debug; 653 | }; 654 | D8020BA82D838FAA008F36CF /* Release */ = { 655 | isa = XCBuildConfiguration; 656 | buildSettings = { 657 | CODE_SIGN_ENTITLEMENTS = PacketTunnelProvider/PacketTunnelProvider.entitlements; 658 | CODE_SIGN_STYLE = Automatic; 659 | CURRENT_PROJECT_VERSION = 1; 660 | DEVELOPMENT_TEAM = 6XT4R7V83F; 661 | GENERATE_INFOPLIST_FILE = YES; 662 | INFOPLIST_FILE = PacketTunnelProvider/Info.plist; 663 | INFOPLIST_KEY_CFBundleDisplayName = PacketTunnelProvider; 664 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 665 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 666 | LD_RUNPATH_SEARCH_PATHS = ( 667 | "$(inherited)", 668 | "@executable_path/Frameworks", 669 | "@executable_path/../../Frameworks", 670 | ); 671 | MARKETING_VERSION = 1.0; 672 | PRODUCT_BUNDLE_IDENTIFIER = click.vpnclient.engine.PacketTunnelProvider; 673 | PRODUCT_NAME = "$(TARGET_NAME)"; 674 | SKIP_INSTALL = YES; 675 | SWIFT_EMIT_LOC_STRINGS = YES; 676 | SWIFT_VERSION = 5.0; 677 | TARGETED_DEVICE_FAMILY = "1,2"; 678 | }; 679 | name = Release; 680 | }; 681 | /* End XCBuildConfiguration section */ 682 | 683 | /* Begin XCConfigurationList section */ 684 | 3A25C0C12D958AC000955407 /* Build configuration list for PBXNativeTarget "VPNclientEngineIOS" */ = { 685 | isa = XCConfigurationList; 686 | buildConfigurations = ( 687 | 3A25C0BE2D958AC000955407 /* Debug */, 688 | 3A25C0BF2D958AC000955407 /* Release */, 689 | ); 690 | defaultConfigurationIsVisible = 0; 691 | defaultConfigurationName = Release; 692 | }; 693 | D8020B512D838DF0008F36CF /* Build configuration list for PBXProject "cntrlr" */ = { 694 | isa = XCConfigurationList; 695 | buildConfigurations = ( 696 | D8020B642D838DF1008F36CF /* Debug */, 697 | D8020B652D838DF1008F36CF /* Release */, 698 | ); 699 | defaultConfigurationIsVisible = 0; 700 | defaultConfigurationName = Release; 701 | }; 702 | D8020B662D838DF1008F36CF /* Build configuration list for PBXNativeTarget "VPNclientEngine" */ = { 703 | isa = XCConfigurationList; 704 | buildConfigurations = ( 705 | D8020B672D838DF1008F36CF /* Debug */, 706 | D8020B682D838DF1008F36CF /* Release */, 707 | ); 708 | defaultConfigurationIsVisible = 0; 709 | defaultConfigurationName = Release; 710 | }; 711 | D8020BA62D838FAA008F36CF /* Build configuration list for PBXNativeTarget "PacketTunnelProvider" */ = { 712 | isa = XCConfigurationList; 713 | buildConfigurations = ( 714 | D8020BA72D838FAA008F36CF /* Debug */, 715 | D8020BA82D838FAA008F36CF /* Release */, 716 | ); 717 | defaultConfigurationIsVisible = 0; 718 | defaultConfigurationName = Release; 719 | }; 720 | /* End XCConfigurationList section */ 721 | }; 722 | rootObject = D8020B4E2D838DF0008F36CF /* Project object */; 723 | } 724 | -------------------------------------------------------------------------------- /cntrlr.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cntrlr.xcodeproj/project.xcworkspace/xcuserdata/anton.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/cntrlr.xcodeproj/project.xcworkspace/xcuserdata/anton.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /cntrlr.xcodeproj/project.xcworkspace/xcuserdata/ginter.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VPNclient/VPNclient-engine-ios/67c1e294415186b953ca41c6ee3015f994e199cb/cntrlr.xcodeproj/project.xcworkspace/xcuserdata/ginter.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /cntrlr.xcodeproj/xcshareddata/xcschemes/PackageTunnelProvider.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 11 | 17 | 23 | 24 | 25 | 31 | 37 | 38 | 39 | 40 | 41 | 47 | 48 | 60 | 64 | 65 | 66 | 72 | 73 | 74 | 75 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /cntrlr.xcodeproj/xcshareddata/xcschemes/cntrlr.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 16 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /cntrlr.xcodeproj/xcuserdata/anton.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PackageTunnelProvider.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | PacketTunnelProvider.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | VPNclientEngineIOS.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 2 21 | 22 | cntrlr.xcscheme_^#shared#^_ 23 | 24 | orderHint 25 | 0 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /cntrlr.xcodeproj/xcuserdata/ginter.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PacketTunnelProvider.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | cntrlr.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | D8020B552D838DF0008F36CF 21 | 22 | primary 23 | 24 | 25 | D8020B9A2D838FAA008F36CF 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /cntrlr/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /cntrlr/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "idiom" : "universal", 16 | "platform" : "ios", 17 | "size" : "1024x1024" 18 | }, 19 | { 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "tinted" 24 | } 25 | ], 26 | "idiom" : "universal", 27 | "platform" : "ios", 28 | "size" : "1024x1024" 29 | } 30 | ], 31 | "info" : { 32 | "author" : "xcode", 33 | "version" : 1 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /cntrlr/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /cntrlr/ContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import NetworkExtension 3 | 4 | struct ContentView: View { 5 | @StateObject private var vpnManager = VPNManager() 6 | @State private var vpnStatus: NEVPNStatus = .invalid 7 | @State private var socks5Proxy: String = "176.226.244.28:1080" 8 | @State private var tunAddr: String = "192.168.1.2" 9 | @State private var tunMask: String = "255.255.255.0" 10 | @State private var tunDns: String = "8.8.8.8" 11 | 12 | var body: some View { 13 | VStack(spacing: 20) { 14 | Text("VPN Status: \(vpnStatus.description)") 15 | .font(.headline) 16 | 17 | TextField("SOCKS5 Proxy (e.g., server:port)", text: $socks5Proxy) 18 | .textFieldStyle(RoundedBorderTextFieldStyle()) 19 | .padding() 20 | TextField("TUN Address (e.g., 192.168.1.2)", text: $tunAddr) 21 | .textFieldStyle(RoundedBorderTextFieldStyle()) 22 | .padding() 23 | TextField("TUN Mask (e.g., 255.255.255.0)", text: $tunMask) 24 | .textFieldStyle(RoundedBorderTextFieldStyle()) 25 | .padding() 26 | TextField("TUN DNS (e.g., 8.8.8.8)", text: $tunDns) 27 | .textFieldStyle(RoundedBorderTextFieldStyle()) 28 | .padding() 29 | 30 | Button(action: { 31 | vpnManager.setupVPNConfiguration(tunAddr: tunAddr, tunMask: tunMask, tunDns: tunDns, socks5Proxy: socks5Proxy) { error in 32 | if let error = error { 33 | print("Error setting up VPN: \(error)") 34 | } else { 35 | print("VPN configuration set up successfully") 36 | vpnManager.startVPN { error in 37 | if let error = error { 38 | print("VPN start failed: \(error)") 39 | } else { 40 | print("VPN starting") 41 | } 42 | } 43 | } 44 | } 45 | }) { 46 | Text(vpnStatus != .invalid ? "Start VPN" : "Add VPN profile") 47 | .frame(width: 200, height: 50) 48 | .background(vpnStatus == .connected || vpnStatus == .connecting || vpnStatus == .disconnecting ? Color.gray : Color.green) 49 | .foregroundColor(.white) 50 | .cornerRadius(10) 51 | } 52 | .disabled(vpnStatus == .connected || vpnStatus == .connecting || vpnStatus == .disconnecting) 53 | 54 | Button(action: { 55 | vpnManager.stopVPN { 56 | print("VPN stopping") 57 | } 58 | }) { 59 | Text("Stop VPN") 60 | .frame(width: 200, height: 50) 61 | .background(vpnStatus != .connected ? Color.gray : Color.red) 62 | .foregroundColor(.white) 63 | .cornerRadius(10) 64 | } 65 | .disabled(vpnStatus != .connected) 66 | } 67 | .padding() 68 | .onAppear { 69 | updateStatus() 70 | NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: nil, queue: .main) { _ in 71 | updateStatus() 72 | } 73 | } 74 | } 75 | 76 | private func updateStatus() { 77 | vpnStatus = vpnManager.vpnStatus 78 | print("\(vpnStatus.description)") 79 | } 80 | } 81 | 82 | struct ContentView_Previews: PreviewProvider { 83 | static var previews: some View { 84 | ContentView() 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /cntrlr/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /cntrlr/VPNManager.swift: -------------------------------------------------------------------------------- 1 | import NetworkExtension 2 | import SwiftUI 3 | 4 | class VPNManager: ObservableObject { 5 | private var vpnManager: NETunnelProviderManager? 6 | private let profileName = "Controller" 7 | private let initializationGroup = DispatchGroup() 8 | 9 | init() { 10 | print("VPNManager: Initializing...") 11 | initializationGroup.enter() 12 | loadVPNManager { [weak self] in 13 | self?.setupStatusObserver() 14 | self?.initializationGroup.leave() 15 | } 16 | } 17 | 18 | private func loadVPNManager(completion: @escaping () -> Void) { 19 | print("VPNManager: Loading VPN managers...") 20 | NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in 21 | guard let self = self else { 22 | print("VPNManager: Self is nil, completing...") 23 | completion() 24 | return 25 | } 26 | if let error = error { 27 | print("VPNManager: Error loading VPN managers: \(error)") 28 | completion() 29 | return 30 | } 31 | 32 | if let existingManager = managers?.first(where: { $0.localizedDescription == self.profileName }) { 33 | self.vpnManager = existingManager 34 | print("VPNManager: Found existing VPN profile: \(self.profileName)") 35 | } else { 36 | self.vpnManager = NETunnelProviderManager() 37 | self.vpnManager?.localizedDescription = self.profileName 38 | print("VPNManager: Created new VPN profile: \(self.profileName)") 39 | } 40 | completion() 41 | } 42 | } 43 | 44 | private func setupStatusObserver() { 45 | print("VPNManager: Setting up status observer") 46 | NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: nil, queue: .main) { [weak self] _ in 47 | print("VPNManager: Status changed to: \(self?.vpnStatus.description ?? "unknown")") 48 | self?.objectWillChange.send() 49 | } 50 | } 51 | 52 | func waitForInitialization() { 53 | initializationGroup.wait() 54 | } 55 | 56 | func setupVPNConfiguration(tunAddr: String, tunMask: String, tunDns: String, socks5Proxy: String, completion: @escaping (Error?) -> Void) { 57 | print("VPNManager: Setting up VPN configuration with tunAddr=\(tunAddr), tunMask=\(tunMask), tunDns=\(tunDns), socks5Proxy=\(socks5Proxy)") 58 | waitForInitialization() 59 | guard let vpnManager = vpnManager else { 60 | print("VPNManager: VPN Manager not initialized") 61 | completion(NSError(domain: "VPNError", code: -1, userInfo: [NSLocalizedDescriptionKey: "VPN Manager not initialized"])) 62 | return 63 | } 64 | 65 | vpnManager.loadFromPreferences { [weak self] error in 66 | guard let self = self else { return } 67 | if let error = error { 68 | print("VPNManager: Load preferences error: \(error)") 69 | completion(error) 70 | return 71 | } 72 | 73 | let tunnelProtocol = NETunnelProviderProtocol() 74 | tunnelProtocol.providerBundleIdentifier = "click.vpnclient.engine.PacketTunnelProvider" 75 | tunnelProtocol.serverAddress = socks5Proxy.components(separatedBy: ":").first ?? "127.0.0.1" 76 | tunnelProtocol.providerConfiguration = [ 77 | "tunAddr": tunAddr, 78 | "tunMask": tunMask, 79 | "tunDns": tunDns, 80 | "socks5Proxy": socks5Proxy 81 | ] 82 | 83 | vpnManager.protocolConfiguration = tunnelProtocol 84 | vpnManager.isEnabled = true 85 | 86 | print("VPNManager: Saving VPN configuration...") 87 | vpnManager.saveToPreferences { error in 88 | if let error = error { 89 | print("VPNManager: Save preferences error: \(error)") 90 | completion(error) 91 | } else { 92 | print("VPNManager: VPN configuration saved successfully") 93 | completion(nil) 94 | } 95 | } 96 | } 97 | } 98 | 99 | func startVPN(completion: @escaping (Error?) -> Void) { 100 | print("VPNManager: Starting VPN...") 101 | waitForInitialization() 102 | guard let vpnManager = vpnManager else { 103 | print("VPNManager: VPN Manager not initialized") 104 | completion(NSError(domain: "VPNError", code: -1, userInfo: [NSLocalizedDescriptionKey: "VPN Manager not initialized"])) 105 | return 106 | } 107 | do { 108 | try vpnManager.connection.startVPNTunnel() 109 | print("VPNManager: VPN tunnel started successfully") 110 | completion(nil) 111 | } catch { 112 | print("VPNManager: Start VPN error: \(error)") 113 | completion(error) 114 | } 115 | } 116 | 117 | func stopVPN(completion: @escaping () -> Void) { 118 | print("VPNManager: Stopping VPN...") 119 | waitForInitialization() 120 | vpnManager?.connection.stopVPNTunnel() 121 | completion() 122 | } 123 | 124 | var vpnStatus: NEVPNStatus { 125 | let status = vpnManager?.connection.status ?? .invalid 126 | return status 127 | } 128 | } 129 | 130 | extension NEVPNStatus { 131 | var description: String { 132 | switch self { 133 | case .disconnected: return "Disconnected" 134 | case .connecting: return "Connecting..." 135 | case .connected: return "Connected" 136 | case .disconnecting: return "Disconnecting..." 137 | default: return "Not Added Profile" 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /cntrlr/cntrlr.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | relay 8 | dns-settings 9 | dns-proxy 10 | content-filter-provider 11 | packet-tunnel-provider 12 | app-proxy-provider 13 | 14 | com.apple.security.application-groups 15 | 16 | group.click.vpnclient 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /cntrlr/cntrlrApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // cntrlrApp.swift 3 | // cntrlr 4 | // 5 | // Created by Barista Newman on 14.03.2025. 6 | // 7 | 8 | import SwiftUI 9 | import SwiftData 10 | 11 | @main 12 | struct cntrlrApp: App { 13 | var body: some Scene { 14 | WindowGroup { 15 | ContentView() 16 | } 17 | } 18 | } 19 | --------------------------------------------------------------------------------