fix
This commit is contained in:
parent
bc87d23ec2
commit
75d7761896
@ -832,94 +832,41 @@ extension SDLContextActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func makeHoleDataProcessor() -> SDLHoleDataProcessor {
|
||||||
|
return .init(
|
||||||
|
networkAddress: self.config.networkAddress,
|
||||||
|
dataCipher: self.dataCipher,
|
||||||
|
snapshotPublisher: self.snapshotPublisher,
|
||||||
|
flowSessionManager: self.flowSessionManager
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private func handleHoleData(data: SDLData) async throws {
|
private func handleHoleData(data: SDLData) async throws {
|
||||||
guard let dataCipher = self.dataCipher else {
|
let processor = self.makeHoleDataProcessor()
|
||||||
|
guard let plan = try processor.makeProcessingPlan(data: data) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let mac = LayerPacket.MacAddress(data: data.dstMac)
|
self.flowTracer.inc(num: plan.inboundBytes, type: .inbound)
|
||||||
let networkAddr = config.networkAddress
|
|
||||||
guard (data.dstMac == networkAddr.mac || mac.isBroadcast() || mac.isMulticast()) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let decyptedData = try dataCipher.decrypt(cipherText: Data(data.data))
|
switch plan.action {
|
||||||
let layerPacket = try LayerPacket(layerData: decyptedData)
|
case .sendARPReply(let dstMac, let responseData):
|
||||||
|
|
||||||
self.flowTracer.inc(num: decyptedData.count, type: .inbound)
|
|
||||||
// 处理arp请求
|
|
||||||
switch layerPacket.type {
|
|
||||||
case .arp:
|
|
||||||
// 判断如果收到的是arp请求
|
|
||||||
if let arpPacket = ARPPacket(data: layerPacket.data) {
|
|
||||||
if arpPacket.targetIP == networkAddr.ip {
|
|
||||||
switch arpPacket.opcode {
|
|
||||||
case .request:
|
|
||||||
SDLLogger.log("[SDLContext] get arp request packet")
|
SDLLogger.log("[SDLContext] get arp request packet")
|
||||||
let response = ARPPacket.arpResponse(for: arpPacket, mac: networkAddr.mac, ip: networkAddr.ip)
|
await self.routeLayerPacket(dstMac: dstMac, type: .arp, data: responseData)
|
||||||
await self.routeLayerPacket(dstMac: arpPacket.senderMAC, type: .arp, data: response.marshal())
|
case .appendARP(let ip, let mac):
|
||||||
case .response:
|
|
||||||
SDLLogger.log("[SDLContext] get arp response packet")
|
SDLLogger.log("[SDLContext] get arp response packet")
|
||||||
await self.arpServer.append(ip: arpPacket.senderIP, mac: arpPacket.senderMAC)
|
await self.arpServer.append(ip: ip, mac: mac)
|
||||||
}
|
case .writeToTun(let packetData, let identityID):
|
||||||
} else {
|
let packet = NEPacket(data: packetData, protocolFamily: 2)
|
||||||
SDLLogger.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(networkAddr.ip))")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SDLLogger.log("[SDLContext] get invalid arp packet")
|
|
||||||
}
|
|
||||||
case .ipv4:
|
|
||||||
// 有数据是通过出口网关转发的,所有只判断是合法的ip包
|
|
||||||
guard let ipPacket = IPPacket(layerPacket.data) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查权限逻辑
|
|
||||||
let identitySnapshot = self.snapshotPublisher.current()
|
|
||||||
let ruleMap = identitySnapshot.lookup(data.identityID)
|
|
||||||
|
|
||||||
if true || self.checkPolicy(ipPacket: ipPacket, ruleMap: ruleMap) {
|
|
||||||
let packet = NEPacket(data: ipPacket.data, protocolFamily: 2)
|
|
||||||
self.provider.packetFlow.writePacketObjects([packet])
|
self.provider.packetFlow.writePacketObjects([packet])
|
||||||
SDLLogger.log("[SDLContext] hole identity: \(data.identityID), allow, data count: \(ipPacket.data.count)", for: .trace)
|
SDLLogger.log("[SDLContext] hole identity: \(identityID), allow, data count: \(packetData.count)", for: .trace)
|
||||||
}
|
case .requestPolicy(let srcIdentityID):
|
||||||
else {
|
SDLLogger.log("[SDLContext] not found identity: \(srcIdentityID) ruleMap", for: .debug)
|
||||||
SDLLogger.log("[SDLContext] not found identity: \(data.identityID) ruleMap", for: .debug)
|
|
||||||
// 向服务器请求权限逻辑
|
// 向服务器请求权限逻辑
|
||||||
await self.identifyStore.policyRequest(srcIdentityId: data.identityID, dstIdentityId: self.config.identityId, using: self.quicClient)
|
await self.identifyStore.policyRequest(srcIdentityId: srcIdentityID, dstIdentityId: self.config.identityId, using: self.quicClient)
|
||||||
|
case .none:
|
||||||
|
()
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
SDLLogger.log("[SDLContext] get invalid packet", for: .debug)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func checkPolicy(ipPacket: IPPacket, ruleMap: IdentityRuleMap?) -> Bool {
|
|
||||||
// 进来的数据反转一下,然后再处理
|
|
||||||
if let reverseFlowSession = ipPacket.flowSession()?.reverse(),
|
|
||||||
self.flowSessionManager.hasSession(reverseFlowSession) {
|
|
||||||
self.flowSessionManager.updateSession(reverseFlowSession)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查权限逻辑
|
|
||||||
let proto = ipPacket.header.proto
|
|
||||||
// 优先判断访问规则
|
|
||||||
switch ipPacket.transportPacket {
|
|
||||||
case .tcp(let tcpPacket):
|
|
||||||
if let ruleMap, ruleMap.isAllow(proto: proto, port: tcpPacket.header.dstPort) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case .udp(let udpPacket):
|
|
||||||
if let ruleMap, ruleMap.isAllow(proto: proto, port: udpPacket.dstPort) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case .icmp(_):
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
143
Tun/Punchnet/Actors/SDLHoleDataProcessor.swift
Normal file
143
Tun/Punchnet/Actors/SDLHoleDataProcessor.swift
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
//
|
||||||
|
// SDLHoleDataProcessor.swift
|
||||||
|
// Tun
|
||||||
|
//
|
||||||
|
// Created by 安礼成 on 2026/4/14.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
final class SDLHoleDataProcessor {
|
||||||
|
enum ProcessingAction {
|
||||||
|
case sendARPReply(dstMac: Data, data: Data)
|
||||||
|
case appendARP(ip: UInt32, mac: Data)
|
||||||
|
case writeToTun(packetData: Data, identityID: UInt32)
|
||||||
|
case requestPolicy(srcIdentityID: UInt32)
|
||||||
|
case none
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProcessingPlan {
|
||||||
|
let inboundBytes: Int
|
||||||
|
let action: ProcessingAction
|
||||||
|
}
|
||||||
|
|
||||||
|
private let networkAddress: SDLConfiguration.NetworkAddress
|
||||||
|
private let dataCipher: CCDataCipher?
|
||||||
|
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
|
||||||
|
private let flowSessionManager: SDLFlowSessionManager
|
||||||
|
|
||||||
|
init(networkAddress: SDLConfiguration.NetworkAddress,
|
||||||
|
dataCipher: CCDataCipher?,
|
||||||
|
snapshotPublisher: SnapshotPublisher<IdentitySnapshot>,
|
||||||
|
flowSessionManager: SDLFlowSessionManager) {
|
||||||
|
self.networkAddress = networkAddress
|
||||||
|
self.dataCipher = dataCipher
|
||||||
|
self.snapshotPublisher = snapshotPublisher
|
||||||
|
self.flowSessionManager = flowSessionManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeProcessingPlan(data: SDLData) throws -> ProcessingPlan? {
|
||||||
|
guard let dataCipher = self.dataCipher else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let mac = LayerPacket.MacAddress(data: data.dstMac)
|
||||||
|
guard (data.dstMac == self.networkAddress.mac || mac.isBroadcast() || mac.isMulticast()) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let decryptedData = try dataCipher.decrypt(cipherText: Data(data.data))
|
||||||
|
let layerPacket = try LayerPacket(layerData: decryptedData)
|
||||||
|
let inboundBytes = decryptedData.count
|
||||||
|
|
||||||
|
// 处理arp请求
|
||||||
|
switch layerPacket.type {
|
||||||
|
case .arp:
|
||||||
|
return self.makeARPPlan(layerData: layerPacket.data, inboundBytes: inboundBytes)
|
||||||
|
case .ipv4:
|
||||||
|
return self.makeIPv4Plan(layerData: layerPacket.data, identityID: data.identityID, inboundBytes: inboundBytes)
|
||||||
|
default:
|
||||||
|
SDLLogger.log("[SDLContext] get invalid packet", for: .debug)
|
||||||
|
return .init(inboundBytes: inboundBytes, action: .none)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func makeARPPlan(layerData: Data, inboundBytes: Int) -> ProcessingPlan {
|
||||||
|
// 判断如果收到的是arp请求
|
||||||
|
if let arpPacket = ARPPacket(data: layerData) {
|
||||||
|
if arpPacket.targetIP == self.networkAddress.ip {
|
||||||
|
switch arpPacket.opcode {
|
||||||
|
case .request:
|
||||||
|
let response = ARPPacket.arpResponse(for: arpPacket, mac: self.networkAddress.mac, ip: self.networkAddress.ip)
|
||||||
|
return .init(
|
||||||
|
inboundBytes: inboundBytes,
|
||||||
|
action: .sendARPReply(dstMac: arpPacket.senderMAC, data: response.marshal())
|
||||||
|
)
|
||||||
|
case .response:
|
||||||
|
return .init(
|
||||||
|
inboundBytes: inboundBytes,
|
||||||
|
action: .appendARP(ip: arpPacket.senderIP, mac: arpPacket.senderMAC)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDLLogger.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(self.networkAddress.ip))")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDLLogger.log("[SDLContext] get invalid arp packet")
|
||||||
|
}
|
||||||
|
|
||||||
|
return .init(inboundBytes: inboundBytes, action: .none)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func makeIPv4Plan(layerData: Data, identityID: UInt32, inboundBytes: Int) -> ProcessingPlan {
|
||||||
|
// 有数据是通过出口网关转发的,所有只判断是合法的ip包
|
||||||
|
guard let ipPacket = IPPacket(layerData) else {
|
||||||
|
return .init(inboundBytes: inboundBytes, action: .none)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查权限逻辑
|
||||||
|
let identitySnapshot = self.snapshotPublisher.current()
|
||||||
|
let ruleMap = identitySnapshot.lookup(identityID)
|
||||||
|
|
||||||
|
if true || self.checkPolicy(ipPacket: ipPacket, ruleMap: ruleMap) {
|
||||||
|
return .init(
|
||||||
|
inboundBytes: inboundBytes,
|
||||||
|
action: .writeToTun(packetData: ipPacket.data, identityID: identityID)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .init(
|
||||||
|
inboundBytes: inboundBytes,
|
||||||
|
action: .requestPolicy(srcIdentityID: identityID)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func checkPolicy(ipPacket: IPPacket, ruleMap: IdentityRuleMap?) -> Bool {
|
||||||
|
// 进来的数据反转一下,然后再处理
|
||||||
|
if let reverseFlowSession = ipPacket.flowSession()?.reverse(),
|
||||||
|
self.flowSessionManager.hasSession(reverseFlowSession) {
|
||||||
|
self.flowSessionManager.updateSession(reverseFlowSession)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查权限逻辑
|
||||||
|
let proto = ipPacket.header.proto
|
||||||
|
// 优先判断访问规则
|
||||||
|
switch ipPacket.transportPacket {
|
||||||
|
case .tcp(let tcpPacket):
|
||||||
|
if let ruleMap, ruleMap.isAllow(proto: proto, port: tcpPacket.header.dstPort) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case .udp(let udpPacket):
|
||||||
|
if let ruleMap, ruleMap.isAllow(proto: proto, port: udpPacket.dstPort) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case .icmp(_):
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user