fix quic
This commit is contained in:
parent
2d6d640a44
commit
703d4e191f
@ -10,8 +10,8 @@ import Darwin
|
||||
actor ArpServerActor {
|
||||
private var known_macs: [UInt32:Data] = [:]
|
||||
|
||||
init(known_macs: [UInt32:Data]) {
|
||||
self.known_macs = known_macs
|
||||
init() {
|
||||
|
||||
}
|
||||
|
||||
func query(ip: UInt32) -> Data? {
|
||||
|
||||
@ -47,7 +47,7 @@ actor SDLContextActor {
|
||||
private var dnsWorker: Task<Void, Never>?
|
||||
|
||||
private var quicClient: SDLQUICClient?
|
||||
private var quicWorker: Task<Void, Never>?
|
||||
private var quicWorkers: [Task<Void, Never>]?
|
||||
|
||||
nonisolated private let puncherActor: SDLPuncherActor
|
||||
// 网络探测对象
|
||||
@ -78,6 +78,9 @@ actor SDLContextActor {
|
||||
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
|
||||
private let policyRequesterActor: PolicyRequesterActor
|
||||
|
||||
// 注册任务
|
||||
private var registerTask: Task<Void, Never>?
|
||||
|
||||
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher, aesCipher: AESCipher) {
|
||||
self.provider = provider
|
||||
self.config = config
|
||||
@ -85,7 +88,7 @@ actor SDLContextActor {
|
||||
self.aesCipher = aesCipher
|
||||
|
||||
self.sessionManager = SessionManager()
|
||||
self.arpServer = ArpServerActor(known_macs: [:])
|
||||
self.arpServer = ArpServerActor()
|
||||
|
||||
self.puncherActor = SDLPuncherActor(querySocketAddress: config.stunSocketAddress)
|
||||
self.proberActor = SDLNATProberActor(addressArray: config.stunProbeSocketAddressArray)
|
||||
@ -131,23 +134,28 @@ actor SDLContextActor {
|
||||
}
|
||||
|
||||
private func startQUICClient() async throws -> SDLQUICClient {
|
||||
self.quicWorker?.cancel()
|
||||
self.quicWorkers?.forEach {$0.cancel()}
|
||||
self.quicClient?.stop()
|
||||
|
||||
// 启动monitor
|
||||
let quicClient = SDLQUICClient(host: "118.178.229.213", port: 1365)
|
||||
let quicClient = SDLQUICClient(host: self.config.serverIp, port: 443)
|
||||
quicClient.start()
|
||||
|
||||
// 等待quic准备好
|
||||
try await quicClient.waitReady()
|
||||
// 这里必须等待quic的协商完成
|
||||
try await Task.sleep(for: .seconds(0.2))
|
||||
SDLLogger.shared.log("[SDLContext] start quic client ready")
|
||||
|
||||
self.quicWorker = Task.detached {
|
||||
let messageTask = Task.detached {
|
||||
for await message in quicClient.messageStream {
|
||||
switch message {
|
||||
case .welcome(let welcome):
|
||||
SDLLogger.shared.log("[SDLContext] quic welcome: \(welcome)")
|
||||
// 注册
|
||||
await self.startRegisterLoop()
|
||||
case .pong:
|
||||
SDLLogger.shared.log("[SDLContext] quic pong")
|
||||
case .registerSuperAck(let registerSuperAck):
|
||||
await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck)
|
||||
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
|
||||
}
|
||||
|
||||
private func startNoticeClient() throws -> SDLNoticeClient {
|
||||
// 启动noticeClient
|
||||
let noticeClient = try SDLNoticeClient(noticePort: self.config.noticePort, logger: SDLLogger.shared)
|
||||
let noticeClient = try SDLNoticeClient(noticePort: self.config.noticePort)
|
||||
noticeClient.start()
|
||||
|
||||
SDLLogger.shared.log("[SDLContext] noticeClient started")
|
||||
@ -196,7 +218,7 @@ actor SDLContextActor {
|
||||
switch event {
|
||||
case .changed:
|
||||
// 需要重新探测网络的nat类型
|
||||
//self.natType = await self.getNatType()
|
||||
await self.probeNatType()
|
||||
SDLLogger.shared.log("didNetworkPathChanged, nat type is:", level: .info)
|
||||
case .unreachable:
|
||||
SDLLogger.shared.log("didNetworkPathUnreachable", level: .warning)
|
||||
@ -210,7 +232,7 @@ actor SDLContextActor {
|
||||
self.dnsWorker = nil
|
||||
|
||||
// 启动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)
|
||||
try dnsClient.start()
|
||||
SDLLogger.shared.log("[SDLContext] dnsClient started")
|
||||
@ -246,11 +268,10 @@ actor SDLContextActor {
|
||||
|
||||
// 处理心跳逻辑
|
||||
let pingTask = Task.detached {
|
||||
let (stream, cont) = AsyncStream.makeStream(of: Void.self)
|
||||
let timerStream = SDLAsyncTimerStream()
|
||||
timerStream.start(cont)
|
||||
timerStream.start(interval: .seconds(5))
|
||||
|
||||
for await _ in stream {
|
||||
for await _ in timerStream.stream {
|
||||
if Task.isCancelled {
|
||||
break
|
||||
}
|
||||
@ -276,6 +297,8 @@ actor SDLContextActor {
|
||||
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
|
||||
case .data(let data):
|
||||
try? await self.handleData(data: data)
|
||||
case .stunReply(let stunReply):
|
||||
SDLLogger.shared.log("[SDLContext] get a stunReply: \(stunReply)")
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,12 +309,8 @@ actor SDLContextActor {
|
||||
self.udpHoleWorkers = [pingTask, messageTask]
|
||||
|
||||
// 开始探测nat的类型
|
||||
Task {
|
||||
let natType = await self.proberActor.probeNatType(using: udpHole)
|
||||
self.setNatType(natType: natType)
|
||||
SDLLogger.shared.log("[SDLContext] nat_type is: \(natType)")
|
||||
}
|
||||
|
||||
self.probeNatType()
|
||||
|
||||
return udpHole
|
||||
}
|
||||
|
||||
@ -303,6 +322,9 @@ actor SDLContextActor {
|
||||
self.udpHoleWorkers?.forEach { $0.cancel() }
|
||||
self.udpHoleWorkers = nil
|
||||
|
||||
self.quicWorkers?.forEach { $0.cancel() }
|
||||
self.quicWorkers = nil
|
||||
|
||||
self.dnsWorker?.cancel()
|
||||
self.dnsWorker = nil
|
||||
|
||||
@ -311,12 +333,34 @@ actor SDLContextActor {
|
||||
|
||||
self.readTask?.cancel()
|
||||
self.readTask = nil
|
||||
|
||||
self.registerTask?.cancel()
|
||||
self.registerTask = nil
|
||||
}
|
||||
|
||||
private func setNatType(natType: SDLNATProberActor.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() {
|
||||
guard let sessionToken = self.sessionToken else {
|
||||
return
|
||||
@ -423,20 +467,6 @@ actor SDLContextActor {
|
||||
if let registerSuperData = try? registerSuper.serializedData() {
|
||||
SDLLogger.shared.log("[SDLContext] will send register super")
|
||||
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 {
|
||||
// 向服务器请求权限逻辑
|
||||
if let sessionToken = self.sessionToken {
|
||||
var policyRequest = SDLPolicyRequest()
|
||||
policyRequest.srcIdentityID = data.identityID
|
||||
policyRequest.dstIdentityID = self.config.identityId
|
||||
|
||||
await self.policyRequesterActor.submitPolicyRequest(using: self.udpHole, request: &policyRequest)
|
||||
}
|
||||
var policyRequest = SDLPolicyRequest()
|
||||
policyRequest.srcIdentityID = data.identityID
|
||||
policyRequest.dstIdentityID = self.config.identityId
|
||||
|
||||
await self.policyRequesterActor.submitPolicyRequest(using: self.quicClient, request: &policyRequest)
|
||||
}
|
||||
default:
|
||||
SDLLogger.shared.log("[SDLContext] get invalid packet", level: .debug)
|
||||
@ -588,11 +616,10 @@ actor SDLContextActor {
|
||||
private func dealPacket(packet: IPPacket) async {
|
||||
let networkAddr = self.config.networkAddress
|
||||
|
||||
// TODO
|
||||
if SDLDNSClient.Helper.isDnsRequestPacket(ipPacket: packet) {
|
||||
let destIp = packet.header.destination_ip
|
||||
SDLLogger.shared.log("[DNSQuery] destIp: \(destIp), int: \(packet.header.destination.asIpAddress())", level: .debug)
|
||||
//self.dnsClient?.forward(ipPacket: packet)
|
||||
self.dnsClient?.forward(ipPacket: packet)
|
||||
return
|
||||
}
|
||||
|
||||
@ -654,7 +681,7 @@ actor SDLContextActor {
|
||||
|
||||
// 尝试打洞
|
||||
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> {
|
||||
return Task.detached {
|
||||
@ -714,13 +752,11 @@ actor SDLContextActor {
|
||||
// todo 测试代码
|
||||
private func triggerPolicy() async {
|
||||
// 向服务器请求权限逻辑
|
||||
if let sessionToken = self.sessionToken {
|
||||
var policyRequest = SDLPolicyRequest()
|
||||
policyRequest.srcIdentityID = 1234
|
||||
policyRequest.dstIdentityID = self.config.identityId
|
||||
|
||||
await self.policyRequesterActor.submitPolicyRequest(using: self.udpHole, request: &policyRequest)
|
||||
}
|
||||
var policyRequest = SDLPolicyRequest()
|
||||
policyRequest.srcIdentityID = 1234
|
||||
policyRequest.dstIdentityID = self.config.identityId
|
||||
|
||||
await self.policyRequesterActor.submitPolicyRequest(using: self.quicClient, request: &policyRequest)
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
@ -30,9 +30,9 @@ actor SDLPuncherActor {
|
||||
self.querySocketAddress = querySocketAddress
|
||||
}
|
||||
|
||||
func submitRegisterRequest(using udpHole: SDLUDPHole?, request: RegisterRequest) {
|
||||
func submitRegisterRequest(quicClient: SDLQUICClient?, request: RegisterRequest) {
|
||||
let dstMac = request.dstMac
|
||||
guard let udpHole, !coolingDown.contains(dstMac) else {
|
||||
guard let quicClient, !coolingDown.contains(dstMac) else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ actor SDLPuncherActor {
|
||||
if self.pktId == 0 {
|
||||
self.pktId = 1
|
||||
}
|
||||
//self.tryHole(using: udpHole, pktId: pktId, request: request)
|
||||
self.tryHole(using: quicClient, pktId: pktId, request: request)
|
||||
|
||||
Task {
|
||||
// 启动冷却期
|
||||
@ -54,22 +54,23 @@ actor SDLPuncherActor {
|
||||
}
|
||||
}
|
||||
|
||||
// func handlePeerInfo(using udpHole: SDLUDPHole, peerInfo: SDLPeerInfo) async {
|
||||
// if let request = pendingRequests.removeValue(forKey: peerInfo.pktID) {
|
||||
// if let remoteAddress = try? await peerInfo.v4Info.socketAddress() {
|
||||
// SDLLogger.shared.log("[SDLContext] hole sock address: \(remoteAddress)", level: .debug)
|
||||
// // 发送register包
|
||||
// var register = SDLRegister()
|
||||
// register.networkID = request.networkId
|
||||
// register.srcMac = request.srcMac
|
||||
// register.dstMac = request.dstMac
|
||||
//
|
||||
// udpHole.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress)
|
||||
// } else {
|
||||
// SDLLogger.shared.log("[SDLContext] hole sock address is invalid: \(peerInfo.v4Info)", level: .warning)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
func handlePeerInfo(using udpHole: SDLUDPHole, peerInfo: SDLPeerInfo) async {
|
||||
guard let request = pendingRequests.removeValue(forKey: peerInfo.pktID),
|
||||
let remoteAddress = try? await peerInfo.v4Info.socketAddress() else {
|
||||
return
|
||||
}
|
||||
|
||||
SDLLogger.shared.log("[SDLContext] hole sock address: \(remoteAddress)", level: .debug)
|
||||
// 发送register包
|
||||
var register = SDLRegister()
|
||||
register.networkID = request.networkId
|
||||
register.srcMac = request.srcMac
|
||||
register.dstMac = request.dstMac
|
||||
|
||||
if let registerData = try? register.serializedData() {
|
||||
udpHole.send(type: .register, data: registerData, remoteAddress: remoteAddress)
|
||||
}
|
||||
}
|
||||
|
||||
private func endCooldown(for key: Data) {
|
||||
self.coolingDown.remove(key)
|
||||
@ -79,14 +80,14 @@ actor SDLPuncherActor {
|
||||
self.pendingRequests.removeValue(forKey: pktId)
|
||||
}
|
||||
|
||||
// private func tryHole(using udpHole: SDLUDPHole, pktId: UInt32, request: RegisterRequest) {
|
||||
// var queryInfo = SDLQueryInfo()
|
||||
// queryInfo.pktID = pktId
|
||||
// queryInfo.dstMac = request.dstMac
|
||||
// self.pendingRequests[pktId] = request
|
||||
//
|
||||
// if let queryData = try? queryInfo.serializedData() {
|
||||
// udpHole.send(type: .queryInfo, data: queryData, remoteAddress: self.querySocketAddress)
|
||||
// }
|
||||
// }
|
||||
private func tryHole(using quicClient: SDLQUICClient, pktId: UInt32, request: RegisterRequest) {
|
||||
var queryInfo = SDLQueryInfo()
|
||||
queryInfo.pktID = pktId
|
||||
queryInfo.dstMac = request.dstMac
|
||||
self.pendingRequests[pktId] = request
|
||||
|
||||
if let queryData = try? queryInfo.serializedData() {
|
||||
quicClient.send(type: .queryInfo, data: queryData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ final class SDLQUICClient {
|
||||
public var messageStream: AsyncStream<SDLQUICInboundMessage>
|
||||
private let messageCont: AsyncStream<SDLQUICInboundMessage>.Continuation
|
||||
private var readTask: Task<Void, Never>?
|
||||
|
||||
|
||||
private let connection: NWConnection
|
||||
private let queue = DispatchQueue(label: "com.sdl.QUICClient.queue") // 专用队列保证线程安全
|
||||
|
||||
@ -102,6 +102,7 @@ final class SDLQUICClient {
|
||||
self.messageCont.finish()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func send(type: SDLPacketType, data: Data) {
|
||||
@ -240,6 +241,8 @@ final class SDLQUICClient {
|
||||
}
|
||||
return .event(.networkShutdown(networkShutdownEvent))
|
||||
}
|
||||
case .pong:
|
||||
return .pong
|
||||
default:
|
||||
SDLLogger.shared.log("SDLUDPHole decode miss type: \(type)")
|
||||
|
||||
|
||||
@ -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
|
||||
guard let udpHole, !coolingDown.contains(identityId) else {
|
||||
guard let quicClient, !coolingDown.contains(identityId) else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ actor PolicyRequesterActor {
|
||||
self.versions[identityId] = version + 1
|
||||
// 发送请求
|
||||
if let queryData = try? request.serializedData() {
|
||||
udpHole.send(type: .policyRequest, data: queryData, remoteAddress: self.querySocketAddress)
|
||||
quicClient.send(type: .policyRequest, data: queryData)
|
||||
}
|
||||
|
||||
Task {
|
||||
|
||||
@ -9,15 +9,18 @@ import Foundation
|
||||
|
||||
class SDLAsyncTimerStream {
|
||||
let timer: DispatchSourceTimer
|
||||
let stream: AsyncStream<Void>
|
||||
private let cont: AsyncStream<Void>.Continuation
|
||||
|
||||
init() {
|
||||
self.timer = DispatchSource.makeTimerSource(queue: .global())
|
||||
(stream, cont) = AsyncStream.makeStream(of: Void.self)
|
||||
}
|
||||
|
||||
func start(_ cont: AsyncStream<Void>.Continuation) {
|
||||
timer.schedule(deadline: .now(), repeating: .seconds(5))
|
||||
func start(interval: DispatchTimeInterval) {
|
||||
timer.schedule(deadline: .now(), repeating: interval)
|
||||
timer.setEventHandler {
|
||||
cont.yield()
|
||||
self.cont.yield()
|
||||
}
|
||||
timer.resume()
|
||||
}
|
||||
|
||||
@ -9,16 +9,6 @@ import NIOCore
|
||||
|
||||
// 配置项目
|
||||
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 let networkId: UInt32
|
||||
public let ip: UInt32
|
||||
@ -49,30 +39,24 @@ public class SDLConfiguration {
|
||||
}
|
||||
|
||||
// 当前的客户端版本
|
||||
let version: UInt8
|
||||
let version: Int
|
||||
|
||||
// 安装渠道
|
||||
let installedChannel: String
|
||||
let serverIp: String
|
||||
let stunServers: [String]
|
||||
|
||||
let superHost: String
|
||||
let superPort: Int
|
||||
|
||||
let stunServers: [StunServer]
|
||||
|
||||
let remoteDnsServer: String
|
||||
let noticePort: Int
|
||||
|
||||
lazy var stunSocketAddress: SocketAddress = {
|
||||
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]] = {
|
||||
return stunServers.map { stunServer in
|
||||
[
|
||||
try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[0]),
|
||||
try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[1])
|
||||
try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1365),
|
||||
try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1366)
|
||||
]
|
||||
}
|
||||
}()
|
||||
@ -83,30 +67,24 @@ public class SDLConfiguration {
|
||||
let accessToken: String
|
||||
let identityId: UInt32
|
||||
|
||||
public init(version: UInt8,
|
||||
installedChannel: String,
|
||||
superHost: String,
|
||||
superPort: Int,
|
||||
stunServers: [StunServer],
|
||||
public init(version: Int,
|
||||
serverIp: String,
|
||||
stunServers: [String],
|
||||
clientId: String,
|
||||
networkAddress: NetworkAddress,
|
||||
hostname: String,
|
||||
noticePort: Int,
|
||||
accessToken: String,
|
||||
identityId: UInt32,
|
||||
remoteDnsServer: String) {
|
||||
identityId: UInt32) {
|
||||
|
||||
self.version = version
|
||||
self.installedChannel = installedChannel
|
||||
self.superHost = superHost
|
||||
self.superPort = superPort
|
||||
self.serverIp = serverIp
|
||||
self.stunServers = stunServers
|
||||
self.clientId = clientId
|
||||
self.networkAddress = networkAddress
|
||||
self.noticePort = noticePort
|
||||
self.accessToken = accessToken
|
||||
self.identityId = identityId
|
||||
self.remoteDnsServer = remoteDnsServer
|
||||
self.hostname = hostname
|
||||
}
|
||||
}
|
||||
@ -115,60 +93,36 @@ public class SDLConfiguration {
|
||||
extension SDLConfiguration {
|
||||
|
||||
static func parse(options: [String: NSObject]) -> SDLConfiguration? {
|
||||
guard 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,
|
||||
guard let version = options["version"] as? Int,
|
||||
let serverIp = options["server_ip"] as? String,
|
||||
let stunAssistIp = options["stun_assist_ip"] as? String,
|
||||
let noticePort = options["notice_port"] as? Int,
|
||||
let accessToken = options["access_token"] as? String,
|
||||
let identityId = options["identity_id"] as? UInt32,
|
||||
let clientId = options["client_id"] as? String,
|
||||
let remoteDnsServer = options["remote_dns_server"] as? String,
|
||||
let hostname = options["hostname"] as? String,
|
||||
let networkAddressDict = options["network_address"] as? [String: NSObject] else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let stunServers = parseStunServers(stunServersStr: stunServersStr), stunServers.count >= 2 else {
|
||||
NSLog("stunServers配置错误")
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let networkAddress = parseNetworkAddress(networkAddressDict) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return SDLConfiguration(version: 1,
|
||||
installedChannel: installed_channel,
|
||||
superHost: superIp,
|
||||
superPort: superPort,
|
||||
|
||||
let stunServers: [String] = [
|
||||
serverIp,
|
||||
stunAssistIp
|
||||
]
|
||||
|
||||
return SDLConfiguration(version: version,
|
||||
serverIp: serverIp,
|
||||
stunServers: stunServers,
|
||||
clientId: clientId,
|
||||
networkAddress: networkAddress,
|
||||
hostname: hostname,
|
||||
noticePort: noticePort,
|
||||
accessToken: accessToken,
|
||||
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
|
||||
identityId: identityId)
|
||||
}
|
||||
|
||||
private static func parseNetworkAddress(_ config: [String: NSObject]) -> SDLConfiguration.NetworkAddress? {
|
||||
|
||||
@ -21,6 +21,10 @@ enum SDLPacketType: UInt8 {
|
||||
case queryInfo = 0x06
|
||||
case peerInfo = 0x07
|
||||
|
||||
// 心跳机制
|
||||
case ping = 0x08
|
||||
case pong = 0x09
|
||||
|
||||
// 事件类型
|
||||
case event = 0x10
|
||||
|
||||
@ -28,7 +32,8 @@ enum SDLPacketType: UInt8 {
|
||||
case registerAck = 0x21
|
||||
|
||||
case stunRequest = 0x30
|
||||
|
||||
case stunReply = 0x31
|
||||
|
||||
case stunProbe = 0x32
|
||||
case stunProbeReply = 0x33
|
||||
|
||||
@ -99,12 +104,15 @@ enum SDLHoleMessage {
|
||||
case register(SDLRegister)
|
||||
case registerAck(SDLRegisterAck)
|
||||
case stunProbeReply(SDLStunProbeReply)
|
||||
case stunReply(SDLStunReply)
|
||||
}
|
||||
|
||||
enum SDLQUICInboundMessage {
|
||||
// 欢迎消息
|
||||
case welcome(SDLWelcome)
|
||||
|
||||
case pong
|
||||
|
||||
// 注册相关
|
||||
case registerSuperAck(SDLRegisterSuperAck)
|
||||
case registerSuperNak(SDLRegisterSuperNak)
|
||||
|
||||
@ -25,12 +25,10 @@ final class SDLNoticeClient {
|
||||
private var task: Task<Void, Never>?
|
||||
|
||||
private var channel: Channel
|
||||
private let logger: SDLLogger
|
||||
private let noticePort: Int
|
||||
|
||||
// 启动函数
|
||||
init(noticePort: Int, logger: SDLLogger) throws {
|
||||
self.logger = logger
|
||||
init(noticePort: Int) throws {
|
||||
self.noticePort = noticePort
|
||||
|
||||
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.logger.log("[SDLNoticeClient] started", level: .debug)
|
||||
SDLLogger.shared.log("[SDLNoticeClient] started", level: .debug)
|
||||
}
|
||||
|
||||
func start() {
|
||||
|
||||
@ -84,6 +84,11 @@ final class SDLUDPHole: ChannelInboundHandler {
|
||||
|
||||
var buffer = envelope.data
|
||||
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 {
|
||||
if let message = try decode(buffer: &buffer) {
|
||||
self.messageContinuation.yield((remoteAddress, message))
|
||||
@ -126,11 +131,9 @@ final class SDLUDPHole: ChannelInboundHandler {
|
||||
|
||||
// --MARK: 编解码器
|
||||
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),
|
||||
let packetType = SDLPacketType(rawValue: type) else {
|
||||
SDLLogger.shared.log("[SDLUDPHole] decode error 11: \(rawType)")
|
||||
SDLLogger.shared.log("[SDLUDPHole] decode error 11")
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -159,6 +162,12 @@ final class SDLUDPHole: ChannelInboundHandler {
|
||||
return nil
|
||||
}
|
||||
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:
|
||||
SDLLogger.shared.log("SDLUDPHole decode miss type: \(type)")
|
||||
|
||||
|
||||
@ -9,25 +9,17 @@ import Foundation
|
||||
|
||||
struct SystemConfig {
|
||||
// 版本设置
|
||||
static let version = 1
|
||||
static let version: Int = 1
|
||||
|
||||
static let version_name = "1.1"
|
||||
|
||||
// 安装渠道
|
||||
static let installedChannel = "MacAppStore"
|
||||
static let serverHost = "punchnet.s5s8.com"
|
||||
|
||||
// super 节点
|
||||
//static let superHost = "118.178.229.213"
|
||||
|
||||
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"
|
||||
// stun探测辅助服务器ip
|
||||
static let stunAssistHost = "punchnet.s5s8.com"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -35,15 +27,12 @@ struct SystemConfig {
|
||||
let mac = getMacAddress()
|
||||
|
||||
let options = [
|
||||
"version:": version as NSObject,
|
||||
"installed_channel": installedChannel as NSObject,
|
||||
"version": version as NSObject,
|
||||
"client_id": clientId as NSObject,
|
||||
"access_token": accessToken as NSObject,
|
||||
"identity_id": identityId as NSObject,
|
||||
"super_ip": superIp as NSObject,
|
||||
"super_port": superPort as NSObject,
|
||||
"stun_servers": stunServers as NSObject,
|
||||
"remote_dns_server": superIp as NSObject,
|
||||
"server_ip": "118.178.229.213" as NSObject,
|
||||
"stun_assist_ip": "118.178.229.213" as NSObject,
|
||||
"hostname": hostname as NSObject,
|
||||
"notice_port": noticePort as NSObject,
|
||||
"network_address": [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user