add fatal log

This commit is contained in:
anlicheng 2026-05-28 16:32:34 +08:00
parent 6714d22137
commit 47e45bbec4
24 changed files with 172 additions and 170 deletions

View File

@ -145,11 +145,11 @@ actor SDLContextActor {
try await self.runRootBody() try await self.runRootBody()
await self.cleanupRoot() await self.cleanupRoot()
} catch is CancellationError { } catch is CancellationError {
SDLLogger.fatal("[SDLContext] root task cancelled") SDLLogger.fatal("[SDLContext] root task cancelled", category: .context)
await self.cleanupRoot() await self.cleanupRoot()
throw CancellationError() throw CancellationError()
} catch { } catch {
SDLLogger.fatal("[SDLContext] root task failed: \(error)") SDLLogger.fatal("[SDLContext] root task failed: \(error)", category: .context)
await self.readySignal.fail(error) await self.readySignal.fail(error)
await self.cleanupRoot() await self.cleanupRoot()
throw error throw error
@ -160,7 +160,7 @@ actor SDLContextActor {
do { do {
try await self.readySignal.wait(timeout: .seconds(30)) try await self.readySignal.wait(timeout: .seconds(30))
} catch { } catch {
SDLLogger.fatal("[SDLContext] start failed while waiting ready signal: \(error)") SDLLogger.fatal("[SDLContext] start failed while waiting ready signal: \(error)", category: .context)
rootTask.cancel() rootTask.cancel()
_ = try? await rootTask.value _ = try? await rootTask.value
self.rootTask = nil self.rootTask = nil
@ -170,7 +170,7 @@ actor SDLContextActor {
// context // context
public func stop() async { public func stop() async {
SDLLogger.fatal("[SDLContext] stop requested") SDLLogger.fatal("[SDLContext] stop requested", category: .context)
let rootTask = self.rootTask let rootTask = self.rootTask
self.rootTask = nil self.rootTask = nil
@ -286,7 +286,7 @@ actor SDLContextActor {
group.addTask { group.addTask {
_ = try await readySignal.wait() _ = try await readySignal.wait()
try await Self.runPeriodic(name: "updatePolicyTask", interval: .seconds(10)) { try await Self.runPeriodic(name: "updatePolicyTask", interval: .seconds(10)) {
SDLLogger.log("[SDLContext] updatePolicyTask execute") SDLLogger.log("[SDLContext] updatePolicyTask execute", category: .context)
await policyService.updatePolicy(superService: superService) await policyService.updatePolicy(superService: superService)
} }
} }
@ -313,7 +313,7 @@ actor SDLContextActor {
} }
guard let client = SDLIPV6AssistClient(assistServerInfo: assistInfo) else { guard let client = SDLIPV6AssistClient(assistServerInfo: assistInfo) else {
SDLLogger.log("[SDLContext] invalid ipv6 assist config", for: .debug) SDLLogger.log("[SDLContext] invalid ipv6 assist config", category: .context)
continue continue
} }
@ -324,7 +324,7 @@ actor SDLContextActor {
} catch is CancellationError { } catch is CancellationError {
throw CancellationError() throw CancellationError()
} catch { } catch {
SDLLogger.log("[SDLContext] ipv6 assist client ended: \(error.localizedDescription)", for: .debug) SDLLogger.log("[SDLContext] ipv6 assist client ended: \(error.localizedDescription)", category: .context)
} }
if self.ipv6AssistClient === client { if self.ipv6AssistClient === client {
@ -371,7 +371,7 @@ actor SDLContextActor {
} }
deinit { deinit {
SDLLogger.log("[SDLContext] deinit", for: .debug) SDLLogger.log("[SDLContext] deinit", category: .context)
} }
} }
@ -391,7 +391,7 @@ extension SDLContextActor {
// UDP NoticeClient App Group // UDP NoticeClient App Group
SDLTunnelAppNotifier.shared.clear() SDLTunnelAppNotifier.shared.clear()
SDLLogger.log("[SDLContext] tunnelAppNotifier ready") SDLLogger.log("[SDLContext] tunnelAppNotifier ready", category: .context)
} }
private func publishTunnelEvent(code: Int? = nil, message: String) { private func publishTunnelEvent(code: Int? = nil, message: String) {
@ -407,7 +407,7 @@ extension SDLContextActor {
case .v6: case .v6:
await self.udpHoleV6Service.send(type: type, data: data, remoteAddress: remoteAddress) await self.udpHoleV6Service.send(type: type, data: data, remoteAddress: remoteAddress)
default: default:
SDLLogger.log("[SDLContext] unsupported socket family: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLContext] unsupported socket family: \(remoteAddress)", category: .context)
} }
} }
@ -438,7 +438,7 @@ extension SDLContextActor {
case .requestExposedService: case .requestExposedService:
await self.requestExposedService() await self.requestExposedService()
case .shutdown(let message): case .shutdown(let message):
SDLLogger.fatal("[SDLContext] Super shutdown received: \(message)") SDLLogger.fatal("[SDLContext] Super shutdown received: \(message)", category: .context)
self.publishTunnelEvent(message: message) self.publishTunnelEvent(message: message)
let error = NSError(domain: "com.jihe.punchnet.tun", code: -2) let error = NSError(domain: "com.jihe.punchnet.tun", code: -2)
self.provider.cancelTunnelWithError(error) self.provider.cancelTunnelWithError(error)
@ -458,17 +458,17 @@ extension SDLContextActor {
do { do {
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer) try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
SDLLogger.log("[SDLContext] setNetworkSettings successed") SDLLogger.log("[SDLContext] setNetworkSettings successed", category: .context)
await self.readySignal.succeed(()) await self.readySignal.succeed(())
} catch { } catch {
SDLLogger.fatal("[SDLContext] apply tunnel network settings failed: \(error)") SDLLogger.fatal("[SDLContext] apply tunnel network settings failed: \(error)", category: .context)
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(error)") SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(error)", category: .context)
await self.failTunnel(error) await self.failTunnel(error)
} }
} }
private func failTunnel(_ error: Error) async { private func failTunnel(_ error: Error) async {
SDLLogger.fatal("[SDLContext] failTunnel: \(error)") SDLLogger.fatal("[SDLContext] failTunnel: \(error)", category: .context)
await self.readySignal.fail(error) await self.readySignal.fail(error)
self.provider.cancelTunnelWithError(error) self.provider.cancelTunnelWithError(error)
} }
@ -525,9 +525,9 @@ extension SDLContextActor {
let probeReply = try? await self.ipv6AssistClient?.probe(requestTimeout: .seconds(3)) let probeReply = try? await self.ipv6AssistClient?.probe(requestTimeout: .seconds(3))
if let v6Info = probeReply?.v6Info, let v6Address = SDLUtil.ipv6DataToString(v6Info.v6) { if let v6Info = probeReply?.v6Info, let v6Address = SDLUtil.ipv6DataToString(v6Info.v6) {
SDLLogger.log("[SDLContext] probe ipv6 address: \(v6Address)") SDLLogger.log("[SDLContext] probe ipv6 address: \(v6Address)", category: .context)
} else { } else {
SDLLogger.log("[SDLContext] probe ipv6 address: empty") SDLLogger.log("[SDLContext] probe ipv6 address: empty", category: .context)
} }
await self.superControlPlane.sendStunRequest(natType: self.natType, v6Info: probeReply?.v6Info) await self.superControlPlane.sendStunRequest(natType: self.natType, v6Info: probeReply?.v6Info)
@ -561,12 +561,12 @@ extension SDLContextActor {
do { do {
try Task.checkCancellation() try Task.checkCancellation()
try await operation() try await operation()
SDLLogger.log("[SDLContext] worker \(name) ended, will restart", for: .debug) SDLLogger.log("[SDLContext] worker \(name) ended, will restart", category: .context)
} catch is CancellationError { } catch is CancellationError {
SDLLogger.log("[SDLContext] worker \(name) cancelled", for: .debug) SDLLogger.log("[SDLContext] worker \(name) cancelled", category: .context)
throw CancellationError() throw CancellationError()
} catch { } catch {
SDLLogger.log("[SDLContext] worker \(name) crashed: \(error.localizedDescription), will restart", for: .debug) SDLLogger.log("[SDLContext] worker \(name) crashed: \(error.localizedDescription), will restart", category: .context)
} }
try await Task.sleep(for: retryDelay) try await Task.sleep(for: retryDelay)
@ -585,10 +585,10 @@ extension SDLContextActor {
try await operation() try await operation()
try await Task.sleep(for: interval) try await Task.sleep(for: interval)
} catch is CancellationError { } catch is CancellationError {
SDLLogger.log("[SDLContext] worker \(name) cancelled", for: .debug) SDLLogger.log("[SDLContext] worker \(name) cancelled", category: .context)
throw CancellationError() throw CancellationError()
} catch { } catch {
SDLLogger.log("[SDLContext] worker \(name) crashed: \(error.localizedDescription), will retry", for: .debug) SDLLogger.log("[SDLContext] worker \(name) crashed: \(error.localizedDescription), will retry", category: .context)
try await Task.sleep(for: retryDelay) try await Task.sleep(for: retryDelay)
} }
} }

View File

@ -24,17 +24,17 @@ struct SDLHoleControlPlane {
func handle(_ event: SDLUDPHoleService.Event) -> [HoleDecision] { func handle(_ event: SDLUDPHoleService.Event) -> [HoleDecision] {
switch event { switch event {
case .ready(let localAddress): case .ready(let localAddress):
SDLLogger.log("[SDLContext] udpHole ready: \(localAddress)") SDLLogger.log("[SDLContext] udpHole ready: \(localAddress)", category: .udpHole)
return [] return []
case .natType(let natType): case .natType(let natType):
SDLLogger.log("[SDLContext] nat_type is: \(natType)") SDLLogger.log("[SDLContext] nat_type is: \(natType)", category: .udpHole)
return [ return [
.updateNatType(natType) .updateNatType(natType)
] ]
case .packet(let remoteAddress, let message): case .packet(let remoteAddress, let message):
return self.handlePacket(remoteAddress: remoteAddress, message: message) return self.handlePacket(remoteAddress: remoteAddress, message: message)
case .closed(let error): case .closed(let error):
SDLLogger.log("[SDLContext] udpHole closed: \(error)", for: .debug) SDLLogger.log("[SDLContext] udpHole closed: \(error)", category: .udpHole)
return [] return []
} }
} }
@ -42,7 +42,7 @@ struct SDLHoleControlPlane {
private func handlePacket(remoteAddress: SocketAddress, message: SDLHoleControlMessage) -> [HoleDecision] { private func handlePacket(remoteAddress: SocketAddress, message: SDLHoleControlMessage) -> [HoleDecision] {
switch message { switch message {
case .stunReply, .stunProbeReply: case .stunReply, .stunProbeReply:
SDLLogger.log("[SDLContext] get a stun reply", for: .debug) SDLLogger.log("[SDLContext] get a stun reply", category: .udpHole)
return [] return []
case .register(let register): case .register(let register):
return self.handleRegister(remoteAddress: remoteAddress, register: register) return self.handleRegister(remoteAddress: remoteAddress, register: register)
@ -52,11 +52,11 @@ struct SDLHoleControlPlane {
} }
private func handleRegister(remoteAddress: SocketAddress, register: SDLRegister) -> [HoleDecision] { private func handleRegister(remoteAddress: SocketAddress, register: SDLRegister) -> [HoleDecision] {
SDLLogger.log("[SDLContext] register packet: \(register), network_address: \(self.networkAddress)") SDLLogger.log("[SDLContext] register packet: \(register), network_address: \(self.networkAddress)", category: .udpHole)
var decisions: [HoleDecision] = [] var decisions: [HoleDecision] = []
guard register.dstMac == self.networkAddress.mac && register.networkID == self.networkAddress.networkId else { guard register.dstMac == self.networkAddress.mac && register.networkID == self.networkAddress.networkId else {
SDLLogger.log("[SDLContext] didReadRegister get a invalid packet, because dst_ip not matched: \(register.dstMac)") SDLLogger.log("[SDLContext] didReadRegister get a invalid packet, because dst_ip not matched: \(register.dstMac)", category: .udpHole)
return decisions return decisions
} }
@ -72,7 +72,7 @@ struct SDLHoleControlPlane {
if let session = self.makeSession(dstMac: register.srcMac, remoteAddress: remoteAddress) { if let session = self.makeSession(dstMac: register.srcMac, remoteAddress: remoteAddress) {
decisions.append(.addSession(session)) decisions.append(.addSession(session))
} else { } else {
SDLLogger.log("[SDLContext] didReadRegister get unsupported remoteAddress: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLContext] didReadRegister get unsupported remoteAddress: \(remoteAddress)", category: .udpHole)
} }
return decisions return decisions
@ -80,12 +80,12 @@ struct SDLHoleControlPlane {
private func handleRegisterAck(remoteAddress: SocketAddress, registerAck: SDLRegisterAck) -> [HoleDecision] { private func handleRegisterAck(remoteAddress: SocketAddress, registerAck: SDLRegisterAck) -> [HoleDecision] {
guard registerAck.dstMac == self.networkAddress.mac && registerAck.networkID == self.networkAddress.networkId else { guard registerAck.dstMac == self.networkAddress.mac && registerAck.networkID == self.networkAddress.networkId else {
SDLLogger.log("[SDLContext] didReadRegisterAck get a invalid packet, because dst_mac not matched: \(registerAck.dstMac)", for: .debug) SDLLogger.log("[SDLContext] didReadRegisterAck get a invalid packet, because dst_mac not matched: \(registerAck.dstMac)", category: .udpHole)
return [] return []
} }
guard let session = self.makeSession(dstMac: registerAck.srcMac, remoteAddress: remoteAddress) else { guard let session = self.makeSession(dstMac: registerAck.srcMac, remoteAddress: remoteAddress) else {
SDLLogger.log("[SDLContext] didReadRegisterAck get unsupported remoteAddress: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLContext] didReadRegisterAck get unsupported remoteAddress: \(remoteAddress)", category: .udpHole)
return [] return []
} }

View File

@ -56,7 +56,7 @@ actor SDLSuperControlPlane {
case .registerSuperNak(let registerSuperNak): case .registerSuperNak(let registerSuperNak):
await self.handleRegisterSuperNak(registerSuperNak) await self.handleRegisterSuperNak(registerSuperNak)
case .peerInfo(let peerInfo): case .peerInfo(let peerInfo):
SDLLogger.log("[SDLContext] peer message: \(peerInfo)") SDLLogger.log("[SDLContext] peer message: \(peerInfo)", category: .super)
await self.onDecision(.resolvePeerInfo(peerInfo)) await self.onDecision(.resolvePeerInfo(peerInfo))
case .event(let event): case .event(let event):
await self.handleEvent(event) await self.handleEvent(event)
@ -65,7 +65,7 @@ actor SDLSuperControlPlane {
case .exposedServiceResponse(let response): case .exposedServiceResponse(let response):
await self.onDecision(.applyExposedServiceResponse(response)) await self.onDecision(.applyExposedServiceResponse(response))
case .arpResponse(let arpResponse): case .arpResponse(let arpResponse):
SDLLogger.log("[SDLContext] get arp response: \(arpResponse)") SDLLogger.log("[SDLContext] get arp response: \(arpResponse)", category: .super)
await self.onDecision(.handleARPResponse(arpResponse)) await self.onDecision(.handleARPResponse(arpResponse))
} }
} }
@ -93,7 +93,7 @@ actor SDLSuperControlPlane {
} }
private func handleWelcome(_ welcome: SDLWelcome) async { private func handleWelcome(_ welcome: SDLWelcome) async {
SDLLogger.log("[SDLContext] quic welcome: \(welcome)") SDLLogger.log("[SDLContext] quic welcome: \(welcome)", category: .super)
if welcome.hasIpv6Assist { if welcome.hasIpv6Assist {
await self.onDecision(.updateIPv6Assist(welcome.ipv6Assist)) await self.onDecision(.updateIPv6Assist(welcome.ipv6Assist))
@ -102,13 +102,13 @@ actor SDLSuperControlPlane {
} }
await self.doRegisterSuper() await self.doRegisterSuper()
SDLLogger.log("[SDLContext] quic doRegisterSuper") SDLLogger.log("[SDLContext] quic doRegisterSuper", category: .super)
} }
private func handleRegisterSuperAck(_ registerSuperAck: SDLRegisterSuperAck) async { private func handleRegisterSuperAck(_ registerSuperAck: SDLRegisterSuperAck) async {
guard let key = try? self.rsaCipher.decode(data: Data(registerSuperAck.key)) else { guard let key = try? self.rsaCipher.decode(data: Data(registerSuperAck.key)) else {
SDLLogger.fatal("[SDLSuperControlPlane] registerSuperAck invalid key, will fail tunnel") SDLLogger.fatal("[SDLSuperControlPlane] registerSuperAck invalid key, will fail tunnel", category: .super)
SDLLogger.log("[SDLContext] registerSuperAck invalid key") SDLLogger.log("[SDLContext] registerSuperAck invalid key", category: .super)
await self.onDecision(.failTunnel(SDLError.invalidKey)) await self.onDecision(.failTunnel(SDLError.invalidKey))
return return
} }
@ -124,13 +124,13 @@ actor SDLSuperControlPlane {
case "chacha20": case "chacha20":
cipher = CCChaCha20Cipher(regionId: regionId, keyData: key) cipher = CCChaCha20Cipher(regionId: regionId, keyData: key)
default: default:
SDLLogger.fatal("[SDLSuperControlPlane] unsupported cipher algorithm \(algorithm), will fail tunnel") SDLLogger.fatal("[SDLSuperControlPlane] unsupported cipher algorithm \(algorithm), will fail tunnel", category: .super)
SDLLogger.log("[SDLContext] registerSuperAck invalid algorithm \(algorithm)") SDLLogger.log("[SDLContext] registerSuperAck invalid algorithm \(algorithm)", category: .super)
await self.onDecision(.failTunnel(SDLError.unsupportedAlgorithm(algorithm: algorithm))) await self.onDecision(.failTunnel(SDLError.unsupportedAlgorithm(algorithm: algorithm)))
return return
} }
SDLLogger.log("[SDLContext] registerSuperAck, use algorithm \(algorithm), key len: \(key.count)") SDLLogger.log("[SDLContext] registerSuperAck, use algorithm \(algorithm), key len: \(key.count)", category: .super)
await self.onDecision(.completeRegistration(cipher: cipher)) await self.onDecision(.completeRegistration(cipher: cipher))
} }
@ -142,29 +142,29 @@ actor SDLSuperControlPlane {
switch errorCode { switch errorCode {
case .invalidToken, .nodeDisabled: case .invalidToken, .nodeDisabled:
SDLLogger.fatal("[SDLSuperControlPlane] SuperNak \(errorCode) will fail tunnel: \(errorMessage)") SDLLogger.fatal("[SDLSuperControlPlane] SuperNak \(errorCode) will fail tunnel: \(errorMessage)", category: .super)
await self.onDecision(.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage)) await self.onDecision(.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage))
await self.onDecision(.failTunnel(NSError(domain: "com.jihe.punchnet.tun", code: -1))) await self.onDecision(.failTunnel(NSError(domain: "com.jihe.punchnet.tun", code: -1)))
case .noIpAddress, .networkFault, .internalFault: case .noIpAddress, .networkFault, .internalFault:
await self.onDecision(.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage)) await self.onDecision(.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage))
} }
SDLLogger.log("[SDLContext] Get a SuperNak message exit") SDLLogger.log("[SDLContext] Get a SuperNak message exit", category: .super)
} }
private func handleEvent(_ event: SDLEvent) async { private func handleEvent(_ event: SDLEvent) async {
switch event.event { switch event.event {
case .natChanged(let natChangedEvent): case .natChanged(let natChangedEvent):
let dstMac = natChangedEvent.mac let dstMac = natChangedEvent.mac
SDLLogger.log("[SDLContext] natChangedEvent, dstMac: \(dstMac)") SDLLogger.log("[SDLContext] natChangedEvent, dstMac: \(dstMac)", category: .super)
await self.onDecision(.removeSession(dstMac: dstMac)) await self.onDecision(.removeSession(dstMac: dstMac))
case .sendRegister(let sendRegisterEvent): case .sendRegister(let sendRegisterEvent):
await self.handleSendRegisterEvent(sendRegisterEvent) await self.handleSendRegisterEvent(sendRegisterEvent)
case .exposedServiceChanged: case .exposedServiceChanged:
SDLLogger.log("[SDLContext] exposedServiceChanged event") SDLLogger.log("[SDLContext] exposedServiceChanged event", category: .super)
await self.onDecision(.requestExposedService) await self.onDecision(.requestExposedService)
case .shutdown(let shutdownEvent): case .shutdown(let shutdownEvent):
SDLLogger.fatal("[SDLSuperControlPlane] shutdown event received: \(shutdownEvent.message)") SDLLogger.fatal("[SDLSuperControlPlane] shutdown event received: \(shutdownEvent.message)", category: .super)
await self.onDecision(.shutdown(message: shutdownEvent.message)) await self.onDecision(.shutdown(message: shutdownEvent.message))
case .none: case .none:
() ()
@ -181,7 +181,7 @@ actor SDLSuperControlPlane {
return return
} }
SDLLogger.log("[SDLContext] sendRegisterEvent, ip: \(event)") SDLLogger.log("[SDLContext] sendRegisterEvent, ip: \(event)", category: .super)
if event.natIp > 0 && event.natPort > 0 { if event.natIp > 0 && event.natPort > 0 {
let address = SDLUtil.int32ToIp(event.natIp) let address = SDLUtil.int32ToIp(event.natIp)
@ -207,7 +207,7 @@ actor SDLSuperControlPlane {
registerSuper.accessToken = self.config.accessToken registerSuper.accessToken = self.config.accessToken
if let registerSuperData = try? registerSuper.serializedData() { if let registerSuperData = try? registerSuper.serializedData() {
SDLLogger.log("[SDLContext] will send register super") SDLLogger.log("[SDLContext] will send register super", category: .super)
await self.onDecision(.sendSuper(type: .registerSuper, data: registerSuperData)) await self.onDecision(.sendSuper(type: .registerSuper, data: registerSuperData))
} }
} }

View File

@ -106,7 +106,7 @@ actor DNSCloudClient {
await self.readySignal.fail(DNSCloudError.cancelled) await self.readySignal.fail(DNSCloudError.cancelled)
self.finishPacketContinuationIfNeed(throwing: nil) self.finishPacketContinuationIfNeed(throwing: nil)
SDLLogger.log("[SDLCloudClient] stopped") SDLLogger.log("[SDLCloudClient] stopped", category: .dns)
} }
private func handleConnectionStateUpdate(_ state: NWConnection.State) async { private func handleConnectionStateUpdate(_ state: NWConnection.State) async {
@ -116,7 +116,7 @@ actor DNSCloudClient {
return return
} }
SDLLogger.log("[DNSClient] Connection ready", for: .debug) SDLLogger.log("[DNSClient] Connection ready", category: .dns)
await self.readySignal.succeed(()) await self.readySignal.succeed(())
case .failed(let error): case .failed(let error):
await self.readySignal.fail(DNSCloudError.failed(error)) await self.readySignal.fail(DNSCloudError.failed(error))
@ -168,7 +168,7 @@ actor DNSCloudClient {
} }
deinit { deinit {
SDLLogger.log("[DNSCloudClient] deinit", for: .debug) SDLLogger.log("[DNSCloudClient] deinit", category: .dns)
} }
} }

View File

@ -44,7 +44,7 @@ actor DNSLocalClient {
self.packetContinuation = continuation self.packetContinuation = continuation
self.packetContinuation.onTermination = { termination in self.packetContinuation.onTermination = { termination in
SDLLogger.log("[DNSLocalClient] packetFlow terminated: \(termination)") SDLLogger.log("[DNSLocalClient] packetFlow terminated: \(termination)", category: .dns)
} }
let parameters = NWParameters.udp let parameters = NWParameters.udp
@ -110,7 +110,7 @@ actor DNSLocalClient {
} }
guard let allocatedTransactionID = self.allocateTransactionID() else { guard let allocatedTransactionID = self.allocateTransactionID() else {
SDLLogger.log("[DNSLocalClient] no available transaction id", for: .debug) SDLLogger.log("[DNSLocalClient] no available transaction id", category: .dns)
return return
} }
@ -140,7 +140,7 @@ actor DNSLocalClient {
self.finishPacketContinuationIfNeed(throwing: nil) self.finishPacketContinuationIfNeed(throwing: nil)
SDLLogger.log("[SDLLocalClient] stopped") SDLLogger.log("[SDLLocalClient] stopped", category: .dns)
} }
private func handleConnectionStateUpdate(_ state: NWConnection.State) async { private func handleConnectionStateUpdate(_ state: NWConnection.State) async {
@ -266,7 +266,7 @@ actor DNSLocalClient {
} }
deinit { deinit {
SDLLogger.log("[DNSLocalClient] deinit", for: .debug) SDLLogger.log("[DNSLocalClient] deinit", category: .dns)
} }
} }

View File

@ -19,7 +19,7 @@ actor DNSLocalService {
let client = DNSLocalClient(host: dnsServer) let client = DNSLocalClient(host: dnsServer)
self.currentClient = client self.currentClient = client
SDLLogger.log("[DNSLocalService] dnsLocalClient started") SDLLogger.log("[DNSLocalService] dnsLocalClient started", category: .dns)
do { do {
try await self.run(client: client) try await self.run(client: client)

View File

@ -7,62 +7,64 @@
import Foundation import Foundation
import os import os
public class SDLLogger: @unchecked Sendable { public final class SDLLogger: @unchecked Sendable {
public enum Subsystem: CaseIterable { public enum Category: String, CaseIterable {
case debug case app
case trace case context
case dns
case network
case packet
case policy
case session
case `super`
case udpHole
} }
private static let debugLoggingEnabled = ProcessInfo.processInfo.environment["SDL_DEBUG_LOG"] != "0" private static let subsystem = "com.jihe.punchnet.tun"
private static let traceLoggingEnabled = ProcessInfo.processInfo.environment["SDL_TRACE_LOG"] == "1" private static let loggers: [Category: SDLLogger] = {
private static let loggers: [Subsystem: SDLLogger] = { Dictionary(uniqueKeysWithValues: Category.allCases.map { ($0, SDLLogger(category: $0)) })
Dictionary(uniqueKeysWithValues: Subsystem.allCases.map { ($0, SDLLogger(subsystem: $0)) })
}() }()
private let log: Logger private let logger: Logger
private init(subsystem: Subsystem) { private init(category: Category) {
var label: String self.logger = Logger(subsystem: Self.subsystem, category: category.rawValue)
switch subsystem {
case .debug:
label = "com.jihe.punchnet.debug"
case .trace:
label = "com.jihe.punchnet.trace"
}
self.log = Logger(subsystem: label, category: "punchnet")
} }
public func _log(_ message: String) { private func log(_ message: String) {
self.log.info("\(message, privacy: .public)") self.logger.info("\(message, privacy: .public)")
} }
public func _fatal(_ message: String) { private func trace(_ message: String) {
self.log.fault("\(message, privacy: .public)") self.logger.debug("\(message, privacy: .public)")
}
private func fatal(_ message: String) {
self.logger.fault("\(message, privacy: .public)")
} }
public static func log(_ message: @autoclosure () -> String, for system: Subsystem = .debug) { public static func log(_ message: @autoclosure () -> String, category: Category = .context) {
guard self.isEnabled(system), let logger = loggers[system] else { guard let logger = loggers[category] else {
return return
} }
logger._log(message()) logger.log(message())
} }
public static func fatal(_ message: @autoclosure () -> String, for system: Subsystem = .debug) { public static func trace(_ message: @autoclosure () -> String, category: Category) {
guard let logger = loggers[system] else { guard let logger = loggers[category] else {
return return
} }
logger._fatal(message()) logger.trace(message())
} }
private static func isEnabled(_ system: Subsystem) -> Bool { public static func fatal(_ message: @autoclosure () -> String, category: Category = .context) {
switch system { guard let logger = loggers[category] else {
case .debug: return
return self.debugLoggingEnabled
case .trace:
return self.traceLoggingEnabled
} }
logger.fatal(message())
} }
} }

View File

@ -84,22 +84,22 @@ actor PacketInboundActor {
switch plan.action { switch plan.action {
case .sendARPReply(let dstMac, let responseData): case .sendARPReply(let dstMac, let responseData):
SDLLogger.log("[PacketInboundActor] get arp request packet") SDLLogger.log("[PacketInboundActor] get arp request packet", category: .packet)
await self.packetOutboundActor.routeLayerPacket(dstMac: dstMac, type: .arp, data: responseData) await self.packetOutboundActor.routeLayerPacket(dstMac: dstMac, type: .arp, data: responseData)
case .appendARP(let ip, let mac): case .appendARP(let ip, let mac):
SDLLogger.log("[PacketInboundActor] get arp response packet") SDLLogger.log("[PacketInboundActor] get arp response packet", category: .packet)
await self.arpResolver.append(ip: ip, mac: mac) await self.arpResolver.append(ip: ip, mac: mac)
case .writeToTun(let packetData, let identityID): case .writeToTun(let packetData, let identityID):
let packet = NEPacket(data: packetData, protocolFamily: 2) let packet = NEPacket(data: packetData, protocolFamily: 2)
self.provider.packetFlow.writePacketObjects([packet]) self.provider.packetFlow.writePacketObjects([packet])
SDLLogger.log("[PacketInboundActor] hole identity: \(identityID), allow, data count: \(packetData.count)", for: .trace) SDLLogger.trace("[PacketInboundActor] hole identity: \(identityID), allow, data count: \(packetData.count)", category: .packet)
case .requestPolicy(let context): case .requestPolicy(let context):
SDLLogger.log("[PacketInboundActor] policy miss, \(context.logDescription)", for: .debug) SDLLogger.log("[PacketInboundActor] policy miss, \(context.logDescription)", category: .packet)
if let queryData = await self.policyService.makePolicyRequest(srcIdentityID: context.srcIdentityID) { if let queryData = await self.policyService.makePolicyRequest(srcIdentityID: context.srcIdentityID) {
await self.superService.send(type: .policyRequest, data: queryData) await self.superService.send(type: .policyRequest, data: queryData)
} }
case .dropByPolicy(let context): case .dropByPolicy(let context):
SDLLogger.log("[PacketInboundActor] policy denied, \(context.logDescription)", for: .trace) SDLLogger.trace("[PacketInboundActor] policy denied, \(context.logDescription)", category: .packet)
case .none: case .none:
() ()
} }
@ -130,7 +130,7 @@ actor PacketInboundActor {
policyRuntime: policyRuntime policyRuntime: policyRuntime
) )
default: default:
SDLLogger.log("[SDLContext] get invalid packet", for: .debug) SDLLogger.log("[SDLContext] get invalid packet", category: .packet)
return .init(inboundBytes: inboundBytes, action: .none) return .init(inboundBytes: inboundBytes, action: .none)
} }
} }
@ -152,10 +152,10 @@ actor PacketInboundActor {
) )
} }
} else { } else {
SDLLogger.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(self.networkAddress.ip))") SDLLogger.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(self.networkAddress.ip))", category: .packet)
} }
} else { } else {
SDLLogger.log("[SDLContext] get invalid arp packet") SDLLogger.log("[SDLContext] get invalid arp packet", category: .packet)
} }
return .init(inboundBytes: inboundBytes, action: .none) return .init(inboundBytes: inboundBytes, action: .none)

View File

@ -172,9 +172,9 @@ actor SDLIPV6AssistClient {
switch state { switch state {
case .ready: case .ready:
SDLLogger.log("[SDLIPV6AssistClient] Connection ready", for: .debug) SDLLogger.log("[SDLIPV6AssistClient] Connection ready", category: .network)
case .failed(let error): case .failed(let error):
SDLLogger.log("[SDLIPV6AssistClient] Connection failed: \(error)", for: .debug) SDLLogger.log("[SDLIPV6AssistClient] Connection failed: \(error)", category: .network)
self.stop(pendingError: error) self.stop(pendingError: error)
case .cancelled: case .cancelled:
self.stop() self.stop()
@ -191,7 +191,7 @@ actor SDLIPV6AssistClient {
request.continuation.resume(returning: packet) request.continuation.resume(returning: packet)
} }
} catch { } catch {
SDLLogger.log("[SDLIPV6AssistClient] Receive error: \(error)", for: .debug) SDLLogger.log("[SDLIPV6AssistClient] Receive error: \(error)", category: .network)
} }
} }

View File

@ -94,7 +94,7 @@ actor PacketOutboundActor {
} }
} }
SDLLogger.log("[PacketOutboundActor] packet reader task finished") SDLLogger.log("[PacketOutboundActor] packet reader task finished", category: .packet)
} }
func handleTunPacket(_ packet: IPPacketView) async { func handleTunPacket(_ packet: IPPacketView) async {
@ -106,15 +106,15 @@ actor PacketOutboundActor {
let nePacket = NEPacket(data: ipPacketData, protocolFamily: 2) let nePacket = NEPacket(data: ipPacketData, protocolFamily: 2)
self.provider.packetFlow.writePacketObjects([nePacket]) self.provider.packetFlow.writePacketObjects([nePacket])
case .cloudDNS(let name, let ipPacketData): case .cloudDNS(let name, let ipPacketData):
SDLLogger.log("[PacketOutboundActor] get cloud dns request: \(name)") SDLLogger.log("[PacketOutboundActor] get cloud dns request: \(name)", category: .packet)
await self.dnsCloudService.forward(ipPacketData: ipPacketData) await self.dnsCloudService.forward(ipPacketData: ipPacketData)
case .localDNS(let name, let payload, let tracker): case .localDNS(let name, let payload, let tracker):
SDLLogger.log("[PacketOutboundActor] get local dns request: \(name)") SDLLogger.log("[PacketOutboundActor] get local dns request: \(name)", category: .packet)
await self.dnsLocalService.query(tracker: tracker, dnsPayload: payload) await self.dnsLocalService.query(tracker: tracker, dnsPayload: payload)
case .forwardToNextHop(let ip, let type, let data, let kind): case .forwardToNextHop(let ip, let type, let data, let kind):
await self.forwardPacketToNextHop(ip: ip, type: type, data: data, kind: kind, originalPacket: packet) await self.forwardPacketToNextHop(ip: ip, type: type, data: data, kind: kind, originalPacket: packet)
case .drop(let reason): case .drop(let reason):
SDLLogger.log("[PacketOutboundActor] drop tun packet, reason: \(reason.rawValue)", for: .trace) SDLLogger.trace("[PacketOutboundActor] drop tun packet, reason: \(reason.rawValue)", category: .packet)
} }
} }
@ -125,19 +125,19 @@ actor PacketOutboundActor {
originalPacket: IPPacketView) async { originalPacket: IPPacketView) async {
switch kind { switch kind {
case .sameNetwork: case .sameNetwork:
SDLLogger.log("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)) same network", for: .trace) SDLLogger.trace("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)) same network", category: .packet)
case .exitNode, .dnsExitNode: case .exitNode, .dnsExitNode:
SDLLogger.log("[PacketOutboundActor] use exit_node: \(SDLUtil.int32ToIp(ip))", for: .trace) SDLLogger.trace("[PacketOutboundActor] use exit_node: \(SDLUtil.int32ToIp(ip))", category: .packet)
} }
if let dstMac = self.arpResolver.snapshot().lookup(ip) { if let dstMac = self.arpResolver.snapshot().lookup(ip) {
SDLLogger.log("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)), dst_mac is: \(SDLUtil.formatMacAddress(mac: dstMac))", for: .trace) SDLLogger.trace("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)), dst_mac is: \(SDLUtil.formatMacAddress(mac: dstMac))", category: .packet)
let didSend = await self.routeLayerPacket(dstMac: dstMac, type: type, data: data) let didSend = await self.routeLayerPacket(dstMac: dstMac, type: type, data: data)
if didSend { if didSend {
self.policyService.recordOutboundFlow(ipPacket: originalPacket) self.policyService.recordOutboundFlow(ipPacket: originalPacket)
} }
} else { } else {
SDLLogger.log("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)) arp query not found, broadcast", for: .trace) SDLLogger.trace("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)) arp query not found, broadcast", category: .packet)
if let arpRequest = try? await self.arpResolver.makeArpRequest(targetIp: ip) { if let arpRequest = try? await self.arpResolver.makeArpRequest(targetIp: ip) {
await self.superService.send(type: .arpRequest, data: arpRequest) await self.superService.send(type: .arpRequest, data: arpRequest)
} }
@ -154,12 +154,12 @@ actor PacketOutboundActor {
case .superNode(let payload): case .superNode(let payload):
await self.sendSuperPacket(type: .data, data: payload) await self.sendSuperPacket(type: .data, data: payload)
case .peer(let payload, let session): case .peer(let payload, let session):
SDLLogger.log("[PacketOutboundActor] send packet by session: \(session)", for: .trace) SDLLogger.trace("[PacketOutboundActor] send packet by session: \(session)", category: .packet)
await self.sendPeerPacket(type: .data, data: payload, remoteAddress: session.natAddress) await self.sendPeerPacket(type: .data, data: payload, remoteAddress: session.natAddress)
self.flowTracer.inc(num: payload.count, type: .p2p) self.flowTracer.inc(num: payload.count, type: .p2p)
case .superNodeAndPunch(let payload, let request): case .superNodeAndPunch(let payload, let request):
await self.sendSuperPacket(type: .data, data: payload) await self.sendSuperPacket(type: .data, data: payload)
SDLLogger.log("[PacketOutboundActor] send packet by super: \(self.stunSocketAddress)", for: .trace) SDLLogger.trace("[PacketOutboundActor] send packet by super: \(self.stunSocketAddress)", category: .packet)
self.flowTracer.inc(num: payload.count, type: .forward) self.flowTracer.inc(num: payload.count, type: .forward)
if let queryData = await self.puncherActor.makeQueryInfoRequest(request: request) { if let queryData = await self.puncherActor.makeQueryInfoRequest(request: request) {
@ -243,7 +243,7 @@ actor PacketOutboundActor {
case .v6: case .v6:
await self.udpHoleV6Service.send(type: type, data: data, remoteAddress: remoteAddress) await self.udpHoleV6Service.send(type: type, data: data, remoteAddress: remoteAddress)
default: default:
SDLLogger.log("[PacketOutboundActor] unsupported socket family: \(remoteAddress)", for: .debug) SDLLogger.log("[PacketOutboundActor] unsupported socket family: \(remoteAddress)", category: .packet)
} }
} }
} }

View File

@ -30,7 +30,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
guard let options, let config = SDLConfiguration.parse(options: options) else { guard let options, let config = SDLConfiguration.parse(options: options) else {
SDLLogger.fatal("[PacketTunnelProvider] startTunnel failed: invalid configuration") SDLLogger.fatal("[PacketTunnelProvider] startTunnel failed: invalid configuration", category: .app)
completionHandler(TunnelError.invalidConfiguration) completionHandler(TunnelError.invalidConfiguration)
return return
} }
@ -40,7 +40,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
} }
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
SDLLogger.fatal("[PacketTunnelProvider] stopTunnel requested, reason: \(reason.rawValue)") SDLLogger.fatal("[PacketTunnelProvider] stopTunnel requested, reason: \(reason.rawValue)", category: .app)
self.stopContext(clearRuntimeConfiguration: true, completionHandler: completionHandler) self.stopContext(clearRuntimeConfiguration: true, completionHandler: completionHandler)
} }
@ -63,21 +63,21 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
} }
override func sleep(completionHandler: @escaping () -> Void) { override func sleep(completionHandler: @escaping () -> Void) {
SDLLogger.fatal("[PacketTunnelProvider] sleep requested, will stop current context") SDLLogger.fatal("[PacketTunnelProvider] sleep requested, will stop current context", category: .app)
self.stopContext(clearRuntimeConfiguration: false) { self.stopContext(clearRuntimeConfiguration: false) {
SDLLogger.log("[PacketTunnelProvider] sleep") SDLLogger.log("[PacketTunnelProvider] sleep", category: .app)
completionHandler() completionHandler()
} }
} }
override func wake() { override func wake() {
SDLLogger.log("[PacketTunnelProvider] wake up!!!!!!!") SDLLogger.log("[PacketTunnelProvider] wake up!!!!!!!", category: .app)
self.startCachedContext { err in self.startCachedContext { err in
if let err { if let err {
SDLLogger.fatal("[PacketTunnelProvider] wakeup start failed: \(err)") SDLLogger.fatal("[PacketTunnelProvider] wakeup start failed: \(err)", category: .app)
SDLLogger.log("[PacketTunnelProvider] wakeup start failed: \(err.localizedDescription)") SDLLogger.log("[PacketTunnelProvider] wakeup start failed: \(err.localizedDescription)", category: .app)
} else { } else {
SDLLogger.log("[PacketTunnelProvider] wakeup and try start") SDLLogger.log("[PacketTunnelProvider] wakeup and try start", category: .app)
} }
} }
} }
@ -123,7 +123,7 @@ private extension PacketTunnelProvider {
self.runtimeLock.unlock() self.runtimeLock.unlock()
guard let config, let rsaCipher else { guard let config, let rsaCipher else {
SDLLogger.fatal("[PacketTunnelProvider] startCachedContext failed: missing cached runtime configuration") SDLLogger.fatal("[PacketTunnelProvider] startCachedContext failed: missing cached runtime configuration", category: .app)
completionHandler(TunnelError.invalidConfiguration) completionHandler(TunnelError.invalidConfiguration)
return return
} }
@ -155,13 +155,13 @@ private extension PacketTunnelProvider {
try await contextActor.start() try await contextActor.start()
self.finishContextStart(contextActor, error: nil) self.finishContextStart(contextActor, error: nil)
} catch { } catch {
SDLLogger.fatal("[PacketTunnelProvider] context start failed: \(error)") SDLLogger.fatal("[PacketTunnelProvider] context start failed: \(error)", category: .app)
self.finishContextStart(contextActor, error: error) self.finishContextStart(contextActor, error: error)
} }
} }
case .starting, .running, .stopping: case .starting, .running, .stopping:
SDLLogger.fatal("[PacketTunnelProvider] startContext rejected: invalid runtime state \(self.runtimeState)") SDLLogger.fatal("[PacketTunnelProvider] startContext rejected: invalid runtime state \(self.runtimeState)", category: .app)
self.runtimeLock.unlock() self.runtimeLock.unlock()
completionHandler(TunnelError.invalidContext) completionHandler(TunnelError.invalidContext)
} }
@ -173,7 +173,7 @@ private extension PacketTunnelProvider {
let startCompletionHandler = self.startCompletionHandler let startCompletionHandler = self.startCompletionHandler
guard contextActor != nil else { guard contextActor != nil else {
SDLLogger.fatal("[PacketTunnelProvider] stopContext requested while context is nil, clearRuntimeConfiguration: \(clearRuntimeConfiguration)") SDLLogger.fatal("[PacketTunnelProvider] stopContext requested while context is nil, clearRuntimeConfiguration: \(clearRuntimeConfiguration)", category: .app)
self.runtimeState = .idle self.runtimeState = .idle
self.startCompletionHandler = nil self.startCompletionHandler = nil
if clearRuntimeConfiguration { if clearRuntimeConfiguration {
@ -195,7 +195,7 @@ private extension PacketTunnelProvider {
} }
self.runtimeLock.unlock() self.runtimeLock.unlock()
SDLLogger.fatal("[PacketTunnelProvider] stopContext will stop current context, clearRuntimeConfiguration: \(clearRuntimeConfiguration)") SDLLogger.fatal("[PacketTunnelProvider] stopContext will stop current context, clearRuntimeConfiguration: \(clearRuntimeConfiguration)", category: .app)
startCompletionHandler?(TunnelError.invalidContext) startCompletionHandler?(TunnelError.invalidContext)
Task { Task {

View File

@ -88,7 +88,7 @@ actor PolicyRuleStore {
ruleMap: PolicyRuleMap(version: version, ruleMap: ruleMap), ruleMap: PolicyRuleMap(version: version, ruleMap: ruleMap),
expiresAt: now + self.policyTTL expiresAt: now + self.policyTTL
) )
SDLLogger.log("[PolicyRuleStore] apply policy response, srcIdentityID: \(id), version: \(version), rulesCount: \(ruleMap.reduce(0) { $0 + $1.value.count })", for: .debug) SDLLogger.log("[PolicyRuleStore] apply policy response, srcIdentityID: \(id), version: \(version), rulesCount: \(ruleMap.reduce(0) { $0 + $1.value.count })", category: .policy)
// //
let snapshot = compileSnapshot() let snapshot = compileSnapshot()

View File

@ -26,17 +26,17 @@ struct PolicyRuntime: @unchecked Sendable {
func evaluateInbound(srcIdentityID: UInt32, ipPacket: IPPacketView) -> InboundDecision { func evaluateInbound(srcIdentityID: UInt32, ipPacket: IPPacketView) -> InboundDecision {
if self.isExposedService(ipPacket: ipPacket) { if self.isExposedService(ipPacket: ipPacket) {
SDLLogger.log("[PolicyRuntime] acl hit, src_identify_id: \(srcIdentityID), check rule: \(debugInfo(ipPacket: ipPacket))") SDLLogger.log("[PolicyRuntime] acl hit, src_identify_id: \(srcIdentityID), check rule: \(debugInfo(ipPacket: ipPacket))", category: .policy)
return self.evaluateByRule(srcIdentityID: srcIdentityID, ipPacket: ipPacket) return self.evaluateByRule(srcIdentityID: srcIdentityID, ipPacket: ipPacket)
} }
if self.isAllowedBySession(ipPacket: ipPacket) { if self.isAllowedBySession(ipPacket: ipPacket) {
SDLLogger.log("[PolicyRuntime] session hit, src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))") SDLLogger.log("[PolicyRuntime] session hit, src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))", category: .policy)
return .allow return .allow
} }
if case .icmp = ipPacket.transportPacket { if case .icmp = ipPacket.transportPacket {
SDLLogger.log("[PolicyRuntime] icmp hit, src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))") SDLLogger.log("[PolicyRuntime] icmp hit, src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))", category: .policy)
return .allow return .allow
} }
@ -49,7 +49,7 @@ struct PolicyRuntime: @unchecked Sendable {
} }
let isAllowed = self.isAllowedByRule(ruleMap: ruleMap, ipPacket: ipPacket) let isAllowed = self.isAllowedByRule(ruleMap: ruleMap, ipPacket: ipPacket)
SDLLogger.log("[PolicyRuntime] rule hit: \(isAllowed), src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))") SDLLogger.log("[PolicyRuntime] rule hit: \(isAllowed), src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))", category: .policy)
return isAllowed ? .allow : .deny return isAllowed ? .allow : .deny
} }

View File

@ -68,7 +68,7 @@ actor PolicyService {
func applyPolicyResponse(_ policyResponse: SDLPolicyResponse) async { func applyPolicyResponse(_ policyResponse: SDLPolicyResponse) async {
guard policyResponse.dstIdentityID == self.identityId else { guard policyResponse.dstIdentityID == self.identityId else {
SDLLogger.log("[PolicyService] ignore policy response, dstIdentityID mismatch: \(policyResponse.dstIdentityID), expected: \(self.identityId)", for: .debug) SDLLogger.log("[PolicyService] ignore policy response, dstIdentityID mismatch: \(policyResponse.dstIdentityID), expected: \(self.identityId)", category: .policy)
return return
} }
@ -79,19 +79,19 @@ actor PolicyService {
var request = SDLExposedServiceRequest() var request = SDLExposedServiceRequest()
self.latestExposedServiceRequestVersion = Self.nextVersion(after: self.latestExposedServiceRequestVersion) self.latestExposedServiceRequestVersion = Self.nextVersion(after: self.latestExposedServiceRequestVersion)
request.version = self.latestExposedServiceRequestVersion request.version = self.latestExposedServiceRequestVersion
SDLLogger.log("[PolicyService] make exposed service request, version: \(request.version)", for: .debug) SDLLogger.log("[PolicyService] make exposed service request, version: \(request.version)", category: .policy)
return try? request.serializedData() return try? request.serializedData()
} }
func applyExposedServiceResponse(_ response: SDLExposedServiceResponse) -> SDLConfiguration.ACL? { func applyExposedServiceResponse(_ response: SDLExposedServiceResponse) -> SDLConfiguration.ACL? {
guard response.version == self.latestExposedServiceRequestVersion else { guard response.version == self.latestExposedServiceRequestVersion else {
SDLLogger.log("[PolicyService] ignore exposed service response, version: \(response.version), latest request version: \(self.latestExposedServiceRequestVersion)", for: .debug) SDLLogger.log("[PolicyService] ignore exposed service response, version: \(response.version), latest request version: \(self.latestExposedServiceRequestVersion)", category: .policy)
return nil return nil
} }
let acl = SDLConfiguration.ACL(response: response) let acl = SDLConfiguration.ACL(response: response)
self.aclPublisher.publish(ExposedServiceSnapshot(acl: acl)) self.aclPublisher.publish(ExposedServiceSnapshot(acl: acl))
SDLLogger.log("[PolicyService] apply exposed service response, version: \(response.version), tcp: \(acl.tcpPorts.count), udp: \(acl.udpPorts.count)", for: .debug) SDLLogger.log("[PolicyService] apply exposed service response, version: \(response.version), tcp: \(acl.tcpPorts.count), udp: \(acl.udpPorts.count)", category: .policy)
return acl return acl
} }
@ -101,7 +101,7 @@ actor PolicyService {
} }
deinit { deinit {
SDLLogger.log("[PolicyService] deinit") SDLLogger.log("[PolicyService] deinit", category: .policy)
} }
private static func nextVersion(after version: UInt32) -> UInt32 { private static func nextVersion(after version: UInt32) -> UInt32 {

View File

@ -70,7 +70,7 @@ actor SDLPuncherActor {
queryInfo.dstMac = request.dstMac queryInfo.dstMac = request.dstMac
guard let queryData = try? queryInfo.serializedData() else { guard let queryData = try? queryInfo.serializedData() else {
SDLLogger.log("[SDLPuncherActor] failed to encode queryInfo", for: .debug) SDLLogger.log("[SDLPuncherActor] failed to encode queryInfo", category: .session)
return nil return nil
} }
@ -100,7 +100,7 @@ actor SDLPuncherActor {
register.dstMac = entry.request.dstMac register.dstMac = entry.request.dstMac
guard let registerData = try? register.serializedData() else { guard let registerData = try? register.serializedData() else {
SDLLogger.log("[SDLPuncherActor] failed to encode register", for: .debug) SDLLogger.log("[SDLPuncherActor] failed to encode register", category: .session)
return [] return []
} }

View File

@ -54,7 +54,7 @@ final class SDLSuperClient: @unchecked Sendable {
self.connection = NWConnection(host: Self.makeEndpointHost(address: serverEndpoint.ip), port: .init(rawValue: port)!, using: params) self.connection = NWConnection(host: Self.makeEndpointHost(address: serverEndpoint.ip), port: .init(rawValue: port)!, using: params)
SDLLogger.log("[SDLSuperClient] start with tls protocol", for: .debug) SDLLogger.log("[SDLSuperClient] start with tls protocol", category: .super)
} }
func run() async throws { func run() async throws {
@ -92,7 +92,7 @@ final class SDLSuperClient: @unchecked Sendable {
let connection = self.connection let connection = self.connection
return AsyncThrowingStream(bufferingPolicy: .bufferingNewest(16)) { continuation in return AsyncThrowingStream(bufferingPolicy: .bufferingNewest(16)) { continuation in
connection.stateUpdateHandler = { [weak self] state in connection.stateUpdateHandler = { [weak self] state in
SDLLogger.log("[SDLSuperClient] new state: \(state)", for: .debug) SDLLogger.log("[SDLSuperClient] new state: \(state)", category: .super)
switch state { switch state {
case .failed(let error): case .failed(let error):
let wrappedError = SDLSuperError.connectionFailed(error) let wrappedError = SDLSuperError.connectionFailed(error)
@ -149,7 +149,7 @@ final class SDLSuperClient: @unchecked Sendable {
connection.send(content: packet, completion: .contentProcessed { [weak self] error in connection.send(content: packet, completion: .contentProcessed { [weak self] error in
if let error { if let error {
SDLLogger.log("[SDLSuperClient] send data get error: \(error)", for: .debug) SDLLogger.log("[SDLSuperClient] send data get error: \(error)", category: .super)
self?.finishMessageStream(throwing: SDLSuperError.writeFailed(error)) self?.finishMessageStream(throwing: SDLSuperError.writeFailed(error))
} }
}) })
@ -193,7 +193,7 @@ final class SDLSuperClient: @unchecked Sendable {
connection.cancel() connection.cancel()
self.finishMessageStream() self.finishMessageStream()
SDLLogger.log("[SDLSuperClient] stopped") SDLLogger.log("[SDLSuperClient] stopped", category: .super)
} }
private func markStarted() -> Bool { private func markStarted() -> Bool {
@ -244,7 +244,7 @@ final class SDLSuperClient: @unchecked Sendable {
} }
deinit { deinit {
SDLLogger.log("[SDLSuperClient] deinit") SDLLogger.log("[SDLSuperClient] deinit", category: .super)
} }
} }

View File

@ -62,14 +62,14 @@ enum SDLSuperCodec {
case .event: case .event:
guard let bytes = buffer.readBytes(length: buffer.readableBytes), guard let bytes = buffer.readBytes(length: buffer.readableBytes),
let event = try? SDLEvent(serializedBytes: bytes) else { let event = try? SDLEvent(serializedBytes: bytes) else {
SDLLogger.log("SDLSuperClient decode Event Error", for: .debug) SDLLogger.log("SDLSuperClient decode Event Error", category: .super)
return nil return nil
} }
return .event(event) return .event(event)
case .pong: case .pong:
return .pong return .pong
default: default:
SDLLogger.log("SDLSuperClient decode miss type: \(type)", for: .debug) SDLLogger.log("SDLSuperClient decode miss type: \(type)", category: .super)
return nil return nil
} }

View File

@ -34,7 +34,7 @@ final class SDLSuperSession: @unchecked Sendable {
} }
private func runLoops() async throws { private func runLoops() async throws {
SDLLogger.log("[SDLSuperSession] start super client: \(self.serverEndpoint.ip)") SDLLogger.log("[SDLSuperSession] start super client: \(self.serverEndpoint.ip)", category: .super)
try await withThrowingTaskGroup(of: Void.self) { group in try await withThrowingTaskGroup(of: Void.self) { group in
defer { defer {

View File

@ -24,7 +24,7 @@ enum SDLSuperTLSVerifier {
// --- Step 1: --- // --- Step 1: ---
var error: CFError? var error: CFError?
guard SecTrustEvaluateWithError(secTrust, &error) else { guard SecTrustEvaluateWithError(secTrust, &error) else {
SDLLogger.log("❌ 系统证书验证失败: \(error?.localizedDescription ?? "未知错误")", for: .debug) SDLLogger.log("❌ 系统证书验证失败: \(error?.localizedDescription ?? "未知错误")", category: .super)
return false return false
} }
@ -33,21 +33,21 @@ enum SDLSuperTLSVerifier {
SecTrustSetPolicies(secTrust, policy) SecTrustSetPolicies(secTrust, policy)
guard SecTrustEvaluateWithError(secTrust, &error) else { guard SecTrustEvaluateWithError(secTrust, &error) else {
SDLLogger.log("❌ 主机名校验失败: \(error?.localizedDescription ?? "未知错误")", for: .debug) SDLLogger.log("❌ 主机名校验失败: \(error?.localizedDescription ?? "未知错误")", category: .super)
return false return false
} }
// --- Step 3: --- // --- Step 3: ---
guard let chain = SecTrustCopyCertificateChain(secTrust) as? [SecCertificate], guard let chain = SecTrustCopyCertificateChain(secTrust) as? [SecCertificate],
let leafCertificate = chain.first else { let leafCertificate = chain.first else {
SDLLogger.log("❌ 无法获取证书链或叶子证书", for: .debug) SDLLogger.log("❌ 无法获取证书链或叶子证书", category: .super)
return false return false
} }
// --- Step 4: --- // --- Step 4: ---
guard let publicKey = SecCertificateCopyKey(leafCertificate), guard let publicKey = SecCertificateCopyKey(leafCertificate),
let publicKeyData = SecKeyCopyExternalRepresentation(publicKey, nil) as Data? else { let publicKeyData = SecKeyCopyExternalRepresentation(publicKey, nil) as Data? else {
SDLLogger.log("❌ 无法提取公钥", for: .debug) SDLLogger.log("❌ 无法提取公钥", category: .super)
return false return false
} }
@ -56,10 +56,10 @@ enum SDLSuperTLSVerifier {
let hashBase64 = Data(hash).base64EncodedString().lowercased() let hashBase64 = Data(hash).base64EncodedString().lowercased()
if pinnedPublicKeyHashes.contains(hashBase64) { if pinnedPublicKeyHashes.contains(hashBase64) {
SDLLogger.log("✅ 公钥校验通过", for: .debug) SDLLogger.log("✅ 公钥校验通过", category: .super)
return true return true
} else { } else {
SDLLogger.log("⚠️ 公钥不匹配! 收到: \(hashBase64), config hashes: \(pinnedPublicKeyHashes)", for: .debug) SDLLogger.log("⚠️ 公钥不匹配! 收到: \(hashBase64), config hashes: \(pinnedPublicKeyHashes)", category: .super)
return false return false
} }
} }

View File

@ -74,10 +74,10 @@ final class SDLUDPHole: ChannelInboundHandler {
if let message = try SDLHoleMessage.decode(buffer: &buffer) { if let message = try SDLHoleMessage.decode(buffer: &buffer) {
self.messageContinuation.yield(SDLHoleDatagram(remoteAddress: remoteAddress, message: message)) self.messageContinuation.yield(SDLHoleDatagram(remoteAddress: remoteAddress, message: message))
} else { } else {
SDLLogger.log("[SDLUDPHole] decode message, get null", for: .debug) SDLLogger.log("[SDLUDPHole] decode message, get null", category: .udpHole)
} }
} catch let err { } catch let err {
SDLLogger.log("[SDLUDPHole] decode message, get error: \(err)", for: .debug) SDLLogger.log("[SDLUDPHole] decode message, get error: \(err)", category: .udpHole)
self.messageContinuation.finish(throwing: err) self.messageContinuation.finish(throwing: err)
} }
} }
@ -126,10 +126,10 @@ final class SDLUDPHole: ChannelInboundHandler {
try? channel?.close().wait() try? channel?.close().wait()
try? self.group.syncShutdownGracefully() try? self.group.syncShutdownGracefully()
SDLLogger.log("[SDLUDPHole] stopped", for: .debug) SDLLogger.log("[SDLUDPHole] stopped", category: .udpHole)
} }
deinit { deinit {
SDLLogger.log("[SDLUDPHole] deinit", for: .debug) SDLLogger.log("[SDLUDPHole] deinit", category: .udpHole)
} }
} }

View File

@ -31,7 +31,7 @@ actor SDLUDPHoleSession {
self.udpHole = udpHole self.udpHole = udpHole
self.localAddress = localAddress self.localAddress = localAddress
SDLLogger.log("[SDLUDPHoleSession] udpHole started, on address: \(localAddress)") SDLLogger.log("[SDLUDPHoleSession] udpHole started, on address: \(localAddress)", category: .udpHole)
await self.onEvent(.ready(localAddress)) await self.onEvent(.ready(localAddress))
try await withThrowingTaskGroup(of: Void.self) { group in try await withThrowingTaskGroup(of: Void.self) { group in
@ -62,12 +62,12 @@ actor SDLUDPHoleSession {
func send(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) async { func send(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) async {
guard case .v4 = remoteAddress else { guard case .v4 = remoteAddress else {
SDLLogger.log("[SDLUDPHoleSession] unsupported socket family: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLUDPHoleSession] unsupported socket family: \(remoteAddress)", category: .udpHole)
return return
} }
guard let udpHole else { guard let udpHole else {
SDLLogger.log("[SDLUDPHoleSession] udpHole is nil for remoteAddress: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLUDPHoleSession] udpHole is nil for remoteAddress: \(remoteAddress)", category: .udpHole)
return return
} }

View File

@ -63,7 +63,7 @@ extension SDLHoleMessage {
} }
return .control(.stunReply(stunReply)) return .control(.stunReply(stunReply))
default: default:
SDLLogger.log("[SDLUDPHole] decode miss type: \(type)", for: .debug) SDLLogger.log("[SDLUDPHole] decode miss type: \(type)", category: .udpHole)
return nil return nil
} }

View File

@ -67,27 +67,27 @@ final class SDLUDPHoleV6: ChannelInboundHandler {
let remoteAddress = envelope.remoteAddress let remoteAddress = envelope.remoteAddress
if let rawBytes = buffer.getBytes(at: buffer.readerIndex, length: buffer.readableBytes) { if let rawBytes = buffer.getBytes(at: buffer.readerIndex, length: buffer.readableBytes) {
SDLLogger.log("[SDLUDPHoleV6] get raw bytes: \(rawBytes.count), from: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLUDPHoleV6] get raw bytes: \(rawBytes.count), from: \(remoteAddress)", category: .udpHole)
} }
do { do {
if let message = try SDLHoleMessage.decode(buffer: &buffer) { if let message = try SDLHoleMessage.decode(buffer: &buffer) {
self.messageContinuation.yield((remoteAddress, message)) self.messageContinuation.yield((remoteAddress, message))
} else { } else {
SDLLogger.log("[SDLUDPHoleV6] decode message, get null", for: .debug) SDLLogger.log("[SDLUDPHoleV6] decode message, get null", category: .udpHole)
} }
} catch let err { } catch let err {
SDLLogger.log("[SDLUDPHoleV6] decode message, get error: \(err)", for: .debug) SDLLogger.log("[SDLUDPHoleV6] decode message, get error: \(err)", category: .udpHole)
} }
} }
func channelInactive(context: ChannelHandlerContext) { func channelInactive(context: ChannelHandlerContext) {
SDLLogger.log("[SDLUDPHoleV6] channelInactive", for: .debug) SDLLogger.log("[SDLUDPHoleV6] channelInactive", category: .udpHole)
self.eventContinuation.yield(.closed) self.eventContinuation.yield(.closed)
} }
func errorCaught(context: ChannelHandlerContext, error: any Error) { func errorCaught(context: ChannelHandlerContext, error: any Error) {
SDLLogger.log("[SDLUDPHoleV6] channel error: \(error)", for: .debug) SDLLogger.log("[SDLUDPHoleV6] channel error: \(error)", category: .udpHole)
context.close(promise: nil) context.close(promise: nil)
self.eventContinuation.yield(.errorCaught) self.eventContinuation.yield(.errorCaught)
} }
@ -114,7 +114,7 @@ final class SDLUDPHoleV6: ChannelInboundHandler {
} }
self.isStopped = true self.isStopped = true
SDLLogger.log("[SDLUDPHoleV6] stop", for: .debug) SDLLogger.log("[SDLUDPHoleV6] stop", category: .udpHole)
self.messageContinuation.finish() self.messageContinuation.finish()
self.eventContinuation.finish() self.eventContinuation.finish()
@ -127,7 +127,7 @@ final class SDLUDPHoleV6: ChannelInboundHandler {
} }
deinit { deinit {
SDLLogger.log("[SDLUDPHoleV6] deinit", for: .debug) SDLLogger.log("[SDLUDPHoleV6] deinit", category: .udpHole)
} }
} }

View File

@ -21,9 +21,9 @@ actor SDLUDPHoleV6Session {
self.udpHoleV6 = udpHoleV6 self.udpHoleV6 = udpHoleV6
if let localAddress { if let localAddress {
SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 started, on address: \(localAddress)") SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 started, on address: \(localAddress)", category: .udpHole)
} else { } else {
SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 started, no local address") SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 started, no local address", category: .udpHole)
} }
try await withThrowingTaskGroup(of: Void.self) { group in try await withThrowingTaskGroup(of: Void.self) { group in
@ -51,7 +51,7 @@ actor SDLUDPHoleV6Session {
try Task.checkCancellation() try Task.checkCancellation()
switch event { switch event {
case .ready: case .ready:
SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 ready") SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 ready", category: .udpHole)
case .closed, .errorCaught: case .closed, .errorCaught:
throw SDLContextError.udpHoleClosed throw SDLContextError.udpHoleClosed
} }
@ -70,12 +70,12 @@ actor SDLUDPHoleV6Session {
func send(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) { func send(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) {
guard case .v6 = remoteAddress else { guard case .v6 = remoteAddress else {
SDLLogger.log("[SDLUDPHoleV6Session] unsupported socket family: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLUDPHoleV6Session] unsupported socket family: \(remoteAddress)", category: .udpHole)
return return
} }
guard let udpHoleV6 else { guard let udpHoleV6 else {
SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 is nil for remoteAddress: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 is nil for remoteAddress: \(remoteAddress)", category: .udpHole)
return return
} }