mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-03-29 06:59:46 +08:00
127 lines
4.8 KiB
Swift
127 lines
4.8 KiB
Swift
//
|
||
// ConnectionManager.swift
|
||
// ProxyPin
|
||
//
|
||
// Created by wanghongen on 2024/9/16.
|
||
//
|
||
|
||
import Foundation
|
||
import Network
|
||
import os.log
|
||
|
||
//管理VPN客户端的连接
|
||
class ConnectionManager : CloseableConnection{
|
||
//static let instance = ConnectionManager()
|
||
|
||
private var table: [String: Connection] = [:]
|
||
|
||
public var proxyAddress: NWEndpoint?
|
||
|
||
private let defaultPorts: [UInt16] = [80, 443, 8080, 8088, 8888, 9000]
|
||
|
||
|
||
func getConnection(nwProtocol: NWProtocol, ip: UInt32, port: UInt16, srcIp: UInt32, srcPort: UInt16) -> Connection? {
|
||
let key = Connection.getConnectionKey(nwProtocol: nwProtocol, destIp: ip, destPort: port, sourceIp: srcIp, sourcePort: srcPort)
|
||
return getConnectionByKey(key: key)
|
||
}
|
||
|
||
func getConnectionByKey(key: String) -> Connection? {
|
||
return table[key]
|
||
}
|
||
|
||
func createTCPConnection(ip: UInt32, port: UInt16, srcIp: UInt32, srcPort: UInt16) -> Connection {
|
||
let key = Connection.getConnectionKey(nwProtocol: .TCP, destIp: ip, destPort: port, sourceIp: srcIp, sourcePort: srcPort)
|
||
|
||
if let existingConnection = table[key] {
|
||
return existingConnection
|
||
}
|
||
|
||
let connection = Connection(nwProtocol: .TCP, sourceIp: srcIp, sourcePort: srcPort, destinationIp: ip, destinationPort: port, connectionCloser: self)
|
||
|
||
let ipString = PacketUtil.intToIPAddress(ip)
|
||
|
||
let endpoint: NWEndpoint
|
||
if (proxyAddress == nil || !defaultPorts.contains(port) || isPrivateIP(ipString)) {
|
||
endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(ipString), port: NWEndpoint.Port(rawValue: port)!)
|
||
// 使用 TCP 协议
|
||
let parameters = NWParameters.tcp
|
||
let nwConnection = NWConnection(to: endpoint, using: parameters)
|
||
connection.channel = nwConnection
|
||
connection.isInitConnect = true
|
||
}
|
||
|
||
self.table[key] = connection
|
||
os_log("Created TCP connection %{public}@", log: OSLog.default, type: .default, key)
|
||
|
||
return connection
|
||
}
|
||
|
||
private func isPrivateIP(_ ip: String) -> Bool {
|
||
return ip.hasPrefix("10.") ||
|
||
ip.hasPrefix("172.") && (16...31).contains(Int(ip.split(separator: ".")[1]) ?? -1) ||
|
||
ip.hasPrefix("192.168.")
|
||
}
|
||
|
||
func createUDPConnection(ip: UInt32, port: UInt16, srcIp: UInt32, srcPort: UInt16) -> Connection {
|
||
let key = Connection.getConnectionKey(nwProtocol: .UDP, destIp: ip, destPort: port, sourceIp: srcIp, sourcePort: srcPort)
|
||
|
||
if let existingConnection = table[key] {
|
||
return existingConnection
|
||
}
|
||
|
||
let connection = Connection(nwProtocol: .UDP, sourceIp: srcIp, sourcePort: srcPort, destinationIp: ip, destinationPort: port, connectionCloser: self)
|
||
|
||
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host((PacketUtil.intToIPAddress(ip))), port: NWEndpoint.Port(rawValue: port)!)
|
||
|
||
let nwConnection = NWConnection(to: endpoint, using: .udp)
|
||
connection.channel = nwConnection
|
||
|
||
os_log("Created UDP connection %{public}@", log: OSLog.default, type: .default, key)
|
||
self.table[key] = connection
|
||
|
||
return connection
|
||
}
|
||
|
||
func closeConnection(connection: Connection) {
|
||
closeConnection(
|
||
nwProtocol: connection.nwProtocol, ip: connection.destinationIp, port: connection.destinationPort,
|
||
srcIp: connection.sourceIp, srcPort: connection.sourcePort
|
||
)
|
||
}
|
||
|
||
// 从内存中删除连接,然后关闭套接字。
|
||
func closeConnection(nwProtocol: NWProtocol, ip: UInt32, port: UInt16, srcIp: UInt32, srcPort: UInt16) {
|
||
let key = Connection.getConnectionKey(nwProtocol: nwProtocol, destIp: ip, destPort: port, sourceIp: srcIp, sourcePort: srcPort)
|
||
|
||
if let connection = self.table.removeValue(forKey: key) {
|
||
if connection.channel?.state != .cancelled {
|
||
connection.channel?.cancel()
|
||
os_log("Closed connection %{public}@", log: OSLog.default, type: .debug, key)
|
||
} else {
|
||
os_log("Connection %{public}@ is already cancelled", log: OSLog.default, type: .debug, key)
|
||
}
|
||
}
|
||
}
|
||
|
||
//添加来自客户端的数据,该数据稍后将在接收到PSH标志时发送到目的服务器。
|
||
func addClientData(data: Data, connection: Connection) {
|
||
guard data.count > 0 else {
|
||
return
|
||
}
|
||
|
||
connection.addSendData(data: data)
|
||
}
|
||
|
||
func keepSessionAlive(connection: Connection) {
|
||
let key = Connection.getConnectionKey(
|
||
nwProtocol: connection.nwProtocol,
|
||
destIp: connection.destinationIp,
|
||
destPort: connection.destinationPort,
|
||
sourceIp: connection.sourceIp,
|
||
sourcePort: connection.sourcePort
|
||
)
|
||
|
||
self.table[key] = connection
|
||
}
|
||
}
|