This commit is contained in:
anlicheng 2026-02-25 00:25:58 +08:00
parent 2d6d640a44
commit 703d4e191f
11 changed files with 186 additions and 185 deletions

View File

@ -10,8 +10,8 @@ import Darwin
actor ArpServerActor { actor ArpServerActor {
private var known_macs: [UInt32:Data] = [:] private var known_macs: [UInt32:Data] = [:]
init(known_macs: [UInt32:Data]) { init() {
self.known_macs = known_macs
} }
func query(ip: UInt32) -> Data? { func query(ip: UInt32) -> Data? {

View File

@ -47,7 +47,7 @@ actor SDLContextActor {
private var dnsWorker: Task<Void, Never>? private var dnsWorker: Task<Void, Never>?
private var quicClient: SDLQUICClient? private var quicClient: SDLQUICClient?
private var quicWorker: Task<Void, Never>? private var quicWorkers: [Task<Void, Never>]?
nonisolated private let puncherActor: SDLPuncherActor nonisolated private let puncherActor: SDLPuncherActor
// //
@ -78,6 +78,9 @@ actor SDLContextActor {
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot> private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
private let policyRequesterActor: PolicyRequesterActor private let policyRequesterActor: PolicyRequesterActor
//
private var registerTask: Task<Void, Never>?
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher, aesCipher: AESCipher) { public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher, aesCipher: AESCipher) {
self.provider = provider self.provider = provider
self.config = config self.config = config
@ -85,7 +88,7 @@ actor SDLContextActor {
self.aesCipher = aesCipher self.aesCipher = aesCipher
self.sessionManager = SessionManager() self.sessionManager = SessionManager()
self.arpServer = ArpServerActor(known_macs: [:]) self.arpServer = ArpServerActor()
self.puncherActor = SDLPuncherActor(querySocketAddress: config.stunSocketAddress) self.puncherActor = SDLPuncherActor(querySocketAddress: config.stunSocketAddress)
self.proberActor = SDLNATProberActor(addressArray: config.stunProbeSocketAddressArray) self.proberActor = SDLNATProberActor(addressArray: config.stunProbeSocketAddressArray)
@ -131,23 +134,28 @@ actor SDLContextActor {
} }
private func startQUICClient() async throws -> SDLQUICClient { private func startQUICClient() async throws -> SDLQUICClient {
self.quicWorker?.cancel() self.quicWorkers?.forEach {$0.cancel()}
self.quicClient?.stop() self.quicClient?.stop()
// monitor // monitor
let quicClient = SDLQUICClient(host: "118.178.229.213", port: 1365) let quicClient = SDLQUICClient(host: self.config.serverIp, port: 443)
quicClient.start() quicClient.start()
// quic // quic
try await quicClient.waitReady() try await quicClient.waitReady()
// quic
try await Task.sleep(for: .seconds(0.2)) try await Task.sleep(for: .seconds(0.2))
SDLLogger.shared.log("[SDLContext] start quic client ready") SDLLogger.shared.log("[SDLContext] start quic client ready")
self.quicWorker = Task.detached { let messageTask = Task.detached {
for await message in quicClient.messageStream { for await message in quicClient.messageStream {
switch message { switch message {
case .welcome(let welcome): case .welcome(let welcome):
SDLLogger.shared.log("[SDLContext] quic welcome: \(welcome)") SDLLogger.shared.log("[SDLContext] quic welcome: \(welcome)")
//
await self.startRegisterLoop()
case .pong:
SDLLogger.shared.log("[SDLContext] quic pong")
case .registerSuperAck(let registerSuperAck): case .registerSuperAck(let registerSuperAck):
await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck) await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck)
case .registerSuperNak(let registerSuperNak): case .registerSuperNak(let registerSuperNak):
@ -162,17 +170,31 @@ actor SDLContextActor {
} }
} }
} }
self.quicClient = quicClient
// //
self.doRegisterSuper() let pingTask = Task.detached {
let timerStream = SDLAsyncTimerStream()
timerStream.start(interval: .seconds(5))
for await _ in timerStream.stream {
if Task.isCancelled {
break
}
quicClient.send(type: .ping, data: Data())
}
SDLLogger.shared.log("[SDLContext] udp pingTask cancel")
}
self.quicClient = quicClient
self.quicWorkers = [messageTask, pingTask]
return quicClient return quicClient
} }
private func startNoticeClient() throws -> SDLNoticeClient { private func startNoticeClient() throws -> SDLNoticeClient {
// noticeClient // noticeClient
let noticeClient = try SDLNoticeClient(noticePort: self.config.noticePort, logger: SDLLogger.shared) let noticeClient = try SDLNoticeClient(noticePort: self.config.noticePort)
noticeClient.start() noticeClient.start()
SDLLogger.shared.log("[SDLContext] noticeClient started") SDLLogger.shared.log("[SDLContext] noticeClient started")
@ -196,7 +218,7 @@ actor SDLContextActor {
switch event { switch event {
case .changed: case .changed:
// nat // nat
//self.natType = await self.getNatType() await self.probeNatType()
SDLLogger.shared.log("didNetworkPathChanged, nat type is:", level: .info) SDLLogger.shared.log("didNetworkPathChanged, nat type is:", level: .info)
case .unreachable: case .unreachable:
SDLLogger.shared.log("didNetworkPathUnreachable", level: .warning) SDLLogger.shared.log("didNetworkPathUnreachable", level: .warning)
@ -210,7 +232,7 @@ actor SDLContextActor {
self.dnsWorker = nil self.dnsWorker = nil
// dns // dns
let dnsSocketAddress = try SocketAddress.makeAddressResolvingHost(self.config.remoteDnsServer, port: 15353) let dnsSocketAddress = try SocketAddress.makeAddressResolvingHost(self.config.serverIp, port: 15353)
let dnsClient = try await SDLDNSClient(dnsServerAddress: dnsSocketAddress, logger: SDLLogger.shared) let dnsClient = try await SDLDNSClient(dnsServerAddress: dnsSocketAddress, logger: SDLLogger.shared)
try dnsClient.start() try dnsClient.start()
SDLLogger.shared.log("[SDLContext] dnsClient started") SDLLogger.shared.log("[SDLContext] dnsClient started")
@ -246,11 +268,10 @@ actor SDLContextActor {
// //
let pingTask = Task.detached { let pingTask = Task.detached {
let (stream, cont) = AsyncStream.makeStream(of: Void.self)
let timerStream = SDLAsyncTimerStream() let timerStream = SDLAsyncTimerStream()
timerStream.start(cont) timerStream.start(interval: .seconds(5))
for await _ in stream { for await _ in timerStream.stream {
if Task.isCancelled { if Task.isCancelled {
break break
} }
@ -276,6 +297,8 @@ actor SDLContextActor {
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck) await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
case .data(let data): case .data(let data):
try? await self.handleData(data: data) try? await self.handleData(data: data)
case .stunReply(let stunReply):
SDLLogger.shared.log("[SDLContext] get a stunReply: \(stunReply)")
} }
} }
@ -286,11 +309,7 @@ actor SDLContextActor {
self.udpHoleWorkers = [pingTask, messageTask] self.udpHoleWorkers = [pingTask, messageTask]
// nat // nat
Task { self.probeNatType()
let natType = await self.proberActor.probeNatType(using: udpHole)
self.setNatType(natType: natType)
SDLLogger.shared.log("[SDLContext] nat_type is: \(natType)")
}
return udpHole return udpHole
} }
@ -303,6 +322,9 @@ actor SDLContextActor {
self.udpHoleWorkers?.forEach { $0.cancel() } self.udpHoleWorkers?.forEach { $0.cancel() }
self.udpHoleWorkers = nil self.udpHoleWorkers = nil
self.quicWorkers?.forEach { $0.cancel() }
self.quicWorkers = nil
self.dnsWorker?.cancel() self.dnsWorker?.cancel()
self.dnsWorker = nil self.dnsWorker = nil
@ -311,12 +333,34 @@ actor SDLContextActor {
self.readTask?.cancel() self.readTask?.cancel()
self.readTask = nil self.readTask = nil
self.registerTask?.cancel()
self.registerTask = nil
} }
private func setNatType(natType: SDLNATProberActor.NatType) { private func setNatType(natType: SDLNATProberActor.NatType) {
self.natType = natType self.natType = natType
} }
//
private func startRegisterLoop() {
guard self.registerTask == nil else {
return
}
self.registerTask = Task {
while !Task.isCancelled {
self.doRegisterSuper()
try? await Task.sleep(for: .seconds(5))
if self.state == .registered {
break
}
SDLLogger.shared.log("[SDLContext] register super failed, retry")
}
self.registerTask = nil
}
}
private func sendStunRequest() { private func sendStunRequest() {
guard let sessionToken = self.sessionToken else { guard let sessionToken = self.sessionToken else {
return return
@ -423,20 +467,6 @@ actor SDLContextActor {
if let registerSuperData = try? registerSuper.serializedData() { if let registerSuperData = try? registerSuper.serializedData() {
SDLLogger.shared.log("[SDLContext] will send register super") SDLLogger.shared.log("[SDLContext] will send register super")
self.quicClient?.send(type: .registerSuper, data: registerSuperData) self.quicClient?.send(type: .registerSuper, data: registerSuperData)
// 5
Task {
try await Task.sleep(for: .seconds(5))
self.checkRegisterState()
}
}
}
//
private func checkRegisterState() {
if self.state == .unregistered {
SDLLogger.shared.log("[SDLContext] register super failed, retry")
self.doRegisterSuper()
} }
} }
@ -535,13 +565,11 @@ actor SDLContextActor {
} }
} else { } else {
// //
if let sessionToken = self.sessionToken {
var policyRequest = SDLPolicyRequest() var policyRequest = SDLPolicyRequest()
policyRequest.srcIdentityID = data.identityID policyRequest.srcIdentityID = data.identityID
policyRequest.dstIdentityID = self.config.identityId policyRequest.dstIdentityID = self.config.identityId
await self.policyRequesterActor.submitPolicyRequest(using: self.udpHole, request: &policyRequest) await self.policyRequesterActor.submitPolicyRequest(using: self.quicClient, request: &policyRequest)
}
} }
default: default:
SDLLogger.shared.log("[SDLContext] get invalid packet", level: .debug) SDLLogger.shared.log("[SDLContext] get invalid packet", level: .debug)
@ -588,11 +616,10 @@ actor SDLContextActor {
private func dealPacket(packet: IPPacket) async { private func dealPacket(packet: IPPacket) async {
let networkAddr = self.config.networkAddress let networkAddr = self.config.networkAddress
// TODO
if SDLDNSClient.Helper.isDnsRequestPacket(ipPacket: packet) { if SDLDNSClient.Helper.isDnsRequestPacket(ipPacket: packet) {
let destIp = packet.header.destination_ip let destIp = packet.header.destination_ip
SDLLogger.shared.log("[DNSQuery] destIp: \(destIp), int: \(packet.header.destination.asIpAddress())", level: .debug) SDLLogger.shared.log("[DNSQuery] destIp: \(destIp), int: \(packet.header.destination.asIpAddress())", level: .debug)
//self.dnsClient?.forward(ipPacket: packet) self.dnsClient?.forward(ipPacket: packet)
return return
} }
@ -654,7 +681,7 @@ actor SDLContextActor {
// //
Task.detached { Task.detached {
await self.puncherActor.submitRegisterRequest(using: udpHole, request: .init(srcMac: networkAddr.mac, dstMac: dstMac, networkId: networkAddr.networkId)) await self.puncherActor.submitRegisterRequest(quicClient: self.quicClient, request: .init(srcMac: networkAddr.mac, dstMac: dstMac, networkId: networkAddr.networkId))
} }
} }
} }
@ -696,6 +723,17 @@ actor SDLContextActor {
} }
} }
//
private func probeNatType() {
Task {
guard let udpHole = self.udpHole else {
return
}
// nat
self.natType = await self.proberActor.probeNatType(using: udpHole)
SDLLogger.shared.log("[SDLContext] nat_type is: \(natType)")
}
}
private func spawnLoop(_ body: @escaping () async throws -> Void) -> Task<Void, Never> { private func spawnLoop(_ body: @escaping () async throws -> Void) -> Task<Void, Never> {
return Task.detached { return Task.detached {
@ -714,13 +752,11 @@ actor SDLContextActor {
// todo // todo
private func triggerPolicy() async { private func triggerPolicy() async {
// //
if let sessionToken = self.sessionToken {
var policyRequest = SDLPolicyRequest() var policyRequest = SDLPolicyRequest()
policyRequest.srcIdentityID = 1234 policyRequest.srcIdentityID = 1234
policyRequest.dstIdentityID = self.config.identityId policyRequest.dstIdentityID = self.config.identityId
await self.policyRequesterActor.submitPolicyRequest(using: self.udpHole, request: &policyRequest) await self.policyRequesterActor.submitPolicyRequest(using: self.quicClient, request: &policyRequest)
}
} }
deinit { deinit {

View File

@ -30,9 +30,9 @@ actor SDLPuncherActor {
self.querySocketAddress = querySocketAddress self.querySocketAddress = querySocketAddress
} }
func submitRegisterRequest(using udpHole: SDLUDPHole?, request: RegisterRequest) { func submitRegisterRequest(quicClient: SDLQUICClient?, request: RegisterRequest) {
let dstMac = request.dstMac let dstMac = request.dstMac
guard let udpHole, !coolingDown.contains(dstMac) else { guard let quicClient, !coolingDown.contains(dstMac) else {
return return
} }
@ -44,7 +44,7 @@ actor SDLPuncherActor {
if self.pktId == 0 { if self.pktId == 0 {
self.pktId = 1 self.pktId = 1
} }
//self.tryHole(using: udpHole, pktId: pktId, request: request) self.tryHole(using: quicClient, pktId: pktId, request: request)
Task { Task {
// //
@ -54,22 +54,23 @@ actor SDLPuncherActor {
} }
} }
// func handlePeerInfo(using udpHole: SDLUDPHole, peerInfo: SDLPeerInfo) async { func handlePeerInfo(using udpHole: SDLUDPHole, peerInfo: SDLPeerInfo) async {
// if let request = pendingRequests.removeValue(forKey: peerInfo.pktID) { guard let request = pendingRequests.removeValue(forKey: peerInfo.pktID),
// if let remoteAddress = try? await peerInfo.v4Info.socketAddress() { let remoteAddress = try? await peerInfo.v4Info.socketAddress() else {
// SDLLogger.shared.log("[SDLContext] hole sock address: \(remoteAddress)", level: .debug) return
// // register }
// var register = SDLRegister()
// register.networkID = request.networkId SDLLogger.shared.log("[SDLContext] hole sock address: \(remoteAddress)", level: .debug)
// register.srcMac = request.srcMac // register
// register.dstMac = request.dstMac var register = SDLRegister()
// register.networkID = request.networkId
// udpHole.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress) register.srcMac = request.srcMac
// } else { register.dstMac = request.dstMac
// SDLLogger.shared.log("[SDLContext] hole sock address is invalid: \(peerInfo.v4Info)", level: .warning)
// } if let registerData = try? register.serializedData() {
// } udpHole.send(type: .register, data: registerData, remoteAddress: remoteAddress)
// } }
}
private func endCooldown(for key: Data) { private func endCooldown(for key: Data) {
self.coolingDown.remove(key) self.coolingDown.remove(key)
@ -79,14 +80,14 @@ actor SDLPuncherActor {
self.pendingRequests.removeValue(forKey: pktId) self.pendingRequests.removeValue(forKey: pktId)
} }
// private func tryHole(using udpHole: SDLUDPHole, pktId: UInt32, request: RegisterRequest) { private func tryHole(using quicClient: SDLQUICClient, pktId: UInt32, request: RegisterRequest) {
// var queryInfo = SDLQueryInfo() var queryInfo = SDLQueryInfo()
// queryInfo.pktID = pktId queryInfo.pktID = pktId
// queryInfo.dstMac = request.dstMac queryInfo.dstMac = request.dstMac
// self.pendingRequests[pktId] = request self.pendingRequests[pktId] = request
//
// if let queryData = try? queryInfo.serializedData() { if let queryData = try? queryInfo.serializedData() {
// udpHole.send(type: .queryInfo, data: queryData, remoteAddress: self.querySocketAddress) quicClient.send(type: .queryInfo, data: queryData)
// } }
// } }
} }

View File

@ -102,6 +102,7 @@ final class SDLQUICClient {
self.messageCont.finish() self.messageCont.finish()
} }
} }
} }
func send(type: SDLPacketType, data: Data) { func send(type: SDLPacketType, data: Data) {
@ -240,6 +241,8 @@ final class SDLQUICClient {
} }
return .event(.networkShutdown(networkShutdownEvent)) return .event(.networkShutdown(networkShutdownEvent))
} }
case .pong:
return .pong
default: default:
SDLLogger.shared.log("SDLUDPHole decode miss type: \(type)") SDLLogger.shared.log("SDLUDPHole decode miss type: \(type)")

View File

@ -24,9 +24,9 @@ actor PolicyRequesterActor {
} }
// //
func submitPolicyRequest(using udpHole: SDLUDPHole?, request: inout SDLPolicyRequest) { func submitPolicyRequest(using quicClient: SDLQUICClient?, request: inout SDLPolicyRequest) {
let identityId = request.srcIdentityID let identityId = request.srcIdentityID
guard let udpHole, !coolingDown.contains(identityId) else { guard let quicClient, !coolingDown.contains(identityId) else {
return return
} }
@ -39,7 +39,7 @@ actor PolicyRequesterActor {
self.versions[identityId] = version + 1 self.versions[identityId] = version + 1
// //
if let queryData = try? request.serializedData() { if let queryData = try? request.serializedData() {
udpHole.send(type: .policyRequest, data: queryData, remoteAddress: self.querySocketAddress) quicClient.send(type: .policyRequest, data: queryData)
} }
Task { Task {

View File

@ -9,15 +9,18 @@ import Foundation
class SDLAsyncTimerStream { class SDLAsyncTimerStream {
let timer: DispatchSourceTimer let timer: DispatchSourceTimer
let stream: AsyncStream<Void>
private let cont: AsyncStream<Void>.Continuation
init() { init() {
self.timer = DispatchSource.makeTimerSource(queue: .global()) self.timer = DispatchSource.makeTimerSource(queue: .global())
(stream, cont) = AsyncStream.makeStream(of: Void.self)
} }
func start(_ cont: AsyncStream<Void>.Continuation) { func start(interval: DispatchTimeInterval) {
timer.schedule(deadline: .now(), repeating: .seconds(5)) timer.schedule(deadline: .now(), repeating: interval)
timer.setEventHandler { timer.setEventHandler {
cont.yield() self.cont.yield()
} }
timer.resume() timer.resume()
} }

View File

@ -9,16 +9,6 @@ import NIOCore
// //
public class SDLConfiguration { public class SDLConfiguration {
public struct StunServer {
public let host: String
public let ports: [Int]
public init(host: String, ports: [Int]) {
self.host = host
self.ports = ports
}
}
public struct NetworkAddress { public struct NetworkAddress {
public let networkId: UInt32 public let networkId: UInt32
public let ip: UInt32 public let ip: UInt32
@ -49,30 +39,24 @@ public class SDLConfiguration {
} }
// //
let version: UInt8 let version: Int
// let serverIp: String
let installedChannel: String let stunServers: [String]
let superHost: String
let superPort: Int
let stunServers: [StunServer]
let remoteDnsServer: String
let noticePort: Int let noticePort: Int
lazy var stunSocketAddress: SocketAddress = { lazy var stunSocketAddress: SocketAddress = {
let stunServer = stunServers[0] let stunServer = stunServers[0]
return try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[0]) return try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1365)
}() }()
// //
lazy var stunProbeSocketAddressArray: [[SocketAddress]] = { lazy var stunProbeSocketAddressArray: [[SocketAddress]] = {
return stunServers.map { stunServer in return stunServers.map { stunServer in
[ [
try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[0]), try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1365),
try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[1]) try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1366)
] ]
} }
}() }()
@ -83,30 +67,24 @@ public class SDLConfiguration {
let accessToken: String let accessToken: String
let identityId: UInt32 let identityId: UInt32
public init(version: UInt8, public init(version: Int,
installedChannel: String, serverIp: String,
superHost: String, stunServers: [String],
superPort: Int,
stunServers: [StunServer],
clientId: String, clientId: String,
networkAddress: NetworkAddress, networkAddress: NetworkAddress,
hostname: String, hostname: String,
noticePort: Int, noticePort: Int,
accessToken: String, accessToken: String,
identityId: UInt32, identityId: UInt32) {
remoteDnsServer: String) {
self.version = version self.version = version
self.installedChannel = installedChannel self.serverIp = serverIp
self.superHost = superHost
self.superPort = superPort
self.stunServers = stunServers self.stunServers = stunServers
self.clientId = clientId self.clientId = clientId
self.networkAddress = networkAddress self.networkAddress = networkAddress
self.noticePort = noticePort self.noticePort = noticePort
self.accessToken = accessToken self.accessToken = accessToken
self.identityId = identityId self.identityId = identityId
self.remoteDnsServer = remoteDnsServer
self.hostname = hostname self.hostname = hostname
} }
} }
@ -115,60 +93,36 @@ public class SDLConfiguration {
extension SDLConfiguration { extension SDLConfiguration {
static func parse(options: [String: NSObject]) -> SDLConfiguration? { static func parse(options: [String: NSObject]) -> SDLConfiguration? {
guard let installed_channel = options["installed_channel"] as? String, guard let version = options["version"] as? Int,
let superIp = options["super_ip"] as? String, let serverIp = options["server_ip"] as? String,
let superPort = options["super_port"] as? Int, let stunAssistIp = options["stun_assist_ip"] as? String,
let stunServersStr = options["stun_servers"] as? String,
let noticePort = options["notice_port"] as? Int, let noticePort = options["notice_port"] as? Int,
let accessToken = options["access_token"] as? String, let accessToken = options["access_token"] as? String,
let identityId = options["identity_id"] as? UInt32, let identityId = options["identity_id"] as? UInt32,
let clientId = options["client_id"] as? String, let clientId = options["client_id"] as? String,
let remoteDnsServer = options["remote_dns_server"] as? String,
let hostname = options["hostname"] as? String, let hostname = options["hostname"] as? String,
let networkAddressDict = options["network_address"] as? [String: NSObject] else { let networkAddressDict = options["network_address"] as? [String: NSObject] else {
return nil return nil
} }
guard let stunServers = parseStunServers(stunServersStr: stunServersStr), stunServers.count >= 2 else {
NSLog("stunServers配置错误")
return nil
}
guard let networkAddress = parseNetworkAddress(networkAddressDict) else { guard let networkAddress = parseNetworkAddress(networkAddressDict) else {
return nil return nil
} }
return SDLConfiguration(version: 1, let stunServers: [String] = [
installedChannel: installed_channel, serverIp,
superHost: superIp, stunAssistIp
superPort: superPort, ]
return SDLConfiguration(version: version,
serverIp: serverIp,
stunServers: stunServers, stunServers: stunServers,
clientId: clientId, clientId: clientId,
networkAddress: networkAddress, networkAddress: networkAddress,
hostname: hostname, hostname: hostname,
noticePort: noticePort, noticePort: noticePort,
accessToken: accessToken, accessToken: accessToken,
identityId: identityId, identityId: identityId)
remoteDnsServer: remoteDnsServer)
}
private static func parseStunServers(stunServersStr: String) -> [SDLConfiguration.StunServer]? {
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])
}
return stunServers.count >= 2 ? stunServers : nil
} }
private static func parseNetworkAddress(_ config: [String: NSObject]) -> SDLConfiguration.NetworkAddress? { private static func parseNetworkAddress(_ config: [String: NSObject]) -> SDLConfiguration.NetworkAddress? {

View File

@ -21,6 +21,10 @@ enum SDLPacketType: UInt8 {
case queryInfo = 0x06 case queryInfo = 0x06
case peerInfo = 0x07 case peerInfo = 0x07
//
case ping = 0x08
case pong = 0x09
// //
case event = 0x10 case event = 0x10
@ -28,6 +32,7 @@ enum SDLPacketType: UInt8 {
case registerAck = 0x21 case registerAck = 0x21
case stunRequest = 0x30 case stunRequest = 0x30
case stunReply = 0x31
case stunProbe = 0x32 case stunProbe = 0x32
case stunProbeReply = 0x33 case stunProbeReply = 0x33
@ -99,12 +104,15 @@ enum SDLHoleMessage {
case register(SDLRegister) case register(SDLRegister)
case registerAck(SDLRegisterAck) case registerAck(SDLRegisterAck)
case stunProbeReply(SDLStunProbeReply) case stunProbeReply(SDLStunProbeReply)
case stunReply(SDLStunReply)
} }
enum SDLQUICInboundMessage { enum SDLQUICInboundMessage {
// //
case welcome(SDLWelcome) case welcome(SDLWelcome)
case pong
// //
case registerSuperAck(SDLRegisterSuperAck) case registerSuperAck(SDLRegisterSuperAck)
case registerSuperNak(SDLRegisterSuperNak) case registerSuperNak(SDLRegisterSuperNak)

View File

@ -25,12 +25,10 @@ final class SDLNoticeClient {
private var task: Task<Void, Never>? private var task: Task<Void, Never>?
private var channel: Channel private var channel: Channel
private let logger: SDLLogger
private let noticePort: Int private let noticePort: Int
// //
init(noticePort: Int, logger: SDLLogger) throws { init(noticePort: Int) throws {
self.logger = logger
self.noticePort = noticePort self.noticePort = noticePort
let bootstrap = DatagramBootstrap(group: self.group) let bootstrap = DatagramBootstrap(group: self.group)
@ -40,7 +38,7 @@ final class SDLNoticeClient {
} }
self.channel = try bootstrap.bind(host: "0.0.0.0", port: 0).wait() self.channel = try bootstrap.bind(host: "0.0.0.0", port: 0).wait()
self.logger.log("[SDLNoticeClient] started", level: .debug) SDLLogger.shared.log("[SDLNoticeClient] started", level: .debug)
} }
func start() { func start() {

View File

@ -84,6 +84,11 @@ final class SDLUDPHole: ChannelInboundHandler {
var buffer = envelope.data var buffer = envelope.data
let remoteAddress = envelope.remoteAddress let remoteAddress = envelope.remoteAddress
if let rawBytes = buffer.getBytes(at: buffer.readerIndex, length: buffer.readableBytes) {
SDLLogger.shared.log("[SDLUDPHole] get raw bytes: \(rawBytes), from: \(remoteAddress)")
}
do { do {
if let message = try decode(buffer: &buffer) { if let message = try decode(buffer: &buffer) {
self.messageContinuation.yield((remoteAddress, message)) self.messageContinuation.yield((remoteAddress, message))
@ -126,11 +131,9 @@ final class SDLUDPHole: ChannelInboundHandler {
// --MARK: // --MARK:
private func decode(buffer: inout ByteBuffer) throws -> SDLHoleMessage? { private func decode(buffer: inout ByteBuffer) throws -> SDLHoleMessage? {
let rawType = buffer.getInteger(at: 0, endianness: .big, as: UInt8.self)
guard let type = buffer.readInteger(as: UInt8.self), guard let type = buffer.readInteger(as: UInt8.self),
let packetType = SDLPacketType(rawValue: type) else { let packetType = SDLPacketType(rawValue: type) else {
SDLLogger.shared.log("[SDLUDPHole] decode error 11: \(rawType)") SDLLogger.shared.log("[SDLUDPHole] decode error 11")
return nil return nil
} }
@ -159,6 +162,12 @@ final class SDLUDPHole: ChannelInboundHandler {
return nil return nil
} }
return .stunProbeReply(stunProbeReply) return .stunProbeReply(stunProbeReply)
case .stunReply:
guard let bytes = buffer.readBytes(length: buffer.readableBytes),
let stunReply = try? SDLStunReply(serializedBytes: bytes) else {
return nil
}
return .stunReply(stunReply)
default: default:
SDLLogger.shared.log("SDLUDPHole decode miss type: \(type)") SDLLogger.shared.log("SDLUDPHole decode miss type: \(type)")

View File

@ -9,25 +9,17 @@ import Foundation
struct SystemConfig { struct SystemConfig {
// //
static let version = 1 static let version: Int = 1
static let version_name = "1.1" static let version_name = "1.1"
// static let serverHost = "punchnet.s5s8.com"
static let installedChannel = "MacAppStore"
// super // stunip
//static let superHost = "118.178.229.213" static let stunAssistHost = "punchnet.s5s8.com"
static let superHost = "punchnet.s5s8.com"
static let superPort = 18083
// stun
static let stunServers = "118.178.229.213:1365,1366;118.178.229.213:1365,1366"
//static let stunServers = "127.0.0.1:1265,1266;127.0.0.1:1265,1266"
static func getOptions(networkId: UInt32, networkDomain: String, ip: String, maskLen: UInt8, accessToken: String, identityId: UInt32, hostname: String, noticePort: Int) -> [String: NSObject]? { static func getOptions(networkId: UInt32, networkDomain: String, ip: String, maskLen: UInt8, accessToken: String, identityId: UInt32, hostname: String, noticePort: Int) -> [String: NSObject]? {
guard let superIp = DNSResolver.resolveAddrInfos(superHost).first else { guard let serverIp = DNSResolver.resolveAddrInfos(serverHost).first else {
return nil return nil
} }
@ -35,15 +27,12 @@ struct SystemConfig {
let mac = getMacAddress() let mac = getMacAddress()
let options = [ let options = [
"version:": version as NSObject, "version": version as NSObject,
"installed_channel": installedChannel as NSObject,
"client_id": clientId as NSObject, "client_id": clientId as NSObject,
"access_token": accessToken as NSObject, "access_token": accessToken as NSObject,
"identity_id": identityId as NSObject, "identity_id": identityId as NSObject,
"super_ip": superIp as NSObject, "server_ip": "118.178.229.213" as NSObject,
"super_port": superPort as NSObject, "stun_assist_ip": "118.178.229.213" as NSObject,
"stun_servers": stunServers as NSObject,
"remote_dns_server": superIp as NSObject,
"hostname": hostname as NSObject, "hostname": hostname as NSObject,
"notice_port": noticePort as NSObject, "notice_port": noticePort as NSObject,
"network_address": [ "network_address": [