feat: add Apple TV support for network extension and refactor ios cmake scripts

This commit is contained in:
spectrum
2026-02-13 16:51:44 +02:00
parent 528015d17e
commit 495d59da07
4 changed files with 130 additions and 29 deletions
+1 -1
View File
@@ -40,6 +40,6 @@ while(IOS_TARGETS)
XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64" XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64"
XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64" XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64"
XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64" XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64"
XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "arm64 x86_64" XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "arm64"
) )
endwhile() endwhile()
+8 -1
View File
@@ -4,6 +4,7 @@ set(AMNEZIA_IOS_APPLETV ${AMNEZIA_IOS_ENABLE_APPLETV_TARGET})
if(AMNEZIA_IOS_APPLETV) if(AMNEZIA_IOS_APPLETV)
message("Apple TV target mode is ON") message("Apple TV target mode is ON")
set(CMAKE_OSX_DEPLOYMENT_TARGET 17.0)
set(QT_NO_SET_DEFAULT_IOS_LAUNCH_SCREEN TRUE) set(QT_NO_SET_DEFAULT_IOS_LAUNCH_SCREEN TRUE)
set(QT_NO_ADD_IOS_LAUNCH_SCREEN_TO_BUNDLE TRUE) set(QT_NO_ADD_IOS_LAUNCH_SCREEN_TO_BUNDLE TRUE)
else() else()
@@ -88,6 +89,7 @@ set_target_properties(${PROJECT} PROPERTIES
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks" XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
XCODE_EMBED_APP_EXTENSIONS networkextension
) )
if(AMNEZIA_IOS_APPLETV) if(AMNEZIA_IOS_APPLETV)
@@ -95,12 +97,17 @@ if(AMNEZIA_IOS_APPLETV)
XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "appletvos appletvsimulator" XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "appletvos appletvsimulator"
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "3" XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "3"
XCODE_ATTRIBUTE_TVOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}" XCODE_ATTRIBUTE_TVOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}"
XCODE_ATTRIBUTE_SDKROOT "appletvos"
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvos*] "appletvos"
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvsimulator*] "appletvsimulator"
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvos*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvsimulator*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
) )
else() else()
set_target_properties(${PROJECT} PROPERTIES set_target_properties(${PROJECT} PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements" XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2" XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
XCODE_EMBED_APP_EXTENSIONS networkextension
) )
endif() endif()
+57 -19
View File
@@ -1,6 +1,13 @@
enable_language(Swift) enable_language(Swift)
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
set(AMNEZIA_IOS_APPLETV ${AMNEZIA_IOS_ENABLE_APPLETV_TARGET})
if(AMNEZIA_IOS_APPLETV)
message("Network Extension tvOS mode is ON")
else()
message("Network Extension tvOS mode is OFF")
endif()
add_executable(networkextension) add_executable(networkextension)
set_target_properties(networkextension PROPERTIES set_target_properties(networkextension PROPERTIES
@@ -28,6 +35,23 @@ set_target_properties(networkextension PROPERTIES
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks" XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks"
) )
if(AMNEZIA_IOS_APPLETV)
set_target_properties(networkextension PROPERTIES
XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "appletvos appletvsimulator"
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "3"
XCODE_ATTRIBUTE_TVOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}"
XCODE_ATTRIBUTE_SDKROOT "appletvos"
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvos*] "appletvos"
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvsimulator*] "appletvsimulator"
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvos*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvsimulator*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
XCODE_ATTRIBUTE_EXCLUDED_LIBRARY_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/usr/lib/swift"
XCODE_ATTRIBUTE_EXCLUDED_FRAMEWORK_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/System/Library/Frameworks"
LINKER_LANGUAGE Swift
)
endif()
if(DEPLOY) if(DEPLOY)
set_target_properties(networkextension PROPERTIES set_target_properties(networkextension PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution" XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
@@ -45,38 +69,49 @@ endif()
set_target_properties(networkextension PROPERTIES set_target_properties(networkextension PROPERTIES
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0" XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES" XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone" XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone"
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO" XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
) )
if(NOT AMNEZIA_IOS_APPLETV)
set_target_properties(networkextension PROPERTIES
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
)
endif()
set_target_properties("networkextension" PROPERTIES set_target_properties("networkextension" PROPERTIES
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK" XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
) )
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
find_library(FW_MOBILE_CORE MobileCoreServices)
find_library(FW_UI_KIT UIKit) find_library(FW_UI_KIT UIKit)
find_library(FW_LIBRESOLV libresolv.9.tbd) find_library(FW_LIBRESOLV libresolv.9.tbd)
target_link_libraries(networkextension PRIVATE ${FW_ASSETS_LIBRARY}) if(NOT AMNEZIA_IOS_APPLETV)
target_link_libraries(networkextension PRIVATE ${FW_MOBILE_CORE}) target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
target_link_libraries(networkextension PRIVATE ${FW_UI_KIT}) target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV}) endif()
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\") target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1) target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources) set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
target_sources(networkextension PRIVATE set(NE_COMMON_SOURCES
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
)
set(NE_FULL_BACKEND_SOURCES
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
${WG_APPLE_SOURCE_DIR}/WireGuardNetworkExtension/ErrorNotifier.swift ${WG_APPLE_SOURCE_DIR}/WireGuardNetworkExtension/ErrorNotifier.swift
${WG_APPLE_SOURCE_DIR}/Shared/Keychain.swift ${WG_APPLE_SOURCE_DIR}/Shared/Keychain.swift
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift ${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
${WG_APPLE_SOURCE_DIR}/Shared/Model/NETunnelProviderProtocol+Extension.swift ${WG_APPLE_SOURCE_DIR}/Shared/Model/NETunnelProviderProtocol+Extension.swift
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
${WG_APPLE_SOURCE_DIR}/Shared/Model/String+ArrayConversion.swift ${WG_APPLE_SOURCE_DIR}/Shared/Model/String+ArrayConversion.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/TunnelConfiguration.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/TunnelConfiguration.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddressRange.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddressRange.swift
@@ -84,16 +119,11 @@ target_sources(networkextension PRIVATE
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSServer.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSServer.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/InterfaceConfiguration.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/InterfaceConfiguration.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PeerConfiguration.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/PeerConfiguration.swift
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c ${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift ${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift ${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift ${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift ${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift ${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
@@ -102,6 +132,12 @@ target_sources(networkextension PRIVATE
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm ${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
) )
target_sources(networkextension PRIVATE ${NE_COMMON_SOURCES})
if(NOT AMNEZIA_IOS_APPLETV)
target_sources(networkextension PRIVATE ${NE_FULL_BACKEND_SOURCES})
endif()
target_sources(networkextension PRIVATE target_sources(networkextension PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy ${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
) )
@@ -113,11 +149,13 @@ set_property(TARGET networkextension APPEND PROPERTY RESOURCE
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR}) target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
find_package(openvpnadapter REQUIRED)
target_link_libraries(networkextension PRIVATE amnezia::openvpnadapter)
find_package(awg-apple REQUIRED) find_package(awg-apple REQUIRED)
target_link_libraries(networkextension PRIVATE amnezia::awg-apple) target_link_libraries(networkextension PRIVATE amnezia::awg-apple)
find_package(hev-socks5-tunnel REQUIRED) if(NOT AMNEZIA_IOS_APPLETV)
target_link_libraries(networkextension PRIVATE heiher::hev-socks5-tunnel) find_package(openvpnadapter REQUIRED)
target_link_libraries(networkextension PRIVATE amnezia::openvpnadapter)
find_package(hev-socks5-tunnel REQUIRED)
target_link_libraries(networkextension PRIVATE heiher::hev-socks5-tunnel)
endif()
@@ -3,7 +3,9 @@ import NetworkExtension
import Network import Network
import os import os
import Darwin import Darwin
#if !os(tvOS)
import OpenVPNAdapter import OpenVPNAdapter
#endif
enum TunnelProtoType: String { enum TunnelProtoType: String {
case wireguard, openvpn, xray case wireguard, openvpn, xray
@@ -37,9 +39,11 @@ struct Constants {
} }
class PacketTunnelProvider: NEPacketTunnelProvider { class PacketTunnelProvider: NEPacketTunnelProvider {
#if !os(tvOS)
var wgAdapter: WireGuardAdapter? var wgAdapter: WireGuardAdapter?
var ovpnAdapter: OpenVPNAdapter? var ovpnAdapter: OpenVPNAdapter?
private lazy var openVPNPacketFlowAdapter = PacketTunnelFlowAdapter(flow: packetFlow) private lazy var openVPNPacketFlowAdapter = PacketTunnelFlowAdapter(flow: packetFlow)
#endif
private let pathMonitorQueue = DispatchQueue(label: Constants.processQueueName + ".path-monitor") private let pathMonitorQueue = DispatchQueue(label: Constants.processQueueName + ".path-monitor")
private let pathMonitor = NWPathMonitor() private let pathMonitor = NWPathMonitor()
private var didReceiveInitialPathUpdate = false private var didReceiveInitialPathUpdate = false
@@ -49,7 +53,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
var splitTunnelType: Int? var splitTunnelType: Int?
var splitTunnelSites: [String]? var splitTunnelSites: [String]?
#if !os(tvOS)
let vpnReachability = OpenVPNReachability() let vpnReachability = OpenVPNReachability()
#endif
var startHandler: ((Error?) -> Void)? var startHandler: ((Error?) -> Void)?
var stopHandler: (() -> Void)? var stopHandler: (() -> Void)?
@@ -57,9 +63,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
var activeIfaceIdx: UInt32 = 0 var activeIfaceIdx: UInt32 = 0
#if !os(tvOS)
func openVPNPacketFlow() -> OpenVPNAdapterPacketFlow { func openVPNPacketFlow() -> OpenVPNAdapterPacketFlow {
openVPNPacketFlowAdapter openVPNPacketFlowAdapter
} }
#endif
override init() { override init() {
super.init() super.init()
@@ -130,11 +138,15 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) { override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
if messageData.count == 1 && messageData[0] == 0 { if messageData.count == 1 && messageData[0] == 0 {
guard let completionHandler else { return } guard let completionHandler else { return }
#if !os(tvOS)
if protoType == .wireguard { if protoType == .wireguard {
handleWireguardAppMessage(messageData, completionHandler: completionHandler) handleWireguardAppMessage(messageData, completionHandler: completionHandler)
} else { } else {
completionHandler(nil) completionHandler(nil)
} }
#else
completionHandler(nil)
#endif
return return
} }
@@ -148,10 +160,12 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
neLog(.info, title: "App said: ", message: message) neLog(.info, title: "App said: ", message: message)
guard let message = try? JSONSerialization.jsonObject(with: messageData, options: []) as? [String: Any] else { guard let message = try? JSONSerialization.jsonObject(with: messageData, options: []) as? [String: Any] else {
#if !os(tvOS)
if protoType == .wireguard { if protoType == .wireguard {
handleWireguardAppMessage(messageData, completionHandler: completionHandler) handleWireguardAppMessage(messageData, completionHandler: completionHandler)
return return
} }
#endif
neLog(.error, message: "Failed to serialize message from app") neLog(.error, message: "Failed to serialize message from app")
return return
} }
@@ -176,7 +190,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
override func startTunnel(options: [String : NSObject]? = nil, override func startTunnel(options: [String : NSObject]? = nil,
completionHandler: @escaping ((any Error)?) -> Void) { completionHandler: @escaping ((any Error)?) -> Void) {
let activationAttemptId = options?[Constants.kActivationAttemptId] as? String let activationAttemptId = options?[Constants.kActivationAttemptId] as? String
#if !os(tvOS)
let errorNotifier = ErrorNotifier(activationAttemptId: activationAttemptId) let errorNotifier = ErrorNotifier(activationAttemptId: activationAttemptId)
#endif
neLog(.info, message: "Start tunnel") neLog(.info, message: "Start tunnel")
@@ -202,13 +218,31 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
switch protoType { switch protoType {
case .wireguard: case .wireguard:
#if os(tvOS)
completionHandler(NSError(domain: "org.amnezia.ne",
code: -1001,
userInfo: [NSLocalizedDescriptionKey: "WireGuard backend is not available for tvOS in this build"]))
#else
startWireguard(activationAttemptId: activationAttemptId, startWireguard(activationAttemptId: activationAttemptId,
errorNotifier: errorNotifier, errorNotifier: errorNotifier,
completionHandler: completionHandler) completionHandler: completionHandler)
#endif
case .openvpn: case .openvpn:
#if os(tvOS)
completionHandler(NSError(domain: "org.amnezia.ne",
code: -1002,
userInfo: [NSLocalizedDescriptionKey: "OpenVPN backend is not available for tvOS in this build"]))
#else
startOpenVPN(completionHandler: completionHandler) startOpenVPN(completionHandler: completionHandler)
#endif
case .xray: case .xray:
#if os(tvOS)
completionHandler(NSError(domain: "org.amnezia.ne",
code: -1003,
userInfo: [NSLocalizedDescriptionKey: "Xray backend is not available for tvOS in this build"]))
#else
startXray(completionHandler: completionHandler) startXray(completionHandler: completionHandler)
#endif
} }
} }
@@ -222,13 +256,25 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
switch protoType { switch protoType {
case .wireguard: case .wireguard:
#if os(tvOS)
completionHandler()
#else
stopWireguard(with: reason, stopWireguard(with: reason,
completionHandler: completionHandler) completionHandler: completionHandler)
#endif
case .openvpn: case .openvpn:
#if os(tvOS)
completionHandler()
#else
stopOpenVPN(with: reason, stopOpenVPN(with: reason,
completionHandler: completionHandler) completionHandler: completionHandler)
#endif
case .xray: case .xray:
#if os(tvOS)
completionHandler()
#else
stopXray(completionHandler: completionHandler) stopXray(completionHandler: completionHandler)
#endif
} }
} }
@@ -240,9 +286,17 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
switch protoType { switch protoType {
case .wireguard: case .wireguard:
#if !os(tvOS)
handleWireguardStatusMessage(messageData, completionHandler: completionHandler) handleWireguardStatusMessage(messageData, completionHandler: completionHandler)
#else
completionHandler?(nil)
#endif
case .openvpn: case .openvpn:
#if !os(tvOS)
handleOpenVPNStatusMessage(messageData, completionHandler: completionHandler) handleOpenVPNStatusMessage(messageData, completionHandler: completionHandler)
#else
completionHandler?(nil)
#endif
case .xray: case .xray:
break; break;
} }
@@ -260,7 +314,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
private func handle(networkChange changePath: Network.NWPath, completion: @escaping (Error?) -> Void) { private func handle(networkChange changePath: Network.NWPath, completion: @escaping (Error?) -> Void) {
updateActiveInterfaceIndex(for: changePath) updateActiveInterfaceIndex(for: changePath)
wg_log(.info, message: "Tunnel restarted.") neLog(.info, message: "Tunnel restarted.")
startTunnel(options: nil, completionHandler: completion) startTunnel(options: nil, completionHandler: completion)
} }
} }
@@ -310,15 +364,16 @@ private extension PacketTunnelProvider {
} }
} }
#if !os(tvOS)
extension WireGuardLogLevel { extension WireGuardLogLevel {
var osLogLevel: OSLogType { var osLogLevel: OSLogType {
switch self { switch self {
case .verbose: case .verbose:
return .debug return .debug
case .error: case .error:
return .error return .error
}
} }
}
} }
final class PacketTunnelFlowAdapter: NSObject, OpenVPNAdapterPacketFlow { final class PacketTunnelFlowAdapter: NSObject, OpenVPNAdapterPacketFlow {
@@ -339,6 +394,7 @@ final class PacketTunnelFlowAdapter: NSObject, OpenVPNAdapterPacketFlow {
flow.writePackets(packets, withProtocols: protocols) flow.writePackets(packets, withProtocols: protocols)
} }
} }
#endif
extension NEProviderStopReason { extension NEProviderStopReason {
var amneziaDescription: String { var amneziaDescription: String {