fix views
This commit is contained in:
parent
ed45954127
commit
1e74de12aa
75
Tun/NetworkInterface.swift
Normal file
75
Tun/NetworkInterface.swift
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// NetworkInterface.swift
|
||||
// punchnet
|
||||
//
|
||||
// Created by 安礼成 on 2025/8/3.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// NetworkInterface.swift
|
||||
// Tun
|
||||
//
|
||||
// Created by 安礼成 on 2024/1/19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct NetworkInterface {
|
||||
public let name: String
|
||||
public let ip: String
|
||||
public let netmask: String
|
||||
}
|
||||
|
||||
public struct NetworkInterfaceManager {
|
||||
/**
|
||||
获取网卡信息, (let name: String let ip: String let netmask: String)
|
||||
*/
|
||||
public static func getInterfaces() -> [NetworkInterface] {
|
||||
var interfaces: [NetworkInterface] = []
|
||||
|
||||
// Get list of all interfaces on the local machine:
|
||||
var ifaddr : UnsafeMutablePointer<ifaddrs>? = nil
|
||||
if getifaddrs(&ifaddr) == 0 {
|
||||
|
||||
// For each interface ...
|
||||
var ptr = ifaddr
|
||||
while( ptr != nil) {
|
||||
|
||||
let flags = Int32(ptr!.pointee.ifa_flags)
|
||||
var addr = ptr!.pointee.ifa_addr.pointee
|
||||
|
||||
// Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
|
||||
if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
|
||||
if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
|
||||
|
||||
var mask = ptr!.pointee.ifa_netmask.pointee
|
||||
|
||||
// Convert interface address to a human readable string:
|
||||
let zero = CChar(0)
|
||||
var hostname = [CChar](repeating: zero, count: Int(NI_MAXHOST))
|
||||
var netmask = [CChar](repeating: zero, count: Int(NI_MAXHOST))
|
||||
if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count),
|
||||
nil, socklen_t(0), NI_NUMERICHOST) == 0) {
|
||||
let address = String(cString: hostname)
|
||||
|
||||
let name = ptr!.pointee.ifa_name!
|
||||
let ifname = String(cString: name)
|
||||
|
||||
if (getnameinfo(&mask, socklen_t(mask.sa_len), &netmask, socklen_t(netmask.count), nil, socklen_t(0), NI_NUMERICHOST) == 0) {
|
||||
let netmaskIP = String(cString: netmask)
|
||||
|
||||
interfaces.append(NetworkInterface(name: ifname, ip: address, netmask: netmaskIP))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr = ptr!.pointee.ifa_next
|
||||
}
|
||||
freeifaddrs(ifaddr)
|
||||
}
|
||||
|
||||
return interfaces
|
||||
}
|
||||
|
||||
}
|
||||
164
Tun/PacketTunnelProvider.swift
Normal file
164
Tun/PacketTunnelProvider.swift
Normal file
@ -0,0 +1,164 @@
|
||||
//
|
||||
// PacketTunnelProvider.swift
|
||||
// punchnet
|
||||
//
|
||||
// Created by 安礼成 on 2025/8/3.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// PacketTunnelProvider.swift
|
||||
// Tun
|
||||
//
|
||||
// Created by 安礼成 on 2024/1/17.
|
||||
//
|
||||
|
||||
import NetworkExtension
|
||||
import Punchnet
|
||||
|
||||
class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
var context: SDLContext?
|
||||
|
||||
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
|
||||
// host: "192.168.0.101", port: 1265
|
||||
guard let options else {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果当前在运行状态,不允许重复请求
|
||||
guard self.context == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
// let token = options["token"] as! String
|
||||
let installed_channel = options["installed_channel"] as! String
|
||||
let superIp = options["super_ip"] as! String
|
||||
let superPort = options["super_port"] as! Int
|
||||
let stunServersStr = options["stun_servers"] as! String
|
||||
|
||||
let stunServers = stunServersStr.split(separator: ";").compactMap { server -> SDLConfiguration.StunServer? in
|
||||
let parts = server.split(separator: ":", maxSplits: 2)
|
||||
guard parts.count == 2 else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let ports = parts[1].split(separator: ",", maxSplits: 2)
|
||||
guard ports.count == 2, let port1 = Int(String(ports[0])), let port2 = Int(String(ports[1])) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return .init(host: String(parts[0]), ports: [port1, port2])
|
||||
}
|
||||
|
||||
guard stunServers.count >= 2 else {
|
||||
NSLog("stunServers配置错误")
|
||||
return
|
||||
}
|
||||
|
||||
let config = SDLConfiguration(version: 1,
|
||||
installedChannel: installed_channel,
|
||||
superHost: superIp,
|
||||
superPort: superPort,
|
||||
stunServers: stunServers,
|
||||
clientId: SDLContext.getUUID(),
|
||||
token: "")
|
||||
// 加密算法
|
||||
let rsaCipher = try! CCRSACipher(keySize: 1024)
|
||||
let aesChiper = CCAESChiper()
|
||||
|
||||
Task {
|
||||
do {
|
||||
self.context = SDLContext(provider: self, config: config, rsaCipher: rsaCipher, aesCipher: aesChiper, logger: SDLLogger(level: .warning))
|
||||
try await self.context?.start()
|
||||
completionHandler(nil)
|
||||
} catch let err {
|
||||
completionHandler(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||
// Add code here to start the process of stopping the tunnel.
|
||||
Task {
|
||||
await self.context?.stop()
|
||||
self.context = nil
|
||||
}
|
||||
completionHandler()
|
||||
}
|
||||
|
||||
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
|
||||
// Add code here to handle the message.
|
||||
if let handler = completionHandler {
|
||||
handler(messageData)
|
||||
}
|
||||
}
|
||||
|
||||
override func sleep(completionHandler: @escaping () -> Void) {
|
||||
// Add code here to get ready to sleep.
|
||||
completionHandler()
|
||||
}
|
||||
|
||||
override func wake() {
|
||||
// Add code here to wake up.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 获取物理网卡ip地址
|
||||
extension PacketTunnelProvider {
|
||||
|
||||
public static var viaInterface: NetworkInterface? = {
|
||||
let interfaces = NetworkInterfaceManager.getInterfaces()
|
||||
|
||||
return interfaces.first {$0.name == "en0"}
|
||||
}()
|
||||
|
||||
struct CCRSACipher: RSACipher {
|
||||
var pubKey: String
|
||||
let privateKeyDER: Data
|
||||
|
||||
init(keySize: Int) throws {
|
||||
let (privateKey, publicKey) = try Self.loadKeys(keySize: keySize)
|
||||
let privKeyStr = SwKeyConvert.PrivateKey.derToPKCS1PEM(privateKey)
|
||||
|
||||
self.pubKey = SwKeyConvert.PublicKey.derToPKCS8PEM(publicKey)
|
||||
self.privateKeyDER = try SwKeyConvert.PrivateKey.pemToPKCS1DER(privKeyStr)
|
||||
}
|
||||
|
||||
public func decode(data: Data) throws -> Data {
|
||||
let tag = Data()
|
||||
let (decryptedData, _) = try CC.RSA.decrypt(data, derKey: self.privateKeyDER, tag: tag, padding: .pkcs1, digest: .none)
|
||||
|
||||
return decryptedData
|
||||
}
|
||||
|
||||
private static func loadKeys(keySize: Int) throws -> (Data, Data) {
|
||||
if let privateKey = UserDefaults.standard.data(forKey: "privateKey"),
|
||||
let publicKey = UserDefaults.standard.data(forKey: "publicKey") {
|
||||
|
||||
return (privateKey, publicKey)
|
||||
} else {
|
||||
let (privateKey, publicKey) = try CC.RSA.generateKeyPair(keySize)
|
||||
UserDefaults.standard.setValue(privateKey, forKey: "privateKey")
|
||||
UserDefaults.standard.setValue(publicKey, forKey: "publicKey")
|
||||
|
||||
return (privateKey, publicKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CCAESChiper: AESCipher {
|
||||
func decypt(aesKey: Data, data: Data) throws -> Data {
|
||||
let ivData = Data(aesKey.prefix(16))
|
||||
return try CC.crypt(.decrypt, blockMode: .cbc, algorithm: .aes, padding: .pkcs7Padding, data: data, key: aesKey, iv: ivData)
|
||||
}
|
||||
|
||||
func encrypt(aesKey: Data, data: Data) throws -> Data {
|
||||
let ivData = Data(aesKey.prefix(16))
|
||||
|
||||
return try CC.crypt(.encrypt, blockMode: .cbc, algorithm: .aes, padding: .pkcs7Padding, data: data, key: aesKey, iv: ivData)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
C82EA7472E3FAA5A00DA5B3C /* Punchnet in Frameworks */ = {isa = PBXBuildFile; productRef = C82EA7462E3FAA5A00DA5B3C /* Punchnet */; };
|
||||
C8A77F2A2DD1E77B00195617 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8A77F292DD1E77B00195617 /* NetworkExtension.framework */; };
|
||||
C8A77F322DD1E77B00195617 /* Tun.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C8A77F272DD1E77B00195617 /* Tun.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
C8A77F792DD1E93900195617 /* NIO in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F782DD1E93900195617 /* NIO */; };
|
||||
@ -14,8 +15,6 @@
|
||||
C8A77F7D2DD1E93900195617 /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F7C2DD1E93900195617 /* NIOCore */; };
|
||||
C8A77F7F2DD1E93900195617 /* NIOEmbedded in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F7E2DD1E93900195617 /* NIOEmbedded */; };
|
||||
C8A77F812DD1E93900195617 /* NIOFoundationCompat in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F802DD1E93900195617 /* NIOFoundationCompat */; };
|
||||
C8A77F832DD1E98B00195617 /* NIO in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F822DD1E98B00195617 /* NIO */; };
|
||||
C8A77F852DD1E99300195617 /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F842DD1E99300195617 /* NIOCore */; };
|
||||
C8A77F882DD1EA0200195617 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F872DD1EA0200195617 /* SwiftProtobuf */; };
|
||||
C8A77F8A2DD1EA0200195617 /* SwiftProtobufPluginLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F892DD1EA0200195617 /* SwiftProtobufPluginLibrary */; };
|
||||
/* End PBXBuildFile section */
|
||||
@ -143,10 +142,9 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C8A77F852DD1E99300195617 /* NIOCore in Frameworks */,
|
||||
C8A77F2A2DD1E77B00195617 /* NetworkExtension.framework in Frameworks */,
|
||||
C8A77F8A2DD1EA0200195617 /* SwiftProtobufPluginLibrary in Frameworks */,
|
||||
C8A77F832DD1E98B00195617 /* NIO in Frameworks */,
|
||||
C82EA7472E3FAA5A00DA5B3C /* Punchnet in Frameworks */,
|
||||
C8A77F882DD1EA0200195617 /* SwiftProtobuf in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -280,10 +278,9 @@
|
||||
);
|
||||
name = Tun;
|
||||
packageProductDependencies = (
|
||||
C8A77F822DD1E98B00195617 /* NIO */,
|
||||
C8A77F842DD1E99300195617 /* NIOCore */,
|
||||
C8A77F872DD1EA0200195617 /* SwiftProtobuf */,
|
||||
C8A77F892DD1EA0200195617 /* SwiftProtobufPluginLibrary */,
|
||||
C82EA7462E3FAA5A00DA5B3C /* Punchnet */,
|
||||
);
|
||||
productName = Tun;
|
||||
productReference = C8A77F272DD1E77B00195617 /* Tun.appex */;
|
||||
@ -325,8 +322,7 @@
|
||||
mainGroup = C8A77EEA2DD1E6D000195617;
|
||||
minimizedProjectReferenceProxies = 1;
|
||||
packageReferences = (
|
||||
C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */,
|
||||
C8A77F862DD1EA0200195617 /* XCLocalSwiftPackageReference "../../packages/swift-protobuf" */,
|
||||
C82EA7452E3FAA5A00DA5B3C /* XCRemoteSwiftPackageReference "swiftlib_sdlan" */,
|
||||
);
|
||||
preferredProjectObjectVersion = 77;
|
||||
productRefGroup = C8A77EF42DD1E6D000195617 /* Products */;
|
||||
@ -475,7 +471,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.2;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@ -532,7 +528,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.2;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = macosx;
|
||||
@ -561,7 +557,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -593,7 +589,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -612,7 +608,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = PF3QG837XS;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -630,7 +626,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = PF3QG837XS;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -647,6 +643,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = PF3QG837XS;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -663,6 +660,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = PF3QG837XS;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -691,6 +689,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet.tun;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -721,6 +720,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.6;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet.tun;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -782,18 +782,23 @@
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCLocalSwiftPackageReference section */
|
||||
C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = "../../packages/swift-nio";
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
C82EA7452E3FAA5A00DA5B3C /* XCRemoteSwiftPackageReference "swiftlib_sdlan" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://gitea.s5s8.com/anlicheng/swiftlib_sdlan.git";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 2.2.0;
|
||||
};
|
||||
C8A77F862DD1EA0200195617 /* XCLocalSwiftPackageReference "../../packages/swift-protobuf" */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = "../../packages/swift-protobuf";
|
||||
};
|
||||
/* End XCLocalSwiftPackageReference section */
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
C82EA7462E3FAA5A00DA5B3C /* Punchnet */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = C82EA7452E3FAA5A00DA5B3C /* XCRemoteSwiftPackageReference "swiftlib_sdlan" */;
|
||||
productName = Punchnet;
|
||||
};
|
||||
C8A77F782DD1E93900195617 /* NIO */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = NIO;
|
||||
@ -814,16 +819,6 @@
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = NIOFoundationCompat;
|
||||
};
|
||||
C8A77F822DD1E98B00195617 /* NIO */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */;
|
||||
productName = NIO;
|
||||
};
|
||||
C8A77F842DD1E99300195617 /* NIOCore */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */;
|
||||
productName = NIOCore;
|
||||
};
|
||||
C8A77F872DD1EA0200195617 /* SwiftProtobuf */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = SwiftProtobuf;
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
{
|
||||
"originHash" : "fc5ff56467a09054cad310ea04e2207caefea4e4c42012fbd995ed64d089417b",
|
||||
"originHash" : "2c771b2bd4bccdc5777d69cc734485452a1e854c0123ba591d596b3f580f4cb8",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "swift-atomics",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-atomics.git",
|
||||
"state" : {
|
||||
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
|
||||
"version" : "1.2.0"
|
||||
"revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7",
|
||||
"version" : "1.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -15,8 +15,26 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-collections.git",
|
||||
"state" : {
|
||||
"revision" : "671108c96644956dddcd89dd59c203dcdb36cec7",
|
||||
"version" : "1.1.4"
|
||||
"revision" : "8c0c0a8b49e080e54e5e328cc552821ff07cd341",
|
||||
"version" : "1.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio.git",
|
||||
"state" : {
|
||||
"revision" : "a5fea865badcb1c993c85b0f0e8d05a4bd2270fb",
|
||||
"version" : "2.85.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-protobuf",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-protobuf.git",
|
||||
"state" : {
|
||||
"revision" : "102a647b573f60f73afdce5613a51d71349fe507",
|
||||
"version" : "1.30.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -24,8 +42,17 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-system.git",
|
||||
"state" : {
|
||||
"revision" : "a34201439c74b53f0fd71ef11741af7e7caf01e1",
|
||||
"version" : "1.4.2"
|
||||
"revision" : "b63d24d465e237966c3f59f47dcac6c70fb0bca3",
|
||||
"version" : "1.6.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftlib_sdlan",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://gitea.s5s8.com/anlicheng/swiftlib_sdlan.git",
|
||||
"state" : {
|
||||
"revision" : "2c05d71dbe3684e51e9de55910619156ebe360c6",
|
||||
"version" : "2.2.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
//
|
||||
// Config.swift
|
||||
// punchnet
|
||||
//
|
||||
// Created by 安礼成 on 2025/5/14.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
enum PunchnetError: Error {
|
||||
case dnsUnreachable
|
||||
}
|
||||
|
||||
struct PunchnetConfig {
|
||||
static let server = "punchnet.aioe.tech"
|
||||
static let port = 18083
|
||||
|
||||
static func getOptions() throws -> [String:NSObject] {
|
||||
var options: [String: NSObject] = [:]
|
||||
|
||||
if let ip = DNSResolver.resolveAddrInfos(PunchnetConfig.server).first {
|
||||
options["super_ip"] = ip as NSObject
|
||||
} else {
|
||||
throw PunchnetError.dnsUnreachable
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -15,4 +15,29 @@ struct SystemConfig {
|
||||
|
||||
// 安装渠道
|
||||
static let installedChannel = "MacAppStore"
|
||||
|
||||
// super 节点
|
||||
//static let superHost = "118.178.229.213"
|
||||
|
||||
static let superHost = "punchnet.aioe.tech"
|
||||
static let superPort = 18083
|
||||
|
||||
// stun探测服务
|
||||
static let stunServers = "118.178.229.213:1265,1266;118.178.229.213:1265,1266"
|
||||
|
||||
static func getOptions(token: String) -> [String:NSObject]? {
|
||||
guard let superIp = DNSResolver.resolveAddrInfos(superHost).first else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return [
|
||||
"version:": version as NSObject,
|
||||
"installed_channel": installedChannel as NSObject,
|
||||
"token": token as NSObject,
|
||||
"super_ip": superIp as NSObject,
|
||||
"super_port": superPort as NSObject,
|
||||
"stun_servers": stunServers as NSObject
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -32,10 +32,7 @@ class VPNManager: ObservableObject {
|
||||
try await manager.loadFromPreferences()
|
||||
self.addVPNStatusObserver(manager)
|
||||
|
||||
var configOptions = try PunchnetConfig.getOptions()
|
||||
configOptions.merge(options, uniquingKeysWith: {$1})
|
||||
|
||||
try manager.connection.startVPNTunnel(options: configOptions)
|
||||
try manager.connection.startVPNTunnel(options: options)
|
||||
}
|
||||
|
||||
// 关闭vpn
|
||||
@ -9,7 +9,6 @@ import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct AbortView: View {
|
||||
|
||||
struct AlertShow: Identifiable {
|
||||
enum ShowContent {
|
||||
case error(String)
|
||||
@ -9,8 +9,7 @@ import SwiftUI
|
||||
import SwiftData
|
||||
import Combine
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
struct IndexView: View {
|
||||
@AppStorage("token") private var token: String = ""
|
||||
@State private var showToken: Bool = false
|
||||
|
||||
@ -191,24 +190,13 @@ struct ContentView: View {
|
||||
case .connected:
|
||||
try await vpnManager.disableVpn()
|
||||
case .disconnected:
|
||||
/*
|
||||
if self.token.isEmpty {
|
||||
self.showAlert = true
|
||||
return
|
||||
}
|
||||
*/
|
||||
//print("use port: \(vpnManager.noticePort as NSObject)")
|
||||
try await vpnManager.enableVpn(options: [
|
||||
"version:": SystemConfig.version as NSObject,
|
||||
"installed_channel": SystemConfig.installedChannel as NSObject,
|
||||
"token": self.token as NSObject
|
||||
])
|
||||
try await vpnManager.enableVpn(options: SystemConfig.getOptions(token: self.token)!)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ContentView()
|
||||
IndexView()
|
||||
//.modelContainer(for: Item.self, inMemory: true)
|
||||
}
|
||||
@ -35,7 +35,7 @@ struct punchnetApp: App {
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup(id: "mainWindow") {
|
||||
ContentView()
|
||||
IndexView()
|
||||
.frame(minWidth: 300, maxWidth: 300, minHeight: 500, maxHeight: 500)
|
||||
.onAppear {
|
||||
// 获取主屏幕的尺寸
|
||||
@ -94,11 +94,7 @@ struct punchnetApp: App {
|
||||
switch self.vpnManager.vpnStatus {
|
||||
case .disconnected:
|
||||
Task {
|
||||
try await vpnManager.enableVpn(options: [
|
||||
"version:": SystemConfig.version as NSObject,
|
||||
"installed_channel": SystemConfig.installedChannel as NSObject,
|
||||
"token": token as NSObject
|
||||
])
|
||||
try await vpnManager.enableVpn(options: SystemConfig.getOptions(token: self.token)!)
|
||||
}
|
||||
case .connected:
|
||||
Task {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user