Clean code, comment
This commit is contained in:
parent
bfbcb64f46
commit
d4f9acdb94
6 changed files with 158 additions and 388 deletions
|
|
@ -8,14 +8,12 @@ set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION
|
||||||
|
|
||||||
|
|
||||||
enable_language(OBJC)
|
enable_language(OBJC)
|
||||||
# enable_language(OBJCXX)
|
|
||||||
enable_language(Swift)
|
enable_language(Swift)
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
|
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
|
||||||
set(LIBS ${LIBS} Qt6::ShaderTools)
|
set(LIBS ${LIBS} Qt6::ShaderTools)
|
||||||
|
|
||||||
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
||||||
#find_library(FW_UIKIT UIKit)
|
|
||||||
find_library(FW_AVFOUNDATION AVFoundation)
|
find_library(FW_AVFOUNDATION AVFoundation)
|
||||||
find_library(FW_FOUNDATION Foundation)
|
find_library(FW_FOUNDATION Foundation)
|
||||||
find_library(FW_STOREKIT StoreKit)
|
find_library(FW_STOREKIT StoreKit)
|
||||||
|
|
@ -24,7 +22,6 @@ find_library(FW_NETWORKEXTENSION NetworkExtension)
|
||||||
|
|
||||||
set(LIBS ${LIBS}
|
set(LIBS ${LIBS}
|
||||||
${FW_AUTHENTICATIONSERVICES}
|
${FW_AUTHENTICATIONSERVICES}
|
||||||
# ${FW_UIKIT}
|
|
||||||
${FW_AVFOUNDATION}
|
${FW_AVFOUNDATION}
|
||||||
${FW_FOUNDATION}
|
${FW_FOUNDATION}
|
||||||
${FW_STOREKIT}
|
${FW_STOREKIT}
|
||||||
|
|
@ -57,14 +54,6 @@ set(MACOSX_BUNDLE_ICON_FILE app.icns)
|
||||||
set_source_files_properties(${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
set_source_files_properties(${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||||
set(SOURCES ${SOURCES} ${ICON_FILE})
|
set(SOURCES ${SOURCES} ${ICON_FILE})
|
||||||
|
|
||||||
# set(HEADERS ${HEADERS}
|
|
||||||
# ${CMAKE_CURRENT_SOURCE_DIR}/ui/macos_util.h
|
|
||||||
# )
|
|
||||||
|
|
||||||
# set(SOURCES ${SOURCES}
|
|
||||||
# ${CMAKE_CURRENT_SOURCE_DIR}/ui/macos_util.mm
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
|
@ -72,7 +61,7 @@ target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||||
set_target_properties(${PROJECT} PROPERTIES
|
set_target_properties(${PROJECT} PROPERTIES
|
||||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Info.plist.in
|
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Info.plist.in
|
||||||
#MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||||
|
|
@ -86,7 +75,7 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
|
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||||
XCODE_GENERATE_SCHEME TRUE
|
XCODE_GENERATE_SCHEME TRUE
|
||||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
||||||
#XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||||
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY "NO"
|
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY "NO"
|
||||||
XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY "YES"
|
XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY "YES"
|
||||||
|
|
@ -96,14 +85,6 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||||
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||||
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
|
||||||
|
|
||||||
# XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
|
|
||||||
# XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
|
||||||
|
|
||||||
|
|
||||||
# XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN"
|
|
||||||
# XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "Mac AppStore AmneziaVPN"
|
|
||||||
|
|
||||||
)
|
)
|
||||||
set_target_properties(${PROJECT} PROPERTIES
|
set_target_properties(${PROJECT} PROPERTIES
|
||||||
|
|
@ -135,13 +116,11 @@ target_sources(${PROJECT} PRIVATE
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${PROJECT} PRIVATE
|
target_sources(${PROJECT} PRIVATE
|
||||||
#${CMAKE_CURRENT_SOURCE_DIR}/macos_ne/app/AmneziaVPNLaunchScreen.storyboard
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Media.xcassets
|
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Media.xcassets
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/PrivacyInfo.xcprivacy
|
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/PrivacyInfo.xcprivacy
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||||
#${CMAKE_CURRENT_SOURCE_DIR}/macos/app/AmneziaVPNLaunchScreen.storyboard
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Media.xcassets
|
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Media.xcassets
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/PrivacyInfo.xcprivacy
|
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/PrivacyInfo.xcprivacy
|
||||||
)
|
)
|
||||||
|
|
@ -149,33 +128,8 @@ set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||||
add_subdirectory(macos/networkextension)
|
add_subdirectory(macos/networkextension)
|
||||||
add_dependencies(${PROJECT} networkextension)
|
add_dependencies(${PROJECT} networkextension)
|
||||||
|
|
||||||
# set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
|
||||||
# "${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNAdapter.framework"
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos)
|
|
||||||
# target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNAdapter.framework")
|
|
||||||
|
|
||||||
get_target_property(QtCore_location Qt6::Core LOCATION)
|
get_target_property(QtCore_location Qt6::Core LOCATION)
|
||||||
message("QtCore_location")
|
message("QtCore_location")
|
||||||
message(${QtCore_location})
|
message(${QtCore_location})
|
||||||
|
|
||||||
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
|
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
|
||||||
|
|
||||||
|
|
||||||
# add_custom_command(TARGET ${PROJECT} POST_BUILD
|
|
||||||
# COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
# )
|
|
||||||
|
|
||||||
# if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
# SET(SIGN_CMD codesign --deep --force --sign 'Apple Distribution: Privacy Technologies OU \(X7UJ388FXK\)' --timestamp --options runtime $<TARGET_BUNDLE_DIR:AmneziaVPN>)
|
|
||||||
# message("Manual signing bundle...")
|
|
||||||
# message(${SIGN_CMD})
|
|
||||||
|
|
||||||
|
|
||||||
# add_custom_command(TARGET ${PROJECT} POST_BUILD
|
|
||||||
# COMMAND ${SIGN_CMD}
|
|
||||||
# )
|
|
||||||
# endif()
|
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@ target_sources(networkextension PRIVATE
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||||
|
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(networkextension PRIVATE
|
target_sources(networkextension PRIVATE
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# go/clangwrap_macos.sh
|
|
||||||
|
|
||||||
# Lấy đường dẫn SDK cho macOS
|
|
||||||
SDK_PATH=`xcrun --sdk macosx --show-sdk-path`
|
|
||||||
|
|
||||||
# Tìm đường dẫn đến `clang` cho macOS
|
|
||||||
CLANG=`xcrun --sdk macosx --find clang`
|
|
||||||
|
|
||||||
# Xác định kiến trúc máy dựa trên biến GOARCH
|
|
||||||
if [ "$GOARCH" == "amd64" ]; then
|
|
||||||
CARCH="x86_64"
|
|
||||||
elif [ "$GOARCH" == "arm64" ]; then
|
|
||||||
CARCH="arm64"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Thực thi `clang` với các tùy chọn cụ thể cho macOS
|
|
||||||
exec $CLANG -arch $CARCH -isysroot $SDK_PATH -mmacosx-version-min=10.15 "$@"
|
|
||||||
|
|
@ -1,353 +1,187 @@
|
||||||
//import Foundation
|
|
||||||
//import NetworkExtension
|
|
||||||
//import WireGuardKitGo
|
|
||||||
//
|
|
||||||
//enum XrayErrors: Error {
|
|
||||||
// case noXrayConfig
|
|
||||||
// case xrayConfigIsWrong
|
|
||||||
// case cantSaveXrayConfig
|
|
||||||
// case cantParseListenAndPort
|
|
||||||
// case cantSaveHevSocksConfig
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//extension Constants {
|
|
||||||
// static let cachesDirectory: URL = {
|
|
||||||
// if let cachesDirectoryURL = FileManager.default.urls(for: .cachesDirectory,
|
|
||||||
// in: .userDomainMask).first {
|
|
||||||
// return cachesDirectoryURL
|
|
||||||
// } else {
|
|
||||||
// fatalError("Unable to retrieve caches directory.")
|
|
||||||
// }
|
|
||||||
// }()
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//extension PacketTunnelProvider {
|
|
||||||
// func startXray(completionHandler: @escaping (Error?) -> Void) {
|
|
||||||
//
|
|
||||||
// // Xray configuration
|
|
||||||
// guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
|
||||||
// let providerConfiguration = protocolConfiguration.providerConfiguration,
|
|
||||||
// let configData = providerConfiguration[Constants.xrayConfigKey] as? Data else {
|
|
||||||
// xrayLog(.error, message: "Can't get xray configuration")
|
|
||||||
// completionHandler(XrayErrors.noXrayConfig)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Tunnel settings
|
|
||||||
// let ipv6Enabled = false
|
|
||||||
// let hideVPNIcon = false
|
|
||||||
//
|
|
||||||
// let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "254.1.1.1")
|
|
||||||
// settings.mtu = 9000
|
|
||||||
//
|
|
||||||
// settings.ipv4Settings = {
|
|
||||||
// let settings = NEIPv4Settings(addresses: ["198.18.0.1"], subnetMasks: ["255.255.0.0"])
|
|
||||||
// settings.includedRoutes = [NEIPv4Route.default()]
|
|
||||||
// return settings
|
|
||||||
// }()
|
|
||||||
//
|
|
||||||
// settings.ipv6Settings = {
|
|
||||||
// guard ipv6Enabled else {
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
// let settings = NEIPv6Settings(addresses: ["fd6e:a81b:704f:1211::1"], networkPrefixLengths: [64])
|
|
||||||
// settings.includedRoutes = [NEIPv6Route.default()]
|
|
||||||
// if hideVPNIcon {
|
|
||||||
// settings.excludedRoutes = [NEIPv6Route(destinationAddress: "::", networkPrefixLength: 128)]
|
|
||||||
// }
|
|
||||||
// return settings
|
|
||||||
// }()
|
|
||||||
//
|
|
||||||
// do {
|
|
||||||
// let xrayConfig = try JSONDecoder().decode(XrayConfig.self,
|
|
||||||
// from: configData)
|
|
||||||
//
|
|
||||||
// var dnsArray = [String]()
|
|
||||||
// if let dns1 = xrayConfig.dns1 {
|
|
||||||
// dnsArray.append(dns1)
|
|
||||||
// }
|
|
||||||
// if let dns2 = xrayConfig.dns2 {
|
|
||||||
// dnsArray.append(dns2)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// settings.dnsSettings = !dnsArray.isEmpty
|
|
||||||
// ? NEDNSSettings(servers: dnsArray)
|
|
||||||
// : NEDNSSettings(servers: ["1.1.1.1"])
|
|
||||||
//
|
|
||||||
// let xrayConfigData = xrayConfig.config.data(using: .utf8)
|
|
||||||
//
|
|
||||||
// guard let xrayConfigData else {
|
|
||||||
// xrayLog(.error, message: "Can't encode config to data")
|
|
||||||
// completionHandler(XrayErrors.xrayConfigIsWrong)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let jsonDict = try JSONSerialization.jsonObject(with: xrayConfigData,
|
|
||||||
// options: []) as? [String: Any]
|
|
||||||
//
|
|
||||||
// guard var jsonDict else {
|
|
||||||
// xrayLog(.error, message: "Can't parse address and port for hevSocks")
|
|
||||||
// completionHandler(XrayErrors.cantParseListenAndPort)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let port = 10808
|
|
||||||
// let address = "::1"
|
|
||||||
//
|
|
||||||
// if var inboundsArray = jsonDict["inbounds"] as? [[String: Any]], !inboundsArray.isEmpty {
|
|
||||||
// inboundsArray[0]["port"] = port
|
|
||||||
// inboundsArray[0]["listen"] = address
|
|
||||||
// jsonDict["inbounds"] = inboundsArray
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let updatedData = try JSONSerialization.data(withJSONObject: jsonDict, options: [])
|
|
||||||
//
|
|
||||||
// setTunnelNetworkSettings(settings) { [weak self] error in
|
|
||||||
// if let error {
|
|
||||||
// completionHandler(error)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Launch xray
|
|
||||||
// self?.setupAndStartXray(configData: updatedData) { xrayError in
|
|
||||||
// if let xrayError {
|
|
||||||
// completionHandler(xrayError)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Launch hevSocks
|
|
||||||
// self?.setupAndRunTun2socks(configData: updatedData,
|
|
||||||
// address: address,
|
|
||||||
// port: port,
|
|
||||||
// completionHandler: completionHandler)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } catch {
|
|
||||||
// completionHandler(error)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func stopXray(completionHandler: () -> Void) {
|
|
||||||
// Socks5Tunnel.quit()
|
|
||||||
// LibXrayStopXray()
|
|
||||||
// completionHandler()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private func setupAndStartXray(configData: Data,
|
|
||||||
// completionHandler: @escaping (Error?) -> Void) {
|
|
||||||
// let path = Constants.cachesDirectory.appendingPathComponent("config.json", isDirectory: false).path
|
|
||||||
// guard FileManager.default.createFile(atPath: path, contents: configData) else {
|
|
||||||
// xrayLog(.error, message: "Can't save xray configuration")
|
|
||||||
// completionHandler(XrayErrors.cantSaveXrayConfig)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// LibXrayRunXray(nil,
|
|
||||||
// path,
|
|
||||||
// Int64.max)
|
|
||||||
//
|
|
||||||
// completionHandler(nil)
|
|
||||||
// xrayLog(.info, message: "Xray started")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private func setupAndRunTun2socks(configData: Data,
|
|
||||||
// address: String,
|
|
||||||
// port: Int,
|
|
||||||
// completionHandler: @escaping (Error?) -> Void) {
|
|
||||||
// let config = """
|
|
||||||
// tunnel:
|
|
||||||
// mtu: 9000
|
|
||||||
// socks5:
|
|
||||||
// port: \(port)
|
|
||||||
// address: \(address)
|
|
||||||
// udp: 'udp'
|
|
||||||
// misc:
|
|
||||||
// task-stack-size: 20480
|
|
||||||
// connect-timeout: 5000
|
|
||||||
// read-write-timeout: 60000
|
|
||||||
// log-file: stderr
|
|
||||||
// log-level: error
|
|
||||||
// limit-nofile: 65535
|
|
||||||
// """
|
|
||||||
//
|
|
||||||
// let configurationFilePath = Constants.cachesDirectory.appendingPathComponent("config.yml", isDirectory: false).path
|
|
||||||
// guard FileManager.default.createFile(atPath: configurationFilePath, contents: config.data(using: .utf8)!) else {
|
|
||||||
// xrayLog(.info, message: "Cant save hevSocks configuration")
|
|
||||||
// completionHandler(XrayErrors.cantSaveHevSocksConfig)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// DispatchQueue.global().async {
|
|
||||||
// xrayLog(.info, message: "Hev socks started")
|
|
||||||
// completionHandler(nil)
|
|
||||||
// Socks5Tunnel.run(withConfig: configurationFilePath)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
import WireGuardKitGo
|
import WireGuardKitGo
|
||||||
|
|
||||||
enum XrayErrors: Error {
|
enum XrayErrors: Error {
|
||||||
case noXrayConfig
|
case noXrayConfig
|
||||||
case cantSaveXrayConfig
|
case xrayConfigIsWrong
|
||||||
case cantParseListenAndPort
|
case cantSaveXrayConfig
|
||||||
case cantSaveHevSocksConfig
|
case cantParseListenAndPort
|
||||||
|
case cantSaveHevSocksConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Constants {
|
extension Constants {
|
||||||
static let cachesDirectory: URL = {
|
static let cachesDirectory: URL = {
|
||||||
if let cachesDirectoryURL = FileManager.default.urls(for: .cachesDirectory,
|
if let cachesDirectoryURL = FileManager.default.urls(for: .cachesDirectory,
|
||||||
in: .userDomainMask).first {
|
in: .userDomainMask).first {
|
||||||
return cachesDirectoryURL
|
return cachesDirectoryURL
|
||||||
} else {
|
} else {
|
||||||
fatalError("Unable to retrieve caches directory.")
|
fatalError("Unable to retrieve caches directory.")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
extension PacketTunnelProvider {
|
extension PacketTunnelProvider {
|
||||||
func startXray(completionHandler: @escaping (Error?) -> Void) {
|
func startXray(completionHandler: @escaping (Error?) -> Void) {
|
||||||
|
|
||||||
// Xray configuration
|
// Xray configuration
|
||||||
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
||||||
let providerConfiguration = protocolConfiguration.providerConfiguration,
|
let providerConfiguration = protocolConfiguration.providerConfiguration,
|
||||||
let xrayConfigData = providerConfiguration[Constants.xrayConfigKey] as? Data else {
|
let configData = providerConfiguration[Constants.xrayConfigKey] as? Data else {
|
||||||
xrayLog(.error, message: "Can't get xray configuration")
|
xrayLog(.error, message: "Can't get xray configuration")
|
||||||
completionHandler(XrayErrors.noXrayConfig)
|
completionHandler(XrayErrors.noXrayConfig)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tunnel settings
|
// Tunnel settings
|
||||||
let ipv6Enabled = true
|
let ipv6Enabled = false
|
||||||
let hideVPNIcon = false
|
let hideVPNIcon = false
|
||||||
|
|
||||||
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "254.1.1.1")
|
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "254.1.1.1")
|
||||||
settings.mtu = 9000
|
settings.mtu = 9000
|
||||||
|
|
||||||
settings.ipv4Settings = {
|
settings.ipv4Settings = {
|
||||||
let settings = NEIPv4Settings(addresses: ["198.18.0.1"], subnetMasks: ["255.255.0.0"])
|
let settings = NEIPv4Settings(addresses: ["198.18.0.1"], subnetMasks: ["255.255.0.0"])
|
||||||
settings.includedRoutes = [NEIPv4Route.default()]
|
settings.includedRoutes = [NEIPv4Route.default()]
|
||||||
return settings
|
return settings
|
||||||
}()
|
}()
|
||||||
|
|
||||||
settings.ipv6Settings = {
|
settings.ipv6Settings = {
|
||||||
guard ipv6Enabled else {
|
guard ipv6Enabled else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let settings = NEIPv6Settings(addresses: ["fd6e:a81b:704f:1211::1"], networkPrefixLengths: [64])
|
let settings = NEIPv6Settings(addresses: ["fd6e:a81b:704f:1211::1"], networkPrefixLengths: [64])
|
||||||
settings.includedRoutes = [NEIPv6Route.default()]
|
settings.includedRoutes = [NEIPv6Route.default()]
|
||||||
if hideVPNIcon {
|
if hideVPNIcon {
|
||||||
settings.excludedRoutes = [NEIPv6Route(destinationAddress: "::", networkPrefixLength: 128)]
|
settings.excludedRoutes = [NEIPv6Route(destinationAddress: "::", networkPrefixLength: 128)]
|
||||||
}
|
}
|
||||||
return settings
|
return settings
|
||||||
}()
|
}()
|
||||||
|
|
||||||
let dns = ["8.8.4.4","1.1.1.1"]
|
do {
|
||||||
settings.dnsSettings = NEDNSSettings(servers: dns)
|
let xrayConfig = try JSONDecoder().decode(XrayConfig.self,
|
||||||
|
from: configData)
|
||||||
|
|
||||||
do {
|
var dnsArray = [String]()
|
||||||
let port = 10808
|
if let dns1 = xrayConfig.dns1 {
|
||||||
let address = "::1"
|
dnsArray.append(dns1)
|
||||||
|
}
|
||||||
|
if let dns2 = xrayConfig.dns2 {
|
||||||
|
dnsArray.append(dns2)
|
||||||
|
}
|
||||||
|
|
||||||
let jsonDict = try JSONSerialization.jsonObject(with: xrayConfigData,
|
settings.dnsSettings = !dnsArray.isEmpty
|
||||||
options: []) as? [String: Any]
|
? NEDNSSettings(servers: dnsArray)
|
||||||
|
: NEDNSSettings(servers: ["1.1.1.1"])
|
||||||
|
|
||||||
guard var jsonDict else {
|
let xrayConfigData = xrayConfig.config.data(using: .utf8)
|
||||||
xrayLog(.error, message: "Can't parse address and port for hevSocks")
|
|
||||||
completionHandler(XrayErrors.cantParseListenAndPort)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if var inboundsArray = jsonDict["inbounds"] as? [[String: Any]], !inboundsArray.isEmpty {
|
guard let xrayConfigData else {
|
||||||
inboundsArray[0]["port"] = port
|
xrayLog(.error, message: "Can't encode config to data")
|
||||||
inboundsArray[0]["listen"] = address
|
completionHandler(XrayErrors.xrayConfigIsWrong)
|
||||||
jsonDict["inbounds"] = inboundsArray
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let updatedData = try JSONSerialization.data(withJSONObject: jsonDict, options: [])
|
let jsonDict = try JSONSerialization.jsonObject(with: xrayConfigData,
|
||||||
|
options: []) as? [String: Any]
|
||||||
|
|
||||||
setTunnelNetworkSettings(settings) { [weak self] error in
|
guard var jsonDict else {
|
||||||
if let error {
|
xrayLog(.error, message: "Can't parse address and port for hevSocks")
|
||||||
completionHandler(error)
|
completionHandler(XrayErrors.cantParseListenAndPort)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Launch xray
|
let port = 10808
|
||||||
self?.setupAndStartXray(configData: updatedData) { xrayError in
|
let address = "::1"
|
||||||
if let xrayError {
|
|
||||||
completionHandler(xrayError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Launch hevSocks
|
if var inboundsArray = jsonDict["inbounds"] as? [[String: Any]], !inboundsArray.isEmpty {
|
||||||
self?.setupAndRunTun2socks(configData: updatedData,
|
inboundsArray[0]["port"] = port
|
||||||
address: address,
|
inboundsArray[0]["listen"] = address
|
||||||
port: port,
|
jsonDict["inbounds"] = inboundsArray
|
||||||
completionHandler: completionHandler)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
completionHandler(error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func stopXray(completionHandler: () -> Void) {
|
let updatedData = try JSONSerialization.data(withJSONObject: jsonDict, options: [])
|
||||||
Socks5Tunnel.quit()
|
|
||||||
LibXrayStopXray()
|
|
||||||
completionHandler()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setupAndStartXray(configData: Data,
|
setTunnelNetworkSettings(settings) { [weak self] error in
|
||||||
completionHandler: @escaping (Error?) -> Void) {
|
if let error {
|
||||||
let path = Constants.cachesDirectory.appendingPathComponent("config.json", isDirectory: false).path
|
completionHandler(error)
|
||||||
guard FileManager.default.createFile(atPath: path, contents: configData) else {
|
return
|
||||||
xrayLog(.error, message: "Can't save xray configuration")
|
}
|
||||||
completionHandler(XrayErrors.cantSaveXrayConfig)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
LibXrayRunXray(nil,
|
// Launch xray
|
||||||
path,
|
self?.setupAndStartXray(configData: updatedData) { xrayError in
|
||||||
Int64.max)
|
if let xrayError {
|
||||||
|
completionHandler(xrayError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
completionHandler(nil)
|
// Launch hevSocks
|
||||||
xrayLog(.info, message: "Xray started")
|
self?.setupAndRunTun2socks(configData: updatedData,
|
||||||
}
|
address: address,
|
||||||
|
port: port,
|
||||||
|
completionHandler: completionHandler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
completionHandler(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func setupAndRunTun2socks(configData: Data,
|
func stopXray(completionHandler: () -> Void) {
|
||||||
address: String,
|
Socks5Tunnel.quit()
|
||||||
port: Int,
|
LibXrayStopXray()
|
||||||
completionHandler: @escaping (Error?) -> Void) {
|
completionHandler()
|
||||||
let config = """
|
}
|
||||||
tunnel:
|
|
||||||
mtu: 9000
|
|
||||||
socks5:
|
|
||||||
port: \(port)
|
|
||||||
address: \(address)
|
|
||||||
udp: 'udp'
|
|
||||||
misc:
|
|
||||||
task-stack-size: 20480
|
|
||||||
connect-timeout: 5000
|
|
||||||
read-write-timeout: 60000
|
|
||||||
log-file: stderr
|
|
||||||
log-level: error
|
|
||||||
limit-nofile: 65535
|
|
||||||
"""
|
|
||||||
|
|
||||||
let configurationFilePath = Constants.cachesDirectory.appendingPathComponent("config.yml", isDirectory: false).path
|
private func setupAndStartXray(configData: Data,
|
||||||
guard FileManager.default.createFile(atPath: configurationFilePath, contents: config.data(using: .utf8)!) else {
|
completionHandler: @escaping (Error?) -> Void) {
|
||||||
xrayLog(.info, message: "Cant save hevSocks configuration")
|
let path = Constants.cachesDirectory.appendingPathComponent("config.json", isDirectory: false).path
|
||||||
completionHandler(XrayErrors.cantSaveHevSocksConfig)
|
guard FileManager.default.createFile(atPath: path, contents: configData) else {
|
||||||
return
|
xrayLog(.error, message: "Can't save xray configuration")
|
||||||
}
|
completionHandler(XrayErrors.cantSaveXrayConfig)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
DispatchQueue.global().async {
|
LibXrayRunXray(nil,
|
||||||
xrayLog(.info, message: "Hev socks started")
|
path,
|
||||||
completionHandler(nil)
|
Int64.max)
|
||||||
Socks5Tunnel.run(withConfig: configurationFilePath)
|
|
||||||
}
|
completionHandler(nil)
|
||||||
}
|
xrayLog(.info, message: "Xray started")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func setupAndRunTun2socks(configData: Data,
|
||||||
|
address: String,
|
||||||
|
port: Int,
|
||||||
|
completionHandler: @escaping (Error?) -> Void) {
|
||||||
|
let config = """
|
||||||
|
tunnel:
|
||||||
|
mtu: 9000
|
||||||
|
socks5:
|
||||||
|
port: \(port)
|
||||||
|
address: \(address)
|
||||||
|
udp: 'udp'
|
||||||
|
misc:
|
||||||
|
task-stack-size: 20480
|
||||||
|
connect-timeout: 5000
|
||||||
|
read-write-timeout: 60000
|
||||||
|
log-file: stderr
|
||||||
|
log-level: error
|
||||||
|
limit-nofile: 65535
|
||||||
|
"""
|
||||||
|
|
||||||
|
let configurationFilePath = Constants.cachesDirectory.appendingPathComponent("config.yml", isDirectory: false).path
|
||||||
|
guard FileManager.default.createFile(atPath: configurationFilePath, contents: config.data(using: .utf8)!) else {
|
||||||
|
xrayLog(.info, message: "Cant save hevSocks configuration")
|
||||||
|
completionHandler(XrayErrors.cantSaveHevSocksConfig)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DispatchQueue.global().async {
|
||||||
|
xrayLog(.info, message: "Hev socks started")
|
||||||
|
completionHandler(nil)
|
||||||
|
Socks5Tunnel.run(withConfig: configurationFilePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue