This commit is contained in:
anlicheng 2026-04-16 11:11:48 +08:00
parent 1e263e275e
commit bfd635c307
3 changed files with 22 additions and 45 deletions

View File

@ -25,6 +25,15 @@ actor SDLContextActor {
private enum UDPHoleKind: Equatable { private enum UDPHoleKind: Equatable {
case v4 case v4
case v6 case v6
func convertAddressType() -> Session.AddressType {
switch self {
case .v4:
return .v4
case .v6:
return .v6
}
}
} }
private var readyState: ReadyState = .idle private var readyState: ReadyState = .idle
@ -845,13 +854,13 @@ extension SDLContextActor {
} }
await self.proberActor.handleProbeReply(localAddress: localAddress, reply: probeReply) await self.proberActor.handleProbeReply(localAddress: localAddress, reply: probeReply)
case .register(let register): case .register(let register):
try? await self.handleRegister(remoteAddress: remoteAddress, register: register) try? await self.handleRegister(remoteAddress: remoteAddress, register: register, source: source)
case .registerAck(let registerAck): case .registerAck(let registerAck):
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck) await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck, source: source)
} }
} }
private func handleRegister(remoteAddress: SocketAddress, register: SDLRegister) async throws { private func handleRegister(remoteAddress: SocketAddress, register: SDLRegister, source: UDPHoleKind) async throws {
let networkAddr = config.networkAddress let networkAddr = config.networkAddress
SDLLogger.log("[SDLContext] register packet: \(register), network_address: \(networkAddr)") SDLLogger.log("[SDLContext] register packet: \(register), network_address: \(networkAddr)")
@ -865,7 +874,7 @@ extension SDLContextActor {
self.sendPeerPacket(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress) self.sendPeerPacket(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress)
// , super-nodenatudpnat // , super-nodenatudpnat
if let session = Session(dstMac: register.srcMac, natAddress: remoteAddress) { if let session = Session(dstMac: register.srcMac, natAddress: remoteAddress, addressType: source.convertAddressType()) {
await self.sessionManager.addSession(session: session) await self.sessionManager.addSession(session: session)
} else { } else {
SDLLogger.log("[SDLContext] didReadRegister get unsupported remoteAddress: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLContext] didReadRegister get unsupported remoteAddress: \(remoteAddress)", for: .debug)
@ -875,11 +884,11 @@ extension SDLContextActor {
} }
} }
private func handleRegisterAck(remoteAddress: SocketAddress, registerAck: SDLRegisterAck) async { private func handleRegisterAck(remoteAddress: SocketAddress, registerAck: SDLRegisterAck, source: UDPHoleKind) async {
// tun, // tun,
let networkAddr = config.networkAddress let networkAddr = config.networkAddress
if registerAck.dstMac == networkAddr.mac && registerAck.networkID == networkAddr.networkId { if registerAck.dstMac == networkAddr.mac && registerAck.networkID == networkAddr.networkId {
if let session = Session(dstMac: registerAck.srcMac, natAddress: remoteAddress) { if let session = Session(dstMac: registerAck.srcMac, natAddress: remoteAddress, addressType: source.convertAddressType()) {
await self.sessionManager.addSession(session: session) await self.sessionManager.addSession(session: session)
} else { } else {
SDLLogger.log("[SDLContext] didReadRegisterAck get unsupported remoteAddress: \(remoteAddress)", for: .debug) SDLLogger.log("[SDLContext] didReadRegisterAck get unsupported remoteAddress: \(remoteAddress)", for: .debug)

View File

@ -8,6 +8,7 @@
import Foundation import Foundation
struct SDLLayerPacketForwarder { struct SDLLayerPacketForwarder {
enum DeliveryPlan { enum DeliveryPlan {
case superNode(payload: Data) case superNode(payload: Data)
case peer(payload: Data, session: Session) case peer(payload: Data, session: Session)
@ -28,8 +29,7 @@ struct SDLLayerPacketForwarder {
return .superNode(payload: payload) return .superNode(payload: payload)
} }
let preferredSessionType = Session.AddressType(packetType: type) if let session = await self.sessionManager.getSession(toAddress: dstMac) {
if let session = await self.sessionManager.getSession(toAddress: dstMac, preferredType: preferredSessionType) {
return .peer(payload: payload, session: session) return .peer(payload: payload, session: session)
} }

View File

@ -8,32 +8,10 @@ import Foundation
import NIOCore import NIOCore
import Darwin import Darwin
struct Session: @unchecked Sendable { struct Session {
enum AddressType: String, Hashable { enum AddressType: String, Hashable {
case v4 case v4
case v6 case v6
init?(socketAddress: SocketAddress) {
switch socketAddress {
case .v4:
self = .v4
case .v6:
self = .v6
default:
return nil
}
}
init?(packetType: LayerPacket.PacketType) {
switch packetType {
case .arp, .ipv4:
self = .v4
case .ipv6:
self = .v6
default:
return nil
}
}
} }
// ip, // ip,
@ -46,11 +24,7 @@ struct Session: @unchecked Sendable {
// 使 // 使
var lastTimestamp: Int32 var lastTimestamp: Int32
init?(dstMac: Data, natAddress: SocketAddress) { init?(dstMac: Data, natAddress: SocketAddress, addressType: AddressType) {
guard let addressType = AddressType(socketAddress: natAddress) else {
return nil
}
self.dstMac = dstMac self.dstMac = dstMac
self.natAddress = natAddress self.natAddress = natAddress
self.addressType = addressType self.addressType = addressType
@ -68,7 +42,7 @@ actor SessionManager {
// session // session
private let ttl: Int32 = 10 private let ttl: Int32 = 10
func getSession(toAddress: Data, preferredType: Session.AddressType? = nil) -> Session? { func getSession(toAddress: Data) -> Session? {
let timestamp = Int32(Date().timeIntervalSince1970) let timestamp = Int32(Date().timeIntervalSince1970)
guard var sessions = self.sessions[toAddress] else { guard var sessions = self.sessions[toAddress] else {
@ -81,7 +55,7 @@ actor SessionManager {
return nil return nil
} }
guard var session = self.selectSession(in: sessions, preferredType: preferredType) else { guard var session = self.selectSession(in: sessions) else {
self.sessions[toAddress] = sessions self.sessions[toAddress] = sessions
return nil return nil
} }
@ -109,13 +83,7 @@ actor SessionManager {
self.sessions.removeValue(forKey: dstMac) self.sessions.removeValue(forKey: dstMac)
} }
private func selectSession(in sessions: [Session.AddressType: Session], preferredType: Session.AddressType?) -> Session? { private func selectSession(in sessions: [Session.AddressType: Session]) -> Session? {
if let preferredType {
if let preferred = sessions[preferredType] {
return preferred
}
}
return sessions.values.max(by: { $0.lastTimestamp < $1.lastTimestamp }) return sessions.values.max(by: { $0.lastTimestamp < $1.lastTimestamp })
} }