diff --git a/Tun/Punchnet/Actors/SDLPuncherActor.swift b/Tun/Punchnet/Actors/SDLPuncherActor.swift index 7141f5d..117a328 100644 --- a/Tun/Punchnet/Actors/SDLPuncherActor.swift +++ b/Tun/Punchnet/Actors/SDLPuncherActor.swift @@ -12,7 +12,6 @@ actor SDLPuncherActor { private var coolingDown: Set = [] private let cooldown: Duration = .seconds(5) - private var superClientActor: SDLSuperClientActor? private var udpHoleActor: SDLUDPHoleActor? // 处理holer @@ -28,10 +27,6 @@ actor SDLPuncherActor { self.logger = logger } - func setSuperClientActor(superClientActor: SDLSuperClientActor?) { - self.superClientActor = superClientActor - } - func setUDPHoleActor(udpHoleActor: SDLUDPHoleActor?) { self.udpHoleActor = udpHoleActor } @@ -59,31 +54,31 @@ actor SDLPuncherActor { } private func tryHole(request: RegisterRequest) async { - var queryInfo = SDLQueryInfo() - queryInfo.dstMac = request.dstMac - guard let message = try? await self.superClientActor?.request(type: .queryInfo, data: try queryInfo.serializedData()) else { - return - } - - switch message.packet { - case .empty: - self.logger.log("[SDLContext] hole query_info get empty: \(message)", level: .debug) - case .peerInfo(let peerInfo): - if let remoteAddress = peerInfo.v4Info.socketAddress() { - self.logger.log("[SDLContext] hole sock address: \(remoteAddress)", level: .debug) - // 发送register包 - var register = SDLRegister() - register.networkID = request.networkId - register.srcMac = request.srcMac - register.dstMac = request.dstMac - - await self.udpHoleActor?.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress) - } else { - self.logger.log("[SDLContext] hole sock address is invalid: \(peerInfo.v4Info)", level: .warning) - } - default: - self.logger.log("[SDLContext] hole query_info is packet: \(message)", level: .warning) - } +// var queryInfo = SDLQueryInfo() +// queryInfo.dstMac = request.dstMac +// guard let message = try? await self.superClientActor?.request(type: .queryInfo, data: try queryInfo.serializedData()) else { +// return +// } +// +// switch message.packet { +// case .empty: +// self.logger.log("[SDLContext] hole query_info get empty: \(message)", level: .debug) +// case .peerInfo(let peerInfo): +// if let remoteAddress = peerInfo.v4Info.socketAddress() { +// self.logger.log("[SDLContext] hole sock address: \(remoteAddress)", level: .debug) +// // 发送register包 +// var register = SDLRegister() +// register.networkID = request.networkId +// register.srcMac = request.srcMac +// register.dstMac = request.dstMac +// +// await self.udpHoleActor?.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress) +// } else { +// self.logger.log("[SDLContext] hole sock address is invalid: \(peerInfo.v4Info)", level: .warning) +// } +// default: +// self.logger.log("[SDLContext] hole query_info is packet: \(message)", level: .warning) +// } } } diff --git a/Tun/Punchnet/Actors/SDLTunnelProviderActor.swift b/Tun/Punchnet/Actors/SDLTunnelProviderActor.swift index b5ffbad..a934113 100644 --- a/Tun/Punchnet/Actors/SDLTunnelProviderActor.swift +++ b/Tun/Punchnet/Actors/SDLTunnelProviderActor.swift @@ -44,8 +44,8 @@ actor SDLTunnelProviderActor { } // 网络改变时需要重新配置网络信息 - func setNetworkSettings(devAddr: SDLDevAddr, dnsServer: String) async throws -> String { - let netAddress = SDLNetAddress(ip: devAddr.netAddr, maskLen: UInt8(devAddr.netBitLen)) + func setNetworkSettings(networkAddress: SDLConfiguration.NetworkAddress, dnsServer: String) async throws -> String { + let netAddress = SDLNetAddress(ip: networkAddress.ip, maskLen: networkAddress.maskLen) let routes = [ Route(dstAddress: netAddress.networkAddress, subnetMask: netAddress.maskAddress), Route(dstAddress: dnsServer, subnetMask: "255.255.255.255") @@ -57,7 +57,7 @@ actor SDLTunnelProviderActor { // 设置网卡的DNS解析 - let networkDomain = devAddr.networkDomain + let networkDomain = networkAddress.networkDomain let dnsSettings = NEDNSSettings(servers: [dnsServer]) dnsSettings.searchDomains = [networkDomain] dnsSettings.matchDomains = [networkDomain] diff --git a/Tun/Punchnet/SDLConfiguration.swift b/Tun/Punchnet/SDLConfiguration.swift index 4c8ee52..cc87e22 100644 --- a/Tun/Punchnet/SDLConfiguration.swift +++ b/Tun/Punchnet/SDLConfiguration.swift @@ -20,6 +20,14 @@ public class SDLConfiguration { } } + public struct NetworkAddress { + public let networkId: UInt32 + public let ip: UInt32 + public let maskLen: UInt8 + public let mac: Data + public let networkDomain: String + } + // 当前的客户端版本 let version: UInt8 @@ -36,6 +44,8 @@ public class SDLConfiguration { let noticePort: Int + let networkAddress: NetworkAddress = .init(networkId: 8, ip: 0, maskLen: 24, mac: "xyz".data(using: .utf8)!, networkDomain: "punchnet") + lazy var stunSocketAddress: SocketAddress = { let stunServer = stunServers[0] return try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[0]) @@ -69,4 +79,30 @@ public class SDLConfiguration { self.hostname = hostname } + // 获取mac地址 + public static func getMacAddress() -> Data { + let key = "gMacAddress2" + + let userDefaults = UserDefaults.standard + if let mac = userDefaults.value(forKey: key) as? Data { + return mac + } + else { + let mac = generateMacAddress() + userDefaults.setValue(mac, forKey: key) + + return mac + } + } + + // 随机生成mac地址 + private static func generateMacAddress() -> Data { + var macAddress = [UInt8](repeating: 0, count: 6) + for i in 0..<6 { + macAddress[i] = UInt8.random(in: 0...255) + } + + return Data(macAddress) + } + } diff --git a/Tun/Punchnet/SDLContext.swift b/Tun/Punchnet/SDLContext.swift index 867ac7a..1e75135 100644 --- a/Tun/Punchnet/SDLContext.swift +++ b/Tun/Punchnet/SDLContext.swift @@ -30,9 +30,6 @@ public class SDLContext { let config: SDLConfiguration - // tun网络地址信息 - var devAddr: SDLDevAddr - // nat映射的相关信息, 暂时没有用处 //var natAddress: SDLNatAddress? // nat的网络类型 @@ -83,11 +80,6 @@ public class SDLContext { self.rsaCipher = rsaCipher self.aesCipher = aesCipher - // 生成mac地址 - var devAddr = SDLDevAddr() - devAddr.mac = Self.getMacAddress() - self.devAddr = devAddr - self.sessionManager = SessionManager() self.arpServer = ArpServer(known_macs: [:]) self.providerActor = SDLTunnelProviderActor(provider: provider, logger: logger) @@ -118,19 +110,7 @@ public class SDLContext { } } } - - group.addTask { - while !Task.isCancelled { - do { - try await self.startSuperClient() - } catch let err { - self.logger.log("[SDLContext] SuperClient get error: \(err), will restart", level: .warning) - await self.arpServer.clear() - try await Task.sleep(for: .seconds(2)) - } - } - } - + group.addTask { await self.startMonitor() } @@ -180,28 +160,27 @@ public class SDLContext { try await Task.sleep(nanoseconds: 5 * 1_000_000_000) try Task.checkCancellation() - if let udpHoleActor = self.udpHoleActor { - let cookie = await udpHoleActor.getCookieId() - var stunRequest = SDLStunRequest() - stunRequest.cookie = cookie - stunRequest.clientID = self.config.clientId - stunRequest.networkID = self.devAddr.networkID - stunRequest.ip = self.devAddr.netAddr - stunRequest.mac = self.devAddr.mac - stunRequest.natType = UInt32(self.natType.rawValue) - - let remoteAddress = self.config.stunSocketAddress - await udpHoleActor.send(type: .stunRequest, data: try stunRequest.serializedData(), remoteAddress: remoteAddress) - self.lastCookie = cookie - } + // TODO +// if let udpHoleActor = self.udpHoleActor { +// let cookie = await udpHoleActor.getCookieId() +// var stunRequest = SDLStunRequest() +// stunRequest.clientID = self.config.clientId +// stunRequest.networkID = self.devAddr.networkID +// stunRequest.ip = self.devAddr.netAddr +// stunRequest.mac = self.devAddr.mac +// stunRequest.natType = UInt32(self.natType.rawValue) +// +// let remoteAddress = self.config.stunSocketAddress +// await udpHoleActor.send(type: .stunRequest, data: try stunRequest.serializedData(), remoteAddress: remoteAddress) +// self.lastCookie = cookie +// } } } group.addTask { - if let eventFlow = self.udpHoleActor?.eventFlow { - for try await event in eventFlow { + if let messageStream = self.udpHoleActor?.messageStream { + for try await (remoteAddress, message) in messageStream { try Task.checkCancellation() - try await self.handleUDPEvent(event: event) } } } @@ -257,225 +236,183 @@ public class SDLContext { } } - private func handleSuperEvent(event: SDLSuperClientActor.SuperEvent) async throws { - switch event { - case .ready: - await self.puncherActor.setSuperClientActor(superClientActor: self.superClientActor) +// private func handleMessage(remoteAddress: SocketAddress, message: SDLHoleInboundMessage) async throws { +// switch message { +//// case .ready: +//// await self.puncherActor.setSuperClientActor(superClientActor: self.superClientActor) +//// +//// self.logger.log("[SDLContext] get registerSuper, mac address: \(SDLUtil.formatMacAddress(mac: self.devAddr.mac))", level: .debug) +//// var registerSuper = SDLRegisterSuper() +//// registerSuper.version = UInt32(self.config.version) +//// registerSuper.clientID = self.config.clientId +//// registerSuper.devAddr = self.devAddr +//// registerSuper.pubKey = self.rsaCipher.pubKey +//// registerSuper.token = self.config.token +//// registerSuper.networkCode = self.config.networkCode +//// registerSuper.hostname = self.config.hostname +//// guard let message = try await self.superClientActor?.request(type: .registerSuper, data: try registerSuper.serializedData()) else { +//// return +//// } + /// + private func handleRegisterSuperAck(registerSuperAck: SDLRegisterSuperAck) async { + // 需要对数据通过rsa的私钥解码 + let aesKey = try! self.rsaCipher.decode(data: Data(registerSuperAck.aesKey)) + + self.logger.log("[SDLContext] get registerSuperAck, aes_key len: \(aesKey.count)", level: .info) + // 服务器分配的tun网卡信息 + do { + let ipAddress = try await self.providerActor.setNetworkSettings(networkAddress: self.config.networkAddress, dnsServer: SDLDNSClientActor.Helper.dnsServer) + await self.noticeClient?.send(data: NoticeMessage.ipAdress(ip: ipAddress)) - self.logger.log("[SDLContext] get registerSuper, mac address: \(SDLUtil.formatMacAddress(mac: self.devAddr.mac))", level: .debug) - var registerSuper = SDLRegisterSuper() - registerSuper.version = UInt32(self.config.version) - registerSuper.clientID = self.config.clientId - registerSuper.devAddr = self.devAddr - registerSuper.pubKey = self.rsaCipher.pubKey - registerSuper.token = self.config.token - registerSuper.networkCode = self.config.networkCode - registerSuper.hostname = self.config.hostname - guard let message = try await self.superClientActor?.request(type: .registerSuper, data: try registerSuper.serializedData()) else { - return - } - - switch message.packet { - case .registerSuperAck(let registerSuperAck): - // 需要对数据通过rsa的私钥解码 - let aesKey = try! self.rsaCipher.decode(data: Data(registerSuperAck.aesKey)) - let upgradeType = SDLUpgradeType(rawValue: registerSuperAck.upgradeType) - - self.logger.log("[SDLContext] get registerSuperAck, aes_key len: \(aesKey.count), network_id:\(registerSuperAck.devAddr.networkID)", level: .info) - self.devAddr = registerSuperAck.devAddr - - if upgradeType == .force { - let forceUpgrade = NoticeMessage.upgrade(prompt: registerSuperAck.upgradePrompt, address: registerSuperAck.upgradeAddress) - await self.noticeClient?.send(data: forceUpgrade) - exit(-1) - } - - // 服务器分配的tun网卡信息 - do { - let ipAddress = try await self.providerActor.setNetworkSettings(devAddr: self.devAddr, dnsServer: SDLDNSClientActor.Helper.dnsServer) - await self.noticeClient?.send(data: NoticeMessage.ipAdress(ip: ipAddress)) - - self.startReader() - } catch let err { - self.logger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)", level: .error) - exit(-1) - } - - self.aesKey = aesKey - if upgradeType == .normal { - let normalUpgrade = NoticeMessage.upgrade(prompt: registerSuperAck.upgradePrompt, address: registerSuperAck.upgradeAddress) - await self.noticeClient?.send(data: normalUpgrade) - } - - case .registerSuperNak(let nakPacket): - let errorMessage = nakPacket.errorMessage - guard let errorCode = SDLNAKErrorCode(rawValue: UInt8(nakPacket.errorCode)) else { - return - } - - switch errorCode { - case .invalidToken, .nodeDisabled: - let alertNotice = NoticeMessage.alert(alert: errorMessage) - await self.noticeClient?.send(data: alertNotice) - exit(-1) - case .noIpAddress, .networkFault, .internalFault: - let alertNotice = NoticeMessage.alert(alert: errorMessage) - await self.noticeClient?.send(data: alertNotice) - } - self.logger.log("[SDLContext] Get a SuperNak message exit", level: .warning) - default: - () - } - - case .event(let evt): - switch evt { - case .natChanged(let natChangedEvent): - let dstMac = natChangedEvent.mac - self.logger.log("[SDLContext] natChangedEvent, dstMac: \(dstMac)", level: .info) - await sessionManager.removeSession(dstMac: dstMac) - case .sendRegister(let sendRegisterEvent): - self.logger.log("[SDLContext] sendRegisterEvent, ip: \(sendRegisterEvent)", level: .debug) - let address = SDLUtil.int32ToIp(sendRegisterEvent.natIp) - if let remoteAddress = try? SocketAddress.makeAddressResolvingHost(address, port: Int(sendRegisterEvent.natPort)) { - // 发送register包 - var register = SDLRegister() - register.networkID = self.devAddr.networkID - register.srcMac = self.devAddr.mac - register.dstMac = sendRegisterEvent.dstMac - await self.udpHoleActor?.send(type: .register, data: try register.serializedData(), remoteAddress: remoteAddress) - } - - case .networkShutdown(let shutdownEvent): - let alertNotice = NoticeMessage.alert(alert: shutdownEvent.message) - await self.noticeClient?.send(data: alertNotice) - exit(-1) - } - case .command(let packetId, let command): - switch command { - case .changeNetwork(let changeNetworkCommand): - // 需要对数据通过rsa的私钥解码 - let aesKey = try! self.rsaCipher.decode(data: Data(changeNetworkCommand.aesKey)) - self.logger.log("[SDLContext] change network command get aes_key len: \(aesKey.count)", level: .info) - self.devAddr = changeNetworkCommand.devAddr - - // 服务器分配的tun网卡信息 - do { - let ipAddress = try await self.providerActor.setNetworkSettings(devAddr: self.devAddr, dnsServer: SDLDNSClientActor.Helper.dnsServer) - await self.noticeClient?.send(data: NoticeMessage.ipAdress(ip: ipAddress)) - - self.startReader() - } catch let err { - self.logger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)", level: .error) - exit(-1) - } - - self.aesKey = aesKey - - var commandAck = SDLCommandAck() - commandAck.status = true - await self.superClientActor?.send(type: .commandAck, packetId: packetId, data: try commandAck.serializedData()) - } + self.startReader() + } catch let err { + self.logger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)", level: .error) + exit(-1) } + self.aesKey = aesKey } - private func handleUDPEvent(event: SDLUDPHoleActor.UDPEvent) async throws { - switch event { - case .ready: - await self.puncherActor.setUDPHoleActor(udpHoleActor: self.udpHoleActor) - // 获取当前网络的类型 - self.natType = await getNatType() - self.logger.log("[SDLContext] broadcast is: \(self.natType)", level: .debug) - - case .message(let remoteAddress, let message): - switch message { - case .register(let register): - self.logger.log("register packet: \(register), dev_addr: \(self.devAddr)", level: .debug) - // 判断目标地址是否是tun的网卡地址, 并且是在同一个网络下 - if register.dstMac == self.devAddr.mac && register.networkID == self.devAddr.networkID { - // 回复ack包 - var registerAck = SDLRegisterAck() - registerAck.networkID = self.devAddr.networkID - registerAck.srcMac = self.devAddr.mac - registerAck.dstMac = register.srcMac - - await self.udpHoleActor?.send(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress) - // 这里需要建立到来源的会话, 在复杂网络下,通过super-node查询到的nat地址不一定靠谱,需要通过udp包的来源地址作为nat地址 - let session = Session(dstMac: register.srcMac, natAddress: remoteAddress) - await self.sessionManager.addSession(session: session) - } else { - self.logger.log("SDLContext didReadRegister get a invalid packet, because dst_ip not matched: \(register.dstMac)", level: .warning) - } - case .registerAck(let registerAck): - // 判断目标地址是否是tun的网卡地址, 并且是在同一个网络下 - if registerAck.dstMac == self.devAddr.mac && registerAck.networkID == self.devAddr.networkID { - let session = Session(dstMac: registerAck.srcMac, natAddress: remoteAddress) - await self.sessionManager.addSession(session: session) - } else { - self.logger.log("SDLContext didReadRegisterAck get a invalid packet, because dst_mac not matched: \(registerAck.dstMac)", level: .warning) - } - case .stunReply(let stunReply): - let cookie = stunReply.cookie - if cookie == self.lastCookie { - // 记录下当前在nat上的映射信息,暂时没有用;后续会用来判断网络类型 - //self.natAddress = stunReply.natAddress - self.logger.log("[SDLContext] get a stunReply: \(try! stunReply.jsonString())", level: .debug) - } - default: - () - } - - case .data(let data): - let mac = LayerPacket.MacAddress(data: data.dstMac) - guard (data.dstMac == self.devAddr.mac || mac.isBroadcast() || mac.isMulticast()) else { - return - } - - guard let decyptedData = try? self.aesCipher.decypt(aesKey: self.aesKey, data: Data(data.data)) else { - return - } - - do { - let layerPacket = try LayerPacket(layerData: decyptedData) - - await 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 == self.devAddr.netAddr { - switch arpPacket.opcode { - case .request: - self.logger.log("[SDLContext] get arp request packet", level: .debug) - let response = ARPPacket.arpResponse(for: arpPacket, mac: self.devAddr.mac, ip: self.devAddr.netAddr) - await self.routeLayerPacket(dstMac: arpPacket.senderMAC, type: .arp, data: response.marshal()) - case .response: - self.logger.log("[SDLContext] get arp response packet", level: .debug) - await self.arpServer.append(ip: arpPacket.senderIP, mac: arpPacket.senderMAC) - } - } else { - self.logger.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(self.devAddr.netAddr))", level: .debug) - } - } else { - self.logger.log("[SDLContext] get invalid arp packet", level: .debug) - } - case .ipv4: - guard let ipPacket = IPPacket(layerPacket.data), ipPacket.header.destination == self.devAddr.netAddr else { - return - } - let packet = NEPacket(data: ipPacket.data, protocolFamily: 2) - await self.providerActor.writePackets(packets: [packet]) - default: - self.logger.log("[SDLContext] get invalid packet", level: .debug) - } - } catch let err { - self.logger.log("[SDLContext] didReadData err: \(err)", level: .warning) - } + private func handleRegisterSuperNak(nakPacket: SDLRegisterSuperNak) async { + let errorMessage = nakPacket.errorMessage + guard let errorCode = SDLNAKErrorCode(rawValue: UInt8(nakPacket.errorCode)) else { + return } + switch errorCode { + case .invalidToken, .nodeDisabled: + let alertNotice = NoticeMessage.alert(alert: errorMessage) + await self.noticeClient?.send(data: alertNotice) + exit(-1) + case .noIpAddress, .networkFault, .internalFault: + let alertNotice = NoticeMessage.alert(alert: errorMessage) + await self.noticeClient?.send(data: alertNotice) + } + self.logger.log("[SDLContext] Get a SuperNak message exit", level: .warning) + } + private func handleEvent(event: SDLEvent) async throws { + switch event { + case .natChanged(let natChangedEvent): + let dstMac = natChangedEvent.mac + self.logger.log("[SDLContext] natChangedEvent, dstMac: \(dstMac)", level: .info) + await sessionManager.removeSession(dstMac: dstMac) + case .sendRegister(let sendRegisterEvent): + self.logger.log("[SDLContext] sendRegisterEvent, ip: \(sendRegisterEvent)", level: .debug) + let address = SDLUtil.int32ToIp(sendRegisterEvent.natIp) + if let remoteAddress = try? SocketAddress.makeAddressResolvingHost(address, port: Int(sendRegisterEvent.natPort)) { + // 发送register包 + var register = SDLRegister() + register.networkID = self.config.networkAddress.networkId + register.srcMac = self.config.networkAddress.mac + register.dstMac = sendRegisterEvent.dstMac + await self.udpHoleActor?.send(type: .register, data: try register.serializedData(), remoteAddress: remoteAddress) + } + + case .networkShutdown(let shutdownEvent): + let alertNotice = NoticeMessage.alert(alert: shutdownEvent.message) + await self.noticeClient?.send(data: alertNotice) + exit(-1) + } + } + +//// case .ready: +//// await self.puncherActor.setUDPHoleActor(udpHoleActor: self.udpHoleActor) +//// // 获取当前网络的类型 +//// self.natType = await getNatType() +//// self.logger.log("[SDLContext] broadcast is: \(self.natType)", level: .debug) +// + + private func handleRegister(remoteAddress: SocketAddress, register: SDLRegister) async throws { + let networkAddr = config.networkAddress + self.logger.log("register packet: \(register), network_address: \(networkAddr)", level: .debug) + + // 判断目标地址是否是tun的网卡地址, 并且是在同一个网络下 + if register.dstMac == networkAddr.mac && register.networkID == networkAddr.networkId { + // 回复ack包 + var registerAck = SDLRegisterAck() + registerAck.networkID = networkAddr.networkId + registerAck.srcMac = networkAddr.mac + registerAck.dstMac = register.srcMac + + await self.udpHoleActor?.send(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress) + // 这里需要建立到来源的会话, 在复杂网络下,通过super-node查询到的nat地址不一定靠谱,需要通过udp包的来源地址作为nat地址 + let session = Session(dstMac: register.srcMac, natAddress: remoteAddress) + await self.sessionManager.addSession(session: session) + } else { + self.logger.log("SDLContext didReadRegister get a invalid packet, because dst_ip not matched: \(register.dstMac)", level: .warning) + } + } + + private func handleRegisterAck(remoteAddress: SocketAddress, registerAck: SDLRegister) async { + // 判断目标地址是否是tun的网卡地址, 并且是在同一个网络下 + let networkAddr = config.networkAddress + if registerAck.dstMac == networkAddr.mac && registerAck.networkID == networkAddr.networkId { + let session = Session(dstMac: registerAck.srcMac, natAddress: remoteAddress) + await self.sessionManager.addSession(session: session) + } else { + self.logger.log("SDLContext didReadRegisterAck get a invalid packet, because dst_mac not matched: \(registerAck.dstMac)", level: .warning) + } + } + + private func handleStunReply(stunReply: SDLStunReply) async { +// let cookie = stunReply.cookie +// if cookie == self.lastCookie { +// // 记录下当前在nat上的映射信息,暂时没有用;后续会用来判断网络类型 +// //self.natAddress = stunReply.natAddress +// self.logger.log("[SDLContext] get a stunReply: \(try! stunReply.jsonString())", level: .debug) +// } + } + + private func handleData(data: SDLData) async throws { + let mac = LayerPacket.MacAddress(data: data.dstMac) + + let networkAddr = config.networkAddress + guard (data.dstMac == networkAddr.mac || mac.isBroadcast() || mac.isMulticast()) else { + return + } + + guard let decyptedData = try? self.aesCipher.decypt(aesKey: self.aesKey, data: Data(data.data)) else { + return + } + + let layerPacket = try LayerPacket(layerData: decyptedData) + + await 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: + self.logger.log("[SDLContext] get arp request packet", level: .debug) + let response = ARPPacket.arpResponse(for: arpPacket, mac: networkAddr.mac, ip: networkAddr.ip) + await self.routeLayerPacket(dstMac: arpPacket.senderMAC, type: .arp, data: response.marshal()) + case .response: + self.logger.log("[SDLContext] get arp response packet", level: .debug) + await self.arpServer.append(ip: arpPacket.senderIP, mac: arpPacket.senderMAC) + } + } else { + self.logger.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(networkAddr.ip))", level: .debug) + } + } else { + self.logger.log("[SDLContext] get invalid arp packet", level: .debug) + } + case .ipv4: + guard let ipPacket = IPPacket(layerPacket.data), ipPacket.header.destination == networkAddr.ip else { + return + } + let packet = NEPacket(data: ipPacket.data, protocolFamily: 2) + await self.providerActor.writePackets(packets: [packet]) + default: + self.logger.log("[SDLContext] get invalid packet", level: .debug) + } + } + + // 流量统计 // public func flowReportTask() { // Task { @@ -512,6 +449,7 @@ public class SDLContext { return } + let networkAddr = self.config.networkAddress if SDLDNSClientActor.Helper.isDnsRequestPacket(ipPacket: packet) { let destIp = packet.header.destination_ip self.logger.log("[DNSQuery] destIp: \(destIp), int: \(packet.header.destination.asIpAddress())", level: .debug) @@ -521,7 +459,7 @@ public class SDLContext { Task.detached { let dstIp = packet.header.destination // 本地通讯, 目标地址是本地服务器的ip地址 - if dstIp == self.devAddr.netAddr { + if dstIp == networkAddr.ip { let nePacket = NEPacket(data: packet.data, protocolFamily: 2) await self.providerActor.writePackets(packets: [nePacket]) return @@ -534,7 +472,7 @@ public class SDLContext { else { self.logger.log("[SDLContext] dstIp: \(dstIp.asIpAddress()) arp query not found, broadcast", level: .debug) // 构造arp广播 - let arpReqeust = ARPPacket.arpRequest(senderIP: self.devAddr.netAddr, senderMAC: self.devAddr.mac, targetIP: dstIp) + let arpReqeust = ARPPacket.arpRequest(senderIP: networkAddr.ip, senderMAC: networkAddr.mac, targetIP: dstIp) await self.routeLayerPacket(dstMac: ARPPacket.broadcastMac , type: .arp, data: arpReqeust.marshal()) } } @@ -542,16 +480,17 @@ public class SDLContext { } private func routeLayerPacket(dstMac: Data, type: LayerPacket.PacketType, data: Data) async { + let networkAddr = self.config.networkAddress // 将数据封装层2层的数据包 - let layerPacket = LayerPacket(dstMac: dstMac, srcMac: self.devAddr.mac, type: type, data: data) + let layerPacket = LayerPacket(dstMac: dstMac, srcMac: networkAddr.mac, type: type, data: data) guard let encodedPacket = try? self.aesCipher.encrypt(aesKey: self.aesKey, data: layerPacket.marshal()) else { return } // 构造数据包 var dataPacket = SDLData() - dataPacket.networkID = self.devAddr.networkID - dataPacket.srcMac = self.devAddr.mac + dataPacket.networkID = networkAddr.networkId + dataPacket.srcMac = networkAddr.mac dataPacket.dstMac = dstMac dataPacket.ttl = 255 dataPacket.data = encodedPacket @@ -575,7 +514,7 @@ public class SDLContext { // 流量统计 await self.flowTracer.inc(num: data.count, type: .forward) // 尝试打洞 - await self.puncherActor.submitRegisterRequest(request: .init(srcMac: self.devAddr.mac, dstMac: dstMac, networkId: self.devAddr.networkID)) + await self.puncherActor.submitRegisterRequest(request: .init(srcMac: networkAddr.mac, dstMac: dstMac, networkId: networkAddr.networkId)) } } } @@ -583,36 +522,8 @@ public class SDLContext { deinit { self.rootTask?.cancel() self.udpHoleActor = nil - self.superClientActor = nil self.dnsClientActor = nil } - - // 获取mac地址 - public static func getMacAddress() -> Data { - let key = "gMacAddress2" - - let userDefaults = UserDefaults.standard - if let mac = userDefaults.value(forKey: key) as? Data { - return mac - } - else { - let mac = generateMacAddress() - userDefaults.setValue(mac, forKey: key) - - return mac - } - } - - // 随机生成mac地址 - private static func generateMacAddress() -> Data { - var macAddress = [UInt8](repeating: 0, count: 6) - for i in 0..<6 { - macAddress[i] = UInt8.random(in: 0...255) - } - - return Data(macAddress) - } - } // 网络类型探测