fix ipPacket

This commit is contained in:
anlicheng 2026-05-25 18:38:51 +08:00
parent a728fd5408
commit 03e8854e79
7 changed files with 28 additions and 219 deletions

View File

@ -38,79 +38,6 @@ struct IPHeader {
} }
} }
// MARK: - IP Packet
struct IPPacket {
let header: IPHeader
let data: Data
let transportPacket: TransportPacket
enum TransportPacket {
case tcp(TCPPacket)
case udp(UDPPacket)
case icmp(ICMPPacket)
case unsupported(UInt8)
case malformed
}
init?(_ data: Data) {
guard data.count >= 20 else {
return nil
}
let version = data[0] >> 4
let headerLen = (data[0] & 0x0F) * 4
guard data.count >= headerLen else {
return nil
}
self.header = IPHeader(
version: version,
headerLength: headerLen,
typeOfService: data[1],
totalLength: UInt16(bytes: (data[2], data[3])),
id: UInt16(bytes: (data[4], data[5])),
offset: UInt16(bytes: (data[6], data[7])),
ttl: data[8],
proto: data[9],
checksum: UInt16(bytes: (data[10], data[11])),
source: UInt32(bytes: (data[12], data[13], data[14], data[15])),
destination: UInt32(bytes: (data[16], data[17], data[18], data[19]))
)
self.data = data
self.transportPacket = Self.parseTransportPacket(proto: data[9], offset: Int(headerLen), data: data)
}
private static func parseTransportPacket(proto: UInt8, offset: Int, data: Data) -> TransportPacket {
guard let proto = TransportProtocol(rawValue: proto) else {
return .unsupported(proto)
}
switch proto {
case .tcp:
guard let tcp = TCPPacket(data, offset: offset) else {
return .malformed
}
return .tcp(tcp)
case .udp:
guard let udp = UDPPacket(data, offset: offset) else {
return .malformed
}
return .udp(udp)
case .icmp:
guard let icmp = ICMPPacket(data, offset: offset) else {
return .malformed
}
return .icmp(icmp)
}
}
}
// MARK: - Lightweight IP Packet View // MARK: - Lightweight IP Packet View
struct IPPacketView { struct IPPacketView {
@ -195,128 +122,3 @@ struct IPPacketView {
data[data.index(data.startIndex, offsetBy: offset)] data[data.index(data.startIndex, offsetBy: offset)]
} }
} }
// MARK: - TCP Flags
struct TCPFlags: OptionSet {
let rawValue: UInt16
static let fin = TCPFlags(rawValue: 1 << 0)
static let syn = TCPFlags(rawValue: 1 << 1)
static let rst = TCPFlags(rawValue: 1 << 2)
static let psh = TCPFlags(rawValue: 1 << 3)
static let ack = TCPFlags(rawValue: 1 << 4)
static let urg = TCPFlags(rawValue: 1 << 5)
static let ece = TCPFlags(rawValue: 1 << 6)
static let cwr = TCPFlags(rawValue: 1 << 7)
}
// MARK: - TCP Header
struct TCPHeader {
let srcPort: UInt16
let dstPort: UInt16
let seq: UInt32
let ack: UInt32
let dataOffset: UInt8
let flags: TCPFlags
let window: UInt16
let checksum: UInt16
let urgentPointer: UInt16
var headerLength: Int {
Int(dataOffset) * 4
}
}
// MARK: - TCP Packet
struct TCPPacket {
let header: TCPHeader
init?(_ data: Data, offset: Int) {
guard data.count >= offset + 20 else {
return nil
}
let srcPort = UInt16(bytes: (data[offset], data[offset + 1]))
let dstPort = UInt16(bytes: (data[offset + 2], data[offset + 3]))
let seq = UInt32(bytes: (data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7]))
let ack = UInt32(bytes: (data[offset + 8], data[offset + 9], data[offset + 10], data[offset + 11]))
let offsetAndFlags = UInt16(bytes: (data[offset + 12], data[offset + 13]))
let dataOffset = UInt8(offsetAndFlags >> 12)
let flags = TCPFlags(rawValue: offsetAndFlags & 0x01FF)
let window = UInt16(bytes: (data[offset + 14], data[offset + 15]))
let checksum = UInt16(bytes: (data[offset + 16], data[offset + 17]))
let urgent = UInt16(bytes: (data[offset + 18], data[offset + 19]))
let header = TCPHeader(
srcPort: srcPort,
dstPort: dstPort,
seq: seq,
ack: ack,
dataOffset: dataOffset,
flags: flags,
window: window,
checksum: checksum,
urgentPointer: urgent
)
let headerLen = header.headerLength
guard data.count >= offset + headerLen else {
return nil
}
self.header = header
}
}
// MARK: - UDP Packet
struct UDPPacket {
let srcPort: UInt16
let dstPort: UInt16
let length: UInt16
let checksum: UInt16
let payloadOffset: Int
init?(_ data: Data, offset: Int) {
guard data.count >= offset + 8 else {
return nil
}
self.srcPort = UInt16(bytes: (data[offset], data[offset + 1]))
self.dstPort = UInt16(bytes: (data[offset + 2], data[offset + 3]))
self.length = UInt16(bytes: (data[offset + 4], data[offset + 5]))
self.checksum = UInt16(bytes: (data[offset + 6], data[offset + 7]))
self.payloadOffset = offset + 8
}
}
// MARK: - ICMP Packet
struct ICMPPacket {
let type: UInt8
let code: UInt8
let checksum: UInt16
init?(_ data: Data, offset: Int) {
guard data.count >= offset + 4 else {
return nil
}
self.type = data[offset]
self.code = data[offset + 1]
self.checksum = UInt16(bytes: (data[offset + 2], data[offset + 3]))
}
}

View File

@ -120,20 +120,6 @@ final class FlowSessionTable: @unchecked Sendable {
} }
extension IPPacket {
func flowSession() -> FlowSession? {
switch self.transportPacket {
case .tcp(let tcpPacket):
return FlowSession(srcIP: header.source, dstIP: header.destination, srcPort: tcpPacket.header.srcPort, dstPort: tcpPacket.header.dstPort, proto: header.proto)
case .udp(let udpPacket):
return FlowSession(srcIP: header.source, dstIP: header.destination, srcPort: udpPacket.srcPort, dstPort: udpPacket.dstPort, proto: header.proto)
default:
return nil
}
}
}
extension IPPacketView { extension IPPacketView {
func flowSession() -> FlowSession? { func flowSession() -> FlowSession? {

View File

@ -26,18 +26,23 @@ struct PolicyRuntime: @unchecked Sendable {
if let reverseFlowSession = ipPacket.flowSession()?.reverse(), if let reverseFlowSession = ipPacket.flowSession()?.reverse(),
self.flowSessionTable.hasSession(reverseFlowSession) { self.flowSessionTable.hasSession(reverseFlowSession) {
self.flowSessionTable.updateSession(reverseFlowSession) self.flowSessionTable.updateSession(reverseFlowSession)
SDLLogger.log("[PolicyRuntime] session hit, src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))")
return .allow return .allow
} }
if case .icmp = ipPacket.transportPacket { if case .icmp = ipPacket.transportPacket {
SDLLogger.log("[PolicyRuntime] icmp hit, src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))")
return .allow return .allow
} }
guard let ruleMap = self.policyRuleSnapshot.lookup(srcIdentityID) else { guard let ruleMap = self.policyRuleSnapshot.lookup(srcIdentityID) else {
return .missingPolicy return .missingPolicy
} }
return self.isAllowedByRule(ruleMap: ruleMap, ipPacket: ipPacket) ? .allow : .deny let isAllowed = self.isAllowedByRule(ruleMap: ruleMap, ipPacket: ipPacket)
SDLLogger.log("[PolicyRuntime] rule hit: \(isAllowed), src_identify_id: \(srcIdentityID), allow: \(debugInfo(ipPacket: ipPacket))")
return isAllowed ? .allow : .deny
} }
private func isAllowedByRule(ruleMap: PolicyRuleMap, ipPacket: IPPacketView) -> Bool { private func isAllowedByRule(ruleMap: PolicyRuleMap, ipPacket: IPPacketView) -> Bool {
@ -52,4 +57,16 @@ struct PolicyRuntime: @unchecked Sendable {
return false return false
} }
} }
private func debugInfo(ipPacket: IPPacketView) -> String {
switch ipPacket.transportPacket {
case .tcp(_, let dstPort):
return "tcp: \(dstPort)"
case .udp(_, let dstPort, _):
return "udp: \(dstPort)"
default:
return "unknown"
}
}
} }

View File

@ -11,7 +11,11 @@ import Security
enum SDLSuperTLSVerifier { enum SDLSuperTLSVerifier {
// Base64 // Base64
static let pinnedPublicKeyHashes = [ static let pinnedPublicKeyHashes = [
"Q41r6hbMWEVyxo6heNAH4Wx/TH5NNOWlNif9bewcJ3E=" //
"Q41r6hbMWEVyxo6heNAH4Wx/TH5NNOWlNif9bewcJ3E=",
//
"oeU0bWqLWMdn79s4ZHz6IRwXmFX4p70u/Qt9VrsDIb4="
] ]
static func verify(trust: sec_trust_t, host: String) -> Bool { static func verify(trust: sec_trust_t, host: String) -> Bool {

2
dmg.sh
View File

@ -1,3 +1,3 @@
#! /bin/sh #! /bin/sh
create-dmg --volname "punchnet" --window-pos 200 120 --window-size 800 400 --icon "punchnet.app" 200 190 --hide-extension "punchnet.app" --app-drop-link 600 185 ~/Desktop/punchnet.dmg /Users/anlicheng/Desktop/punchnetv10 create-dmg --volname "punchnet" --window-pos 200 120 --window-size 800 400 --icon "punchnet.app" 200 190 --hide-extension "punchnet.app" --app-drop-link 600 185 ~/Desktop/punchnet.dmg /Users/anlicheng/Desktop/punchnet-release-v1.0

View File

@ -18,10 +18,10 @@ struct SystemConfig {
// //
static let channel = "appstore" static let channel = "appstore"
static let serverHost = "root.punchsky.com" static let serverHost = "test.punchsky.com"
// stunip // stunip
static let stunAssistHost = "root.punchsky.com" static let stunAssistHost = "test.punchsky.com"
// //
static let systemInfo: String = { static let systemInfo: String = {

View File

@ -47,7 +47,7 @@ struct SDLAPIClient {
let (data, _) = try await session.data(for: request) let (data, _) = try await session.data(for: request)
if let response = String(bytes: data, encoding: .utf8) { if let response = String(bytes: data, encoding: .utf8) {
NSLog("url: \(path), response is: \(response)") NSLog("url: \(url.absoluteString), response is: \(response)")
} }
let apiResponse = try JSONDecoder().decode(SDLAPIResponse<T>.self, from: data) let apiResponse = try JSONDecoder().decode(SDLAPIResponse<T>.self, from: data)