fix rules
This commit is contained in:
parent
3947c1f6da
commit
2e6e1e5b3f
@ -6,17 +6,17 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
struct IdentityRuleMap {
|
struct IdentityRuleMap {
|
||||||
let ruleMap: [UInt32: [UInt32: UInt8]]
|
// map[proto][port]
|
||||||
|
let ruleMap: [UInt8: [UInt16: Bool]]
|
||||||
|
|
||||||
init(ruleMap: [UInt32: [UInt32: UInt8]]) {
|
init(ruleMap: [UInt8: [UInt16: Bool]]) {
|
||||||
self.ruleMap = ruleMap
|
self.ruleMap = ruleMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func isAllow(proto: UInt32, port: UInt32) -> Bool {
|
func isAllow(proto: UInt8, port: UInt16) -> Bool {
|
||||||
if let portMap = self.ruleMap[proto],
|
if let portMap = self.ruleMap[proto],
|
||||||
let allowed = portMap[port],
|
let allowed = portMap[port] {
|
||||||
allowed > 0 {
|
return allowed
|
||||||
return true
|
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,28 +5,106 @@
|
|||||||
// Created by 安礼成 on 2026/2/5.
|
// Created by 安礼成 on 2026/2/5.
|
||||||
//
|
//
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import NIO
|
||||||
|
|
||||||
|
final class IdentitySession {
|
||||||
|
var version: UInt32
|
||||||
|
var totalNum: UInt32
|
||||||
|
private var parts: [UInt32: SDLPolicyResponse] = [:]
|
||||||
|
|
||||||
|
init(part: SDLPolicyResponse) {
|
||||||
|
self.version = part.version
|
||||||
|
self.totalNum = part.totalNum
|
||||||
|
self.parts[part.index] = part
|
||||||
|
}
|
||||||
|
|
||||||
|
func merge(part: SDLPolicyResponse) {
|
||||||
|
if part.version < version {
|
||||||
|
// 低版本数据丢弃
|
||||||
|
} else if part.version == version {
|
||||||
|
self.parts[part.index] = part
|
||||||
|
} else {
|
||||||
|
self.parts.removeAll()
|
||||||
|
self.parts[part.index] = part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func process() -> Data? {
|
||||||
|
// parts是连续的,从0开始,并且数量等于total_num
|
||||||
|
let indexs = parts.keys.sorted().map { UInt32($0) }
|
||||||
|
guard indexs.count == self.totalNum && isContinuousFromZero(indexs: indexs) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var rulesData: Data = Data()
|
||||||
|
for i in 0..<totalNum {
|
||||||
|
if let part = self.parts[i] {
|
||||||
|
rulesData.append(part.rules)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDLLogger.shared.log("[IdentitySession] get a completed rules: \(rulesData.count)")
|
||||||
|
|
||||||
|
return rulesData
|
||||||
|
}
|
||||||
|
|
||||||
|
private func isContinuousFromZero(indexs: [UInt32]) -> Bool {
|
||||||
|
guard !indexs.isEmpty else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return indexs.enumerated().allSatisfy { idx, value in
|
||||||
|
idx == value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
actor IdentityStore {
|
actor IdentityStore {
|
||||||
typealias IdentityID = UInt32
|
typealias IdentityID = UInt32
|
||||||
|
|
||||||
|
nonisolated private let alloctor = ByteBufferAllocator()
|
||||||
|
|
||||||
private let publisher: SnapshotPublisher<IdentitySnapshot>
|
private let publisher: SnapshotPublisher<IdentitySnapshot>
|
||||||
private let identityMap: [IdentityID: IdentityRuleMap] = [:]
|
private var identityMap: [IdentityID: IdentityRuleMap] = [:]
|
||||||
|
private var sessions: [IdentityID: IdentitySession] = [:]
|
||||||
|
|
||||||
init(publisher: SnapshotPublisher<IdentitySnapshot>) {
|
init(publisher: SnapshotPublisher<IdentitySnapshot>) {
|
||||||
self.publisher = publisher
|
self.publisher = publisher
|
||||||
}
|
}
|
||||||
|
|
||||||
func apply(_ id: IdentityID, ruleBytes: Data) {
|
func apply(policyResponse: SDLPolicyResponse) {
|
||||||
|
let id = policyResponse.srcIdentityID
|
||||||
|
let session = self.sessions[id, default: IdentitySession(part: policyResponse)]
|
||||||
|
session.merge(part: policyResponse)
|
||||||
|
|
||||||
// if model.affectsRuntime {
|
// 判断一下是否接受完成
|
||||||
// let snapshot = compileSnapshot(from: model)
|
if let rulesData = session.process() {
|
||||||
// publisher.publish(snapshot)
|
var buffer = alloctor.buffer(bytes: rulesData)
|
||||||
// }
|
var ruleMap: [UInt8: [UInt16: Bool]] = [:]
|
||||||
|
while true {
|
||||||
|
guard let proto = buffer.readInteger(endianness: .big, as: UInt8.self),
|
||||||
|
let port = buffer.readInteger(endianness: .big, as: UInt16.self) else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ruleMap[proto, default: [:]][port] = true
|
||||||
|
}
|
||||||
|
self.identityMap[id] = IdentityRuleMap(ruleMap: ruleMap)
|
||||||
|
|
||||||
|
// 删除当前的session信息
|
||||||
|
self.sessions.removeValue(forKey: id)
|
||||||
|
|
||||||
|
SDLLogger.shared.log("[IdentitySession] get compile Snapshot rules nums: \(self.identityMap[id]?.ruleMap.count), success: \(self.identityMap[id]?.isAllow(proto: 1, port: 80))")
|
||||||
|
|
||||||
|
// 发布新的快照信息
|
||||||
|
let snapshot = compileSnapshot()
|
||||||
|
publisher.publish(snapshot)
|
||||||
|
} else {
|
||||||
|
self.sessions[id] = session
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func compileSnapshot() -> IdentitySnapshot {
|
||||||
|
return IdentitySnapshot(identityMap: identityMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// func compileSnapshot() -> IdentitySnapshot {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|||||||
56
Tun/Punchnet/Policy/PolicyRequesterActor.swift
Normal file
56
Tun/Punchnet/Policy/PolicyRequesterActor.swift
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// SDLPuncherActor.swift
|
||||||
|
// Tun
|
||||||
|
//
|
||||||
|
// Created by 安礼成 on 2026/1/7.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import NIOCore
|
||||||
|
|
||||||
|
actor PolicyRequesterActor {
|
||||||
|
nonisolated private let cooldown: Duration = .seconds(5)
|
||||||
|
|
||||||
|
// identityId
|
||||||
|
private var coolingDown: Set<UInt32> = []
|
||||||
|
|
||||||
|
// 处理各个请求的版本问题, map[identityId] = version
|
||||||
|
private var versions: [UInt32: UInt32] = [:]
|
||||||
|
// 处理holer
|
||||||
|
nonisolated private let querySocketAddress: SocketAddress
|
||||||
|
|
||||||
|
init(querySocketAddress: SocketAddress) {
|
||||||
|
self.querySocketAddress = querySocketAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交权限请求
|
||||||
|
func submitPolicyRequest(using udpHole: SDLUDPHole?, request: inout SDLPolicyRequest) {
|
||||||
|
let identityId = request.srcIdentityID
|
||||||
|
guard let udpHole, !coolingDown.contains(identityId) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发一次打洞
|
||||||
|
coolingDown.insert(identityId)
|
||||||
|
|
||||||
|
let version = self.versions[identityId, default: 1]
|
||||||
|
request.version = version
|
||||||
|
// 更新请求的版本问题
|
||||||
|
self.versions[identityId] = version + 1
|
||||||
|
// 发送请求
|
||||||
|
if let queryData = try? request.serializedData() {
|
||||||
|
udpHole.send(type: .policyRequest, data: queryData, remoteAddress: self.querySocketAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
Task {
|
||||||
|
// 启动冷却期
|
||||||
|
try? await Task.sleep(for: .seconds(5))
|
||||||
|
self.endCooldown(for: identityId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func endCooldown(for key: UInt32) {
|
||||||
|
self.coolingDown.remove(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -13,11 +13,6 @@ final class SnapshotPublisher<IdentitySnapshot: AnyObject> {
|
|||||||
self.atomic = ManagedAtomic(.passRetained(snapshot))
|
self.atomic = ManagedAtomic(.passRetained(snapshot))
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
|
||||||
let ref = atomic.load(ordering: .relaxed)
|
|
||||||
ref.release()
|
|
||||||
}
|
|
||||||
|
|
||||||
func publish(_ snapshot: IdentitySnapshot) {
|
func publish(_ snapshot: IdentitySnapshot) {
|
||||||
let newRef = Unmanaged.passRetained(snapshot)
|
let newRef = Unmanaged.passRetained(snapshot)
|
||||||
let oldRef = atomic.exchange(newRef, ordering: .acquiring)
|
let oldRef = atomic.exchange(newRef, ordering: .acquiring)
|
||||||
@ -29,4 +24,9 @@ final class SnapshotPublisher<IdentitySnapshot: AnyObject> {
|
|||||||
atomic.load(ordering: .relaxed).takeUnretainedValue()
|
atomic.load(ordering: .relaxed).takeUnretainedValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
let ref = atomic.load(ordering: .relaxed)
|
||||||
|
ref.release()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,6 +81,7 @@ public class SDLConfiguration {
|
|||||||
let networkAddress: NetworkAddress
|
let networkAddress: NetworkAddress
|
||||||
let hostname: String
|
let hostname: String
|
||||||
let accessToken: String
|
let accessToken: String
|
||||||
|
let identityId: UInt32
|
||||||
|
|
||||||
public init(version: UInt8,
|
public init(version: UInt8,
|
||||||
installedChannel: String,
|
installedChannel: String,
|
||||||
@ -92,6 +93,7 @@ public class SDLConfiguration {
|
|||||||
hostname: String,
|
hostname: String,
|
||||||
noticePort: Int,
|
noticePort: Int,
|
||||||
accessToken: String,
|
accessToken: String,
|
||||||
|
identityId: UInt32,
|
||||||
remoteDnsServer: String) {
|
remoteDnsServer: String) {
|
||||||
|
|
||||||
self.version = version
|
self.version = version
|
||||||
@ -103,6 +105,7 @@ public class SDLConfiguration {
|
|||||||
self.networkAddress = networkAddress
|
self.networkAddress = networkAddress
|
||||||
self.noticePort = noticePort
|
self.noticePort = noticePort
|
||||||
self.accessToken = accessToken
|
self.accessToken = accessToken
|
||||||
|
self.identityId = identityId
|
||||||
self.remoteDnsServer = remoteDnsServer
|
self.remoteDnsServer = remoteDnsServer
|
||||||
self.hostname = hostname
|
self.hostname = hostname
|
||||||
}
|
}
|
||||||
@ -118,6 +121,7 @@ extension SDLConfiguration {
|
|||||||
let stunServersStr = options["stun_servers"] as? String,
|
let stunServersStr = options["stun_servers"] as? String,
|
||||||
let noticePort = options["notice_port"] as? Int,
|
let noticePort = options["notice_port"] as? Int,
|
||||||
let accessToken = options["access_token"] as? String,
|
let accessToken = options["access_token"] as? String,
|
||||||
|
let identityId = options["identity_id"] as? UInt32,
|
||||||
let clientId = options["client_id"] as? String,
|
let clientId = options["client_id"] as? String,
|
||||||
let remoteDnsServer = options["remote_dns_server"] as? String,
|
let remoteDnsServer = options["remote_dns_server"] as? String,
|
||||||
let hostname = options["hostname"] as? String,
|
let hostname = options["hostname"] as? String,
|
||||||
@ -144,6 +148,7 @@ extension SDLConfiguration {
|
|||||||
hostname: hostname,
|
hostname: hostname,
|
||||||
noticePort: noticePort,
|
noticePort: noticePort,
|
||||||
accessToken: accessToken,
|
accessToken: accessToken,
|
||||||
|
identityId: identityId,
|
||||||
remoteDnsServer: remoteDnsServer)
|
remoteDnsServer: remoteDnsServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -73,6 +73,7 @@ actor SDLContextActor {
|
|||||||
// 处理权限控制
|
// 处理权限控制
|
||||||
private let identifyStore: IdentityStore
|
private let identifyStore: IdentityStore
|
||||||
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
|
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
|
||||||
|
private let policyRequesterActor: PolicyRequesterActor
|
||||||
|
|
||||||
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher, aesCipher: AESCipher) {
|
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher, aesCipher: AESCipher) {
|
||||||
self.provider = provider
|
self.provider = provider
|
||||||
@ -90,6 +91,7 @@ actor SDLContextActor {
|
|||||||
let snapshotPublisher = SnapshotPublisher(initial: IdentitySnapshot.empty())
|
let snapshotPublisher = SnapshotPublisher(initial: IdentitySnapshot.empty())
|
||||||
self.identifyStore = IdentityStore(publisher: snapshotPublisher)
|
self.identifyStore = IdentityStore(publisher: snapshotPublisher)
|
||||||
self.snapshotPublisher = snapshotPublisher
|
self.snapshotPublisher = snapshotPublisher
|
||||||
|
self.policyRequesterActor = PolicyRequesterActor(querySocketAddress: config.stunSocketAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func start() {
|
public func start() {
|
||||||
@ -241,6 +243,10 @@ actor SDLContextActor {
|
|||||||
try? await self.handleRegister(remoteAddress: remoteAddress, register: register)
|
try? await self.handleRegister(remoteAddress: remoteAddress, register: register)
|
||||||
case .registerAck(let registerAck):
|
case .registerAck(let registerAck):
|
||||||
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
|
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
|
||||||
|
case .policyReponse(let policyResponse):
|
||||||
|
SDLLogger.shared.log("[SDLContext] get a policyResponse: \(policyResponse.totalNum) of \(policyResponse.index), bytes: \(policyResponse.rules.count)")
|
||||||
|
// 处理权限的请求问题
|
||||||
|
await self.identifyStore.apply(policyResponse: policyResponse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +304,6 @@ actor SDLContextActor {
|
|||||||
stunRequest.natType = UInt32(self.natType.rawValue)
|
stunRequest.natType = UInt32(self.natType.rawValue)
|
||||||
stunRequest.sessionToken = sessionToken
|
stunRequest.sessionToken = sessionToken
|
||||||
|
|
||||||
SDLLogger.shared.log("[SDLContext] send stun request: \(stunRequest)")
|
|
||||||
if let stunData = try? stunRequest.serializedData() {
|
if let stunData = try? stunRequest.serializedData() {
|
||||||
let remoteAddress = self.config.stunSocketAddress
|
let remoteAddress = self.config.stunSocketAddress
|
||||||
self.udpHole?.send(type: .stunRequest, data: stunData, remoteAddress: remoteAddress)
|
self.udpHole?.send(type: .stunRequest, data: stunData, remoteAddress: remoteAddress)
|
||||||
@ -310,6 +315,8 @@ actor SDLContextActor {
|
|||||||
self.aesKey = try! self.rsaCipher.decode(data: Data(registerSuperAck.aesKey))
|
self.aesKey = try! self.rsaCipher.decode(data: Data(registerSuperAck.aesKey))
|
||||||
self.sessionToken = registerSuperAck.sessionToken
|
self.sessionToken = registerSuperAck.sessionToken
|
||||||
|
|
||||||
|
await self.triggerPolicy()
|
||||||
|
|
||||||
SDLLogger.shared.log("[SDLContext] get registerSuperAck, aes_key len: \(self.aesKey!.count)", level: .info)
|
SDLLogger.shared.log("[SDLContext] get registerSuperAck, aes_key len: \(self.aesKey!.count)", level: .info)
|
||||||
// 服务器分配的tun网卡信息
|
// 服务器分配的tun网卡信息
|
||||||
do {
|
do {
|
||||||
@ -496,15 +503,24 @@ actor SDLContextActor {
|
|||||||
self.provider.packetFlow.writePacketObjects([packet])
|
self.provider.packetFlow.writePacketObjects([packet])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// todo 向服务器请求权限逻辑
|
// 向服务器请求权限逻辑
|
||||||
|
if let sessionToken = self.sessionToken {
|
||||||
|
var policyRequest = SDLPolicyRequest()
|
||||||
|
policyRequest.clientID = self.config.clientId
|
||||||
|
policyRequest.networkID = self.config.networkAddress.networkId
|
||||||
|
policyRequest.mac = self.config.networkAddress.mac
|
||||||
|
policyRequest.srcIdentityID = data.identityID
|
||||||
|
policyRequest.dstIdentityID = self.config.identityId
|
||||||
|
policyRequest.sessionToken = sessionToken
|
||||||
|
|
||||||
|
await self.policyRequesterActor.submitPolicyRequest(using: self.udpHole, request: &policyRequest)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
SDLLogger.shared.log("[SDLContext] get invalid packet", level: .debug)
|
SDLLogger.shared.log("[SDLContext] get invalid packet", level: .debug)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 流量统计
|
// 流量统计
|
||||||
// public func flowReportTask() {
|
// public func flowReportTask() {
|
||||||
// Task {
|
// Task {
|
||||||
@ -585,6 +601,7 @@ actor SDLContextActor {
|
|||||||
dataPacket.srcMac = networkAddr.mac
|
dataPacket.srcMac = networkAddr.mac
|
||||||
dataPacket.dstMac = dstMac
|
dataPacket.dstMac = dstMac
|
||||||
dataPacket.ttl = 255
|
dataPacket.ttl = 255
|
||||||
|
dataPacket.identityID = self.config.identityId
|
||||||
dataPacket.data = encodedPacket
|
dataPacket.data = encodedPacket
|
||||||
|
|
||||||
let data = try! dataPacket.serializedData()
|
let data = try! dataPacket.serializedData()
|
||||||
@ -665,6 +682,22 @@ actor SDLContextActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo 测试代码
|
||||||
|
private func triggerPolicy() async {
|
||||||
|
// 向服务器请求权限逻辑
|
||||||
|
if let sessionToken = self.sessionToken {
|
||||||
|
var policyRequest = SDLPolicyRequest()
|
||||||
|
policyRequest.clientID = self.config.clientId
|
||||||
|
policyRequest.networkID = self.config.networkAddress.networkId
|
||||||
|
policyRequest.mac = self.config.networkAddress.mac
|
||||||
|
policyRequest.srcIdentityID = 1234
|
||||||
|
policyRequest.dstIdentityID = self.config.identityId
|
||||||
|
policyRequest.sessionToken = sessionToken
|
||||||
|
|
||||||
|
await self.policyRequesterActor.submitPolicyRequest(using: self.udpHole, request: &policyRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.udpHole = nil
|
self.udpHole = nil
|
||||||
self.dnsClient = nil
|
self.dnsClient = nil
|
||||||
|
|||||||
@ -467,12 +467,18 @@ struct SDLPolicyRequest: @unchecked Sendable {
|
|||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||||
// methods supported on all messages.
|
// methods supported on all messages.
|
||||||
|
|
||||||
|
var clientID: String = String()
|
||||||
|
|
||||||
var networkID: UInt32 = 0
|
var networkID: UInt32 = 0
|
||||||
|
|
||||||
|
var mac: Data = Data()
|
||||||
|
|
||||||
var srcIdentityID: UInt32 = 0
|
var srcIdentityID: UInt32 = 0
|
||||||
|
|
||||||
var dstIdentityID: UInt32 = 0
|
var dstIdentityID: UInt32 = 0
|
||||||
|
|
||||||
|
var version: UInt32 = 0
|
||||||
|
|
||||||
var sessionToken: Data = Data()
|
var sessionToken: Data = Data()
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||||
@ -1589,10 +1595,13 @@ extension SDLArpResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
|
|||||||
extension SDLPolicyRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
extension SDLPolicyRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||||
static let protoMessageName: String = "SDLPolicyRequest"
|
static let protoMessageName: String = "SDLPolicyRequest"
|
||||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||||
1: .standard(proto: "network_id"),
|
1: .standard(proto: "client_id"),
|
||||||
2: .standard(proto: "src_identity_id"),
|
2: .standard(proto: "network_id"),
|
||||||
3: .standard(proto: "dst_identity_id"),
|
3: .same(proto: "mac"),
|
||||||
4: .standard(proto: "session_token"),
|
4: .standard(proto: "src_identity_id"),
|
||||||
|
5: .standard(proto: "dst_identity_id"),
|
||||||
|
6: .same(proto: "version"),
|
||||||
|
7: .standard(proto: "session_token"),
|
||||||
]
|
]
|
||||||
|
|
||||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||||
@ -1601,35 +1610,50 @@ extension SDLPolicyRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme
|
|||||||
// allocates stack space for every case branch when no optimizations are
|
// allocates stack space for every case branch when no optimizations are
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||||
switch fieldNumber {
|
switch fieldNumber {
|
||||||
case 1: try { try decoder.decodeSingularUInt32Field(value: &self.networkID) }()
|
case 1: try { try decoder.decodeSingularStringField(value: &self.clientID) }()
|
||||||
case 2: try { try decoder.decodeSingularUInt32Field(value: &self.srcIdentityID) }()
|
case 2: try { try decoder.decodeSingularUInt32Field(value: &self.networkID) }()
|
||||||
case 3: try { try decoder.decodeSingularUInt32Field(value: &self.dstIdentityID) }()
|
case 3: try { try decoder.decodeSingularBytesField(value: &self.mac) }()
|
||||||
case 4: try { try decoder.decodeSingularBytesField(value: &self.sessionToken) }()
|
case 4: try { try decoder.decodeSingularUInt32Field(value: &self.srcIdentityID) }()
|
||||||
|
case 5: try { try decoder.decodeSingularUInt32Field(value: &self.dstIdentityID) }()
|
||||||
|
case 6: try { try decoder.decodeSingularUInt32Field(value: &self.version) }()
|
||||||
|
case 7: try { try decoder.decodeSingularBytesField(value: &self.sessionToken) }()
|
||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||||
|
if !self.clientID.isEmpty {
|
||||||
|
try visitor.visitSingularStringField(value: self.clientID, fieldNumber: 1)
|
||||||
|
}
|
||||||
if self.networkID != 0 {
|
if self.networkID != 0 {
|
||||||
try visitor.visitSingularUInt32Field(value: self.networkID, fieldNumber: 1)
|
try visitor.visitSingularUInt32Field(value: self.networkID, fieldNumber: 2)
|
||||||
|
}
|
||||||
|
if !self.mac.isEmpty {
|
||||||
|
try visitor.visitSingularBytesField(value: self.mac, fieldNumber: 3)
|
||||||
}
|
}
|
||||||
if self.srcIdentityID != 0 {
|
if self.srcIdentityID != 0 {
|
||||||
try visitor.visitSingularUInt32Field(value: self.srcIdentityID, fieldNumber: 2)
|
try visitor.visitSingularUInt32Field(value: self.srcIdentityID, fieldNumber: 4)
|
||||||
}
|
}
|
||||||
if self.dstIdentityID != 0 {
|
if self.dstIdentityID != 0 {
|
||||||
try visitor.visitSingularUInt32Field(value: self.dstIdentityID, fieldNumber: 3)
|
try visitor.visitSingularUInt32Field(value: self.dstIdentityID, fieldNumber: 5)
|
||||||
|
}
|
||||||
|
if self.version != 0 {
|
||||||
|
try visitor.visitSingularUInt32Field(value: self.version, fieldNumber: 6)
|
||||||
}
|
}
|
||||||
if !self.sessionToken.isEmpty {
|
if !self.sessionToken.isEmpty {
|
||||||
try visitor.visitSingularBytesField(value: self.sessionToken, fieldNumber: 4)
|
try visitor.visitSingularBytesField(value: self.sessionToken, fieldNumber: 7)
|
||||||
}
|
}
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
try unknownFields.traverse(visitor: &visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ==(lhs: SDLPolicyRequest, rhs: SDLPolicyRequest) -> Bool {
|
static func ==(lhs: SDLPolicyRequest, rhs: SDLPolicyRequest) -> Bool {
|
||||||
|
if lhs.clientID != rhs.clientID {return false}
|
||||||
if lhs.networkID != rhs.networkID {return false}
|
if lhs.networkID != rhs.networkID {return false}
|
||||||
|
if lhs.mac != rhs.mac {return false}
|
||||||
if lhs.srcIdentityID != rhs.srcIdentityID {return false}
|
if lhs.srcIdentityID != rhs.srcIdentityID {return false}
|
||||||
if lhs.dstIdentityID != rhs.dstIdentityID {return false}
|
if lhs.dstIdentityID != rhs.dstIdentityID {return false}
|
||||||
|
if lhs.version != rhs.version {return false}
|
||||||
if lhs.sessionToken != rhs.sessionToken {return false}
|
if lhs.sessionToken != rhs.sessionToken {return false}
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -32,6 +32,10 @@ enum SDLPacketType: UInt8 {
|
|||||||
case stunProbe = 0x32
|
case stunProbe = 0x32
|
||||||
case stunProbeReply = 0x33
|
case stunProbeReply = 0x33
|
||||||
|
|
||||||
|
// 权限控制
|
||||||
|
case policyRequest = 0xb0
|
||||||
|
case policyResponse = 0xb1
|
||||||
|
|
||||||
case data = 0xFF
|
case data = 0xFF
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +107,8 @@ enum SDLHoleSignal {
|
|||||||
|
|
||||||
case register(SDLRegister)
|
case register(SDLRegister)
|
||||||
case registerAck(SDLRegisterAck)
|
case registerAck(SDLRegisterAck)
|
||||||
|
|
||||||
|
case policyReponse(SDLPolicyResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 命令类型
|
// 命令类型
|
||||||
|
|||||||
@ -137,9 +137,11 @@ final class SDLUDPHole: ChannelInboundHandler {
|
|||||||
|
|
||||||
// --MARK: 编解码器
|
// --MARK: 编解码器
|
||||||
private func decode(buffer: inout ByteBuffer) throws -> SDLHoleMessage? {
|
private func decode(buffer: inout ByteBuffer) throws -> SDLHoleMessage? {
|
||||||
|
let rawType = buffer.getInteger(at: 0, endianness: .big, as: UInt8.self)
|
||||||
|
|
||||||
guard let type = buffer.readInteger(as: UInt8.self),
|
guard let type = buffer.readInteger(as: UInt8.self),
|
||||||
let packetType = SDLPacketType(rawValue: type) else {
|
let packetType = SDLPacketType(rawValue: type) else {
|
||||||
SDLLogger.shared.log("[SDLUDPHole] decode error 11")
|
SDLLogger.shared.log("[SDLUDPHole] decode error 11: \(rawType)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +188,12 @@ final class SDLUDPHole: ChannelInboundHandler {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return .signal(.peerInfo(peerInfo))
|
return .signal(.peerInfo(peerInfo))
|
||||||
|
case .policyResponse:
|
||||||
|
guard let bytes = buffer.readBytes(length: buffer.readableBytes),
|
||||||
|
let policyResponse = try? SDLPolicyResponse(serializedBytes: bytes) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return .signal(.policyReponse(policyResponse))
|
||||||
case .event:
|
case .event:
|
||||||
guard let eventVal = buffer.readInteger(as: UInt8.self),
|
guard let eventVal = buffer.readInteger(as: UInt8.self),
|
||||||
let event = SDLEventType(rawValue: eventVal),
|
let event = SDLEventType(rawValue: eventVal),
|
||||||
@ -220,7 +228,6 @@ final class SDLUDPHole: ChannelInboundHandler {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return .signal(.event(.refreshAuth(refreshAuthEvent)))
|
return .signal(.event(.refreshAuth(refreshAuthEvent)))
|
||||||
|
|
||||||
case .networkShutdown:
|
case .networkShutdown:
|
||||||
guard let networkShutdownEvent = try? SDLNetworkShutdownEvent(serializedBytes: bytes) else {
|
guard let networkShutdownEvent = try? SDLNetworkShutdownEvent(serializedBytes: bytes) else {
|
||||||
SDLLogger.shared.log("[SDLUDPHole] decode error 18")
|
SDLLogger.shared.log("[SDLUDPHole] decode error 18")
|
||||||
|
|||||||
@ -26,7 +26,7 @@ struct SystemConfig {
|
|||||||
static let stunServers = "118.178.229.213:1365,1366;118.178.229.213:1365,1366"
|
static let stunServers = "118.178.229.213:1365,1366;118.178.229.213:1365,1366"
|
||||||
//static let stunServers = "127.0.0.1:1265,1266;127.0.0.1:1265,1266"
|
//static let stunServers = "127.0.0.1:1265,1266;127.0.0.1:1265,1266"
|
||||||
|
|
||||||
static func getOptions(networkId: UInt32, networkDomain: String, ip: String, maskLen: UInt8, accessToken: String, hostname: String, noticePort: Int) -> [String: NSObject]? {
|
static func getOptions(networkId: UInt32, networkDomain: String, ip: String, maskLen: UInt8, accessToken: String, identityId: UInt32, hostname: String, noticePort: Int) -> [String: NSObject]? {
|
||||||
guard let superIp = DNSResolver.resolveAddrInfos(superHost).first else {
|
guard let superIp = DNSResolver.resolveAddrInfos(superHost).first else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -39,6 +39,7 @@ struct SystemConfig {
|
|||||||
"installed_channel": installedChannel as NSObject,
|
"installed_channel": installedChannel as NSObject,
|
||||||
"client_id": clientId as NSObject,
|
"client_id": clientId as NSObject,
|
||||||
"access_token": accessToken as NSObject,
|
"access_token": accessToken as NSObject,
|
||||||
|
"identity_id": identityId as NSObject,
|
||||||
"super_ip": superIp as NSObject,
|
"super_ip": superIp as NSObject,
|
||||||
"super_port": superPort as NSObject,
|
"super_port": superPort as NSObject,
|
||||||
"stun_servers": stunServers as NSObject,
|
"stun_servers": stunServers as NSObject,
|
||||||
|
|||||||
@ -61,6 +61,7 @@ struct NetworkDisconnctedView: View {
|
|||||||
ip: "10.211.179.1",
|
ip: "10.211.179.1",
|
||||||
maskLen: 24,
|
maskLen: 24,
|
||||||
accessToken: "accessToken1234",
|
accessToken: "accessToken1234",
|
||||||
|
identityId: 1234,
|
||||||
hostname: "mysql",
|
hostname: "mysql",
|
||||||
noticePort: 1234)
|
noticePort: 1234)
|
||||||
// token存在则优先使用token
|
// token存在则优先使用token
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user