fix SDLIPV6AssistClient
This commit is contained in:
parent
fb60f1ab68
commit
720bf3549a
148
Tun/Punchnet/SDLIPV6AssistClient.swift
Normal file
148
Tun/Punchnet/SDLIPV6AssistClient.swift
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
//
|
||||||
|
// SDLDNSClient 2.swift
|
||||||
|
// punchnet
|
||||||
|
//
|
||||||
|
// Created by 安礼成 on 2026/4/9.
|
||||||
|
//
|
||||||
|
import Foundation
|
||||||
|
import Network
|
||||||
|
|
||||||
|
actor SDLIPV6AssistClient {
|
||||||
|
private enum State {
|
||||||
|
case idle
|
||||||
|
case running
|
||||||
|
case stopped
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: State = .idle
|
||||||
|
private var connection: NWConnection?
|
||||||
|
private var receiveTask: Task<Void, Never>?
|
||||||
|
private let assistServerAddress: NWEndpoint
|
||||||
|
|
||||||
|
init(host: String, port: UInt16 ) {
|
||||||
|
self.assistServerAddress = .hostPort(host: NWEndpoint.Host(host), port: NWEndpoint.Port(integerLiteral: port))
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
guard case .idle = self.state else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state = .running
|
||||||
|
|
||||||
|
// 1. 配置参数:这是解决环路的关键
|
||||||
|
let parameters = NWParameters.udp
|
||||||
|
|
||||||
|
// 禁止此连接走 TUN 网卡(在 NE 中 TUN 通常被归类为 .other)
|
||||||
|
parameters.prohibitedInterfaceTypes = [.other]
|
||||||
|
// 2. 增强健壮性:启用多路径切换(替代 pathSelectionOptions 的意图)
|
||||||
|
parameters.multipathServiceType = .handover
|
||||||
|
|
||||||
|
// 2. 创建连接
|
||||||
|
let connection = NWConnection(to: self.assistServerAddress, using: parameters)
|
||||||
|
self.connection = connection
|
||||||
|
|
||||||
|
connection.stateUpdateHandler = { [weak self] state in
|
||||||
|
Task {
|
||||||
|
await self?.handleConnectionStateUpdate(state, for: connection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动连接队列
|
||||||
|
connection.start(queue: .global())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 接收数据的递归循环
|
||||||
|
private static func makeReceiveStream(for connection: NWConnection) -> AsyncStream<Data> {
|
||||||
|
return AsyncStream(bufferingPolicy: .bufferingNewest(256)) { continuation in
|
||||||
|
func receiveNext() {
|
||||||
|
connection.receiveMessage { content, _, _, error in
|
||||||
|
if let data = content, !data.isEmpty {
|
||||||
|
// 将收到的 DNS 响应写回 AsyncStream
|
||||||
|
continuation.yield(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if error == nil && connection.state == .ready {
|
||||||
|
receiveNext() // 继续监听下一个包
|
||||||
|
} else {
|
||||||
|
continuation.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
receiveNext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 发送 DNS 查询包(由 TUN 拦截到的原始 IP 包数据)
|
||||||
|
func forward(ipPacketData: Data) {
|
||||||
|
guard case .running = self.state, let connection = self.connection, connection.state == .ready else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.send(content: ipPacketData, completion: .contentProcessed { error in
|
||||||
|
if let error = error {
|
||||||
|
SDLLogger.log("[SDLIPV6AssistClient] Send error: \(error)", for: .debug)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
guard self.state != .stopped else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state = .stopped
|
||||||
|
self.receiveTask?.cancel()
|
||||||
|
self.receiveTask = nil
|
||||||
|
self.connection?.cancel()
|
||||||
|
self.connection = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleConnectionStateUpdate(_ state: NWConnection.State, for connection: NWConnection) {
|
||||||
|
guard case .running = self.state else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch state {
|
||||||
|
case .ready:
|
||||||
|
SDLLogger.log("[SDLIPV6AssistClient] Connection ready", for: .debug)
|
||||||
|
self.startReceiveTask(for: connection)
|
||||||
|
case .failed(let error):
|
||||||
|
SDLLogger.log("[SDLIPV6AssistClient] Connection failed: \(error)", for: .debug)
|
||||||
|
self.stop()
|
||||||
|
case .cancelled:
|
||||||
|
self.stop()
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func startReceiveTask(for connection: NWConnection) {
|
||||||
|
guard self.receiveTask == nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let stream = Self.makeReceiveStream(for: connection)
|
||||||
|
self.receiveTask = Task { [weak self] in
|
||||||
|
for await data in stream {
|
||||||
|
guard let self else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
await self.handleReceivedPacket(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleReceivedPacket(_ data: Data) {
|
||||||
|
guard case .running = self.state else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog("data: \(data)")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.connection?.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user