fix outbound路径
This commit is contained in:
parent
76b5d3212f
commit
ced138c3a5
@ -12,6 +12,12 @@ import NIOCore
|
|||||||
actor PacketOutboundActor {
|
actor PacketOutboundActor {
|
||||||
private typealias PacketReadResult = (packets: [Data], protocols: [NSNumber])?
|
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 provider: NEPacketTunnelProvider
|
||||||
private let sessionManager: SessionManager
|
private let sessionManager: SessionManager
|
||||||
private let arpResolver: ArpResolver
|
private let arpResolver: ArpResolver
|
||||||
@ -112,7 +118,7 @@ actor PacketOutboundActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleTunPacket(_ packet: IPPacket) async {
|
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)
|
let decision = router.route(packet: packet)
|
||||||
|
|
||||||
if decision.shouldTrackFlow, let flowSession = packet.flowSession() {
|
if decision.shouldTrackFlow, let flowSession = packet.flowSession() {
|
||||||
@ -146,8 +152,7 @@ actor PacketOutboundActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func routeLayerPacket(dstMac: Data, type: LayerPacket.PacketType, data: Data) async {
|
func routeLayerPacket(dstMac: Data, type: LayerPacket.PacketType, data: Data) async {
|
||||||
let forwarder = self.makeLayerPacketForwarder()
|
guard let plan = try? self.makeDeliveryPlan(dstMac: dstMac, type: type, data: data) else {
|
||||||
guard let plan = try? forwarder.makeDeliveryPlan(dstMac: dstMac, type: type, data: data) else {
|
|
||||||
return
|
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 {
|
switch decision {
|
||||||
case .loopback(let ipPacketData):
|
case .loopback(let ipPacketData):
|
||||||
let nePacket = NEPacket(data: ipPacketData, protocolFamily: 2)
|
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 {
|
switch kind {
|
||||||
case .sameNetwork:
|
case .sameNetwork:
|
||||||
SDLLogger.log("[PacketOutboundActor] dstIp: \(SDLUtil.int32ToIp(ip)) same network", for: .trace)
|
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 {
|
private func sendSuperPacket(type: SDLPacketType, data: Data) async {
|
||||||
await self.sendPacket(type: type, data: data, remoteAddress: self.stunSocketAddress)
|
await self.sendPacket(type: type, data: data, remoteAddress: self.stunSocketAddress)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// SDLTunPacketRouter.swift
|
// PacketOutboundRouter.swift
|
||||||
// Tun
|
// Tun
|
||||||
//
|
//
|
||||||
// Created by 安礼成 on 2026/4/14.
|
// Created by 安礼成 on 2026/4/14.
|
||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct SDLTunPacketRouter {
|
struct PacketOutboundRouter {
|
||||||
enum DropReason: String {
|
enum DropReason: String {
|
||||||
case invalidDNSRequest
|
case invalidDNSRequest
|
||||||
case noRoute
|
case noRoute
|
||||||
@ -95,7 +95,7 @@ struct SDLTunPacketRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SDLTunPacketRouter.RouteDecision {
|
extension PacketOutboundRouter.RouteDecision {
|
||||||
|
|
||||||
var shouldTrackFlow: Bool {
|
var shouldTrackFlow: Bool {
|
||||||
switch self {
|
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