fix outbound路径
This commit is contained in:
parent
76b5d3212f
commit
ced138c3a5
@ -12,6 +12,12 @@ import NIOCore
|
||||
actor PacketOutboundActor {
|
||||
private typealias PacketReadResult = (packets: [Data], protocols: [NSNumber])?
|
||||
|
||||
private enum DeliveryPlan {
|
||||
case superNode(payload: Data)
|
||||
case peer(payload: Data, session: Session)
|
||||
case superNodeAndPunch(payload: Data, request: SDLPuncherActor.RegisterRequest)
|
||||
}
|
||||
|
||||
private let provider: NEPacketTunnelProvider
|
||||
private let sessionManager: SessionManager
|
||||
private let arpResolver: ArpResolver
|
||||
@ -112,7 +118,7 @@ actor PacketOutboundActor {
|
||||
}
|
||||
|
||||
func handleTunPacket(_ packet: IPPacket) async {
|
||||
let router = SDLTunPacketRouter(networkAddress: self.networkAddress, exitNode: self.exitNode)
|
||||
let router = PacketOutboundRouter(networkAddress: self.networkAddress, exitNode: self.exitNode)
|
||||
let decision = router.route(packet: packet)
|
||||
|
||||
if decision.shouldTrackFlow, let flowSession = packet.flowSession() {
|
||||
@ -146,8 +152,7 @@ actor PacketOutboundActor {
|
||||
}
|
||||
|
||||
func routeLayerPacket(dstMac: Data, type: LayerPacket.PacketType, data: Data) async {
|
||||
let forwarder = self.makeLayerPacketForwarder()
|
||||
guard let plan = try? forwarder.makeDeliveryPlan(dstMac: dstMac, type: type, data: data) else {
|
||||
guard let plan = try? self.makeDeliveryPlan(dstMac: dstMac, type: type, data: data) else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -169,7 +174,50 @@ actor PacketOutboundActor {
|
||||
}
|
||||
}
|
||||
|
||||
private func handleTunRouteDecision(_ decision: SDLTunPacketRouter.RouteDecision) async {
|
||||
private func makeDeliveryPlan(dstMac: Data, type: LayerPacket.PacketType, data: Data) throws -> DeliveryPlan? {
|
||||
guard let payload = try self.makeDataPayload(dstMac: dstMac, type: type, data: data) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ARPPacket.isBroadcastMac(dstMac) {
|
||||
return .superNode(payload: payload)
|
||||
}
|
||||
|
||||
if let session = self.sessionManager.snapshot().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 makeDataPayload(dstMac: Data, type: LayerPacket.PacketType, data: Data) throws -> Data? {
|
||||
guard let dataCipher = self.dataCipher else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let layerPacket = LayerPacket(dstMac: dstMac, srcMac: self.networkAddress.mac, type: type, data: data)
|
||||
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.isP2P = true
|
||||
dataPacket.data = encodedPacket
|
||||
|
||||
return try dataPacket.serializedData()
|
||||
}
|
||||
|
||||
private func handleTunRouteDecision(_ decision: PacketOutboundRouter.RouteDecision) async {
|
||||
switch decision {
|
||||
case .loopback(let ipPacketData):
|
||||
let nePacket = NEPacket(data: ipPacketData, protocolFamily: 2)
|
||||
@ -187,7 +235,7 @@ actor PacketOutboundActor {
|
||||
}
|
||||
}
|
||||
|
||||
private func forwardPacketToNextHop(ip: UInt32, type: LayerPacket.PacketType, data: Data, kind: SDLTunPacketRouter.ForwardKind) async {
|
||||
private func forwardPacketToNextHop(ip: UInt32, type: LayerPacket.PacketType, data: Data, kind: PacketOutboundRouter.ForwardKind) async {
|
||||
switch kind {
|
||||
case .sameNetwork:
|
||||
SDLLogger.log("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)) same network", for: .trace)
|
||||
@ -206,15 +254,6 @@ actor PacketOutboundActor {
|
||||
}
|
||||
}
|
||||
|
||||
private func makeLayerPacketForwarder() -> SDLLayerPacketForwarder {
|
||||
return .init(
|
||||
networkAddress: self.networkAddress,
|
||||
identityID: self.identityId,
|
||||
dataCipher: self.dataCipher,
|
||||
sessionSnapshot: self.sessionManager.snapshot()
|
||||
)
|
||||
}
|
||||
|
||||
private func sendSuperPacket(type: SDLPacketType, data: Data) async {
|
||||
await self.sendPacket(type: type, data: data, remoteAddress: self.stunSocketAddress)
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SDLTunPacketRouter.swift
|
||||
// PacketOutboundRouter.swift
|
||||
// Tun
|
||||
//
|
||||
// Created by 安礼成 on 2026/4/14.
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SDLTunPacketRouter {
|
||||
struct PacketOutboundRouter {
|
||||
enum DropReason: String {
|
||||
case invalidDNSRequest
|
||||
case noRoute
|
||||
@ -95,7 +95,7 @@ struct SDLTunPacketRouter {
|
||||
}
|
||||
}
|
||||
|
||||
extension SDLTunPacketRouter.RouteDecision {
|
||||
extension PacketOutboundRouter.RouteDecision {
|
||||
|
||||
var shouldTrackFlow: Bool {
|
||||
switch self {
|
||||
@ -1,67 +0,0 @@
|
||||
//
|
||||
// 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 sessionSnapshot: SessionSnapshot
|
||||
|
||||
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.sessionSnapshot.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.isP2P = true
|
||||
dataPacket.data = encodedPacket
|
||||
|
||||
return try dataPacket.serializedData()
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user