fix forwarder

This commit is contained in:
anlicheng 2026-04-14 20:56:27 +08:00
parent dcddadb985
commit bc87d23ec2
2 changed files with 93 additions and 33 deletions

View File

@ -991,47 +991,42 @@ extension SDLContextActor {
}
}
private func makeLayerPacketForwarder() -> SDLLayerPacketForwarder {
return .init(
networkAddress: self.config.networkAddress,
identityID: self.config.identityId,
dataCipher: self.dataCipher,
sessionManager: self.sessionManager
)
}
private func routeLayerPacket(dstMac: Data, type: LayerPacket.PacketType, data: Data) async {
let networkAddr = self.config.networkAddress
// 2
let layerPacket = LayerPacket(dstMac: dstMac, srcMac: networkAddr.mac, type: type, data: data)
guard let dataCipher = self.dataCipher,
let encodedPacket = try? dataCipher.encrypt(plainText: layerPacket.marshal()) else {
//
let forwarder = self.makeLayerPacketForwarder()
guard let plan = try? forwarder.makeDeliveryPlan(dstMac: dstMac, type: type, data: data) else {
return
}
//
var dataPacket = SDLData()
dataPacket.networkID = networkAddr.networkId
dataPacket.srcMac = networkAddr.mac
dataPacket.dstMac = dstMac
dataPacket.ttl = 255
dataPacket.identityID = self.config.identityId
dataPacket.data = encodedPacket
let data = try! dataPacket.serializedData()
// 广
if ARPPacket.isBroadcastMac(dstMac) {
switch plan {
case .superNode(let payload):
// super_node
self.sendSuperPacket(type: .data, data: data)
}
else {
self.sendSuperPacket(type: .data, data: payload)
case .peer(let payload, let session):
// session
if let session = self.sessionManager.getSession(toAddress: dstMac) {
SDLLogger.log("[SDLContext] step 5 send packet by session: \(session)", for: .trace)
self.sendPeerPacket(type: .data, data: data, remoteAddress: session.natAddress)
self.flowTracer.inc(num: data.count, type: .p2p)
}
else {
// super_node
self.sendSuperPacket(type: .data, data: data)
SDLLogger.log("[SDLContext] step 5 send packet by super: \(self.config.stunSocketAddress)", for: .trace)
//
self.flowTracer.inc(num: data.count, type: .forward)
//
await self.puncherActor.submitRegisterRequest(quicClient: self.quicClient, request: .init(srcMac: networkAddr.mac, dstMac: dstMac, networkId: networkAddr.networkId))
}
SDLLogger.log("[SDLContext] step 5 send packet by session: \(session)", for: .trace)
self.sendPeerPacket(type: .data, data: payload, remoteAddress: session.natAddress)
self.flowTracer.inc(num: payload.count, type: .p2p)
case .superNodeAndPunch(let payload, let request):
// super_node
self.sendSuperPacket(type: .data, data: payload)
SDLLogger.log("[SDLContext] step 5 send packet by super: \(self.config.stunSocketAddress)", for: .trace)
//
self.flowTracer.inc(num: payload.count, type: .forward)
//
await self.puncherActor.submitRegisterRequest(quicClient: self.quicClient, request: request)
}
}

View File

@ -0,0 +1,65 @@
//
// SDLLayerPacketForwarder.swift
// Tun
//
// Created by on 2026/4/14.
//
import Foundation
struct SDLLayerPacketForwarder {
enum DeliveryPlan {
case superNode(payload: Data)
case peer(payload: Data, session: Session)
case superNodeAndPunch(payload: Data, request: SDLPuncherActor.RegisterRequest)
}
let networkAddress: SDLConfiguration.NetworkAddress
let identityID: UInt32
let dataCipher: CCDataCipher?
let sessionManager: SessionManager
func makeDeliveryPlan(dstMac: Data, type: LayerPacket.PacketType, data: Data) throws -> DeliveryPlan? {
guard let payload = try self.makePayload(dstMac: dstMac, type: type, data: data) else {
return nil
}
if ARPPacket.isBroadcastMac(dstMac) {
return .superNode(payload: payload)
}
if let session = self.sessionManager.getSession(toAddress: dstMac) {
return .peer(payload: payload, session: session)
}
return .superNodeAndPunch(
payload: payload,
request: .init(
srcMac: self.networkAddress.mac,
dstMac: dstMac,
networkId: self.networkAddress.networkId
)
)
}
private func makePayload(dstMac: Data, type: LayerPacket.PacketType, data: Data) throws -> Data? {
// 2
let layerPacket = LayerPacket(dstMac: dstMac, srcMac: self.networkAddress.mac, type: type, data: data)
guard let dataCipher = self.dataCipher else {
return nil
}
let encodedPacket = try dataCipher.encrypt(plainText: layerPacket.marshal())
//
var dataPacket = SDLData()
dataPacket.networkID = self.networkAddress.networkId
dataPacket.srcMac = self.networkAddress.mac
dataPacket.dstMac = dstMac
dataPacket.ttl = 255
dataPacket.identityID = self.identityID
dataPacket.data = encodedPacket
return try dataPacket.serializedData()
}
}