punchnet-macos/Tun/DNS/DNSCloudService.swift
2026-05-28 16:03:04 +08:00

74 lines
1.8 KiB
Swift

import Foundation
actor DNSCloudService {
private let serverIP: String
private var onEvent: DNSEventHandler = { _ in }
private var currentClient: DNSCloudClient?
init(serverIP: String) {
self.serverIP = serverIP
}
func updateEventHandler(_ onEvent: @escaping DNSEventHandler) {
self.onEvent = onEvent
}
func run() async throws {
let client = DNSCloudClient(serverIP: self.serverIP, port: 15353)
self.currentClient = client
defer {
self.clearCurrent(client)
}
do {
let onEvent = self.onEvent
try await withThrowingTaskGroup(of: Void.self) { group in
defer {
group.cancelAll()
}
group.addTask {
try await client.run()
}
group.addTask {
for try await packet in client.packetFlow {
try Task.checkCancellation()
await onEvent(.packet(packet))
}
}
_ = try await group.next()
}
await client.stop()
} catch is CancellationError {
await client.stop()
throw CancellationError()
} catch {
await client.stop()
throw error
}
}
func stop() async {
let client = self.currentClient
self.currentClient = nil
await client?.stop()
}
func forward(ipPacketData: Data) async {
await self.currentClient?.forward(ipPacketData: ipPacketData)
}
private func clearCurrent(_ client: DNSCloudClient) {
if self.currentClient === client {
self.currentClient = nil
}
}
}