Merge pull request #4 from keeshux/split-socket-link
Split socket and link implementations
This commit is contained in:
commit
acc129bf3b
|
@ -116,11 +116,11 @@ private extension NEProvider {
|
||||||
switch endpointProtocol.socketType {
|
switch endpointProtocol.socketType {
|
||||||
case .udp:
|
case .udp:
|
||||||
let impl = createUDPSession(to: endpoint, from: nil)
|
let impl = createUDPSession(to: endpoint, from: nil)
|
||||||
return NEUDPInterface(impl: impl)
|
return NEUDPSocket(impl: impl)
|
||||||
|
|
||||||
case .tcp:
|
case .tcp:
|
||||||
let impl = createTCPConnection(to: endpoint, enableTLS: false, tlsParameters: nil, delegate: nil)
|
let impl = createTCPConnection(to: endpoint, enableTLS: false, tlsParameters: nil, delegate: nil)
|
||||||
return NETCPInterface(impl: impl)
|
return NETCPSocket(impl: impl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol LinkProducer {
|
protocol LinkProducer {
|
||||||
func link() -> LinkInterface
|
func link(withMTU mtu: Int) -> LinkInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol GenericSocketDelegate: class {
|
protocol GenericSocketDelegate: class {
|
||||||
|
|
|
@ -12,16 +12,13 @@ import SwiftyBeaver
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
||||||
class NETCPInterface: NSObject, GenericSocket, LinkInterface {
|
class NETCPSocket: NSObject, GenericSocket {
|
||||||
private static var linkContext = 0
|
private static var linkContext = 0
|
||||||
|
|
||||||
private let impl: NWTCPConnection
|
private let impl: NWTCPConnection
|
||||||
|
|
||||||
private let maxPacketSize: Int
|
init(impl: NWTCPConnection) {
|
||||||
|
|
||||||
init(impl: NWTCPConnection, maxPacketSize: Int? = nil) {
|
|
||||||
self.impl = impl
|
self.impl = impl
|
||||||
self.maxPacketSize = maxPacketSize ?? (512 * 1024)
|
|
||||||
isActive = false
|
isActive = false
|
||||||
isShutdown = false
|
isShutdown = false
|
||||||
}
|
}
|
||||||
|
@ -58,13 +55,13 @@ class NETCPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl.addObserver(self, forKeyPath: #keyPath(NWTCPConnection.state), options: [.initial, .new], context: &NETCPInterface.linkContext)
|
impl.addObserver(self, forKeyPath: #keyPath(NWTCPConnection.state), options: [.initial, .new], context: &NETCPSocket.linkContext)
|
||||||
impl.addObserver(self, forKeyPath: #keyPath(NWTCPConnection.hasBetterPath), options: .new, context: &NETCPInterface.linkContext)
|
impl.addObserver(self, forKeyPath: #keyPath(NWTCPConnection.hasBetterPath), options: .new, context: &NETCPSocket.linkContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unobserve() {
|
func unobserve() {
|
||||||
impl.removeObserver(self, forKeyPath: #keyPath(NWTCPConnection.state), context: &NETCPInterface.linkContext)
|
impl.removeObserver(self, forKeyPath: #keyPath(NWTCPConnection.state), context: &NETCPSocket.linkContext)
|
||||||
impl.removeObserver(self, forKeyPath: #keyPath(NWTCPConnection.hasBetterPath), context: &NETCPInterface.linkContext)
|
impl.removeObserver(self, forKeyPath: #keyPath(NWTCPConnection.hasBetterPath), context: &NETCPSocket.linkContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shutdown() {
|
func shutdown() {
|
||||||
|
@ -76,17 +73,17 @@ class NETCPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
guard impl.hasBetterPath else {
|
guard impl.hasBetterPath else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return NETCPInterface(impl: NWTCPConnection(upgradeFor: impl))
|
return NETCPSocket(impl: NWTCPConnection(upgradeFor: impl))
|
||||||
}
|
}
|
||||||
|
|
||||||
func link() -> LinkInterface {
|
func link(withMTU mtu: Int) -> LinkInterface {
|
||||||
return self
|
return NETCPLink(impl: impl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Connection KVO (any queue)
|
// MARK: Connection KVO (any queue)
|
||||||
|
|
||||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||||
guard (context == &NETCPInterface.linkContext) else {
|
guard (context == &NETCPSocket.linkContext) else {
|
||||||
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -148,12 +145,28 @@ class NETCPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NETCPLink: LinkInterface {
|
||||||
|
private let impl: NWTCPConnection
|
||||||
|
|
||||||
|
private let maxPacketSize: Int
|
||||||
|
|
||||||
|
init(impl: NWTCPConnection, maxPacketSize: Int? = nil) {
|
||||||
|
self.impl = impl
|
||||||
|
self.mtu = .max
|
||||||
|
self.maxPacketSize = maxPacketSize ?? (512 * 1024)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: LinkInterface
|
// MARK: LinkInterface
|
||||||
|
|
||||||
let isReliable: Bool = true
|
let isReliable: Bool = true
|
||||||
|
|
||||||
let mtu: Int = .max
|
var remoteAddress: String? {
|
||||||
|
return (impl.remoteAddress as? NWHostEndpoint)?.hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
let mtu: Int
|
||||||
|
|
||||||
var packetBufferSize: Int {
|
var packetBufferSize: Int {
|
||||||
return maxPacketSize
|
return maxPacketSize
|
||||||
|
@ -206,7 +219,7 @@ class NETCPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NETCPInterface {
|
extension NETCPSocket {
|
||||||
override var description: String {
|
override var description: String {
|
||||||
guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else {
|
guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else {
|
||||||
return impl.endpoint.description
|
return impl.endpoint.description
|
||||||
|
|
|
@ -12,16 +12,13 @@ import SwiftyBeaver
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
||||||
class NEUDPInterface: NSObject, GenericSocket, LinkInterface {
|
class NEUDPSocket: NSObject, GenericSocket {
|
||||||
private static var linkContext = 0
|
private static var linkContext = 0
|
||||||
|
|
||||||
private let impl: NWUDPSession
|
private let impl: NWUDPSession
|
||||||
|
|
||||||
private let maxDatagrams: Int
|
init(impl: NWUDPSession) {
|
||||||
|
|
||||||
init(impl: NWUDPSession, maxDatagrams: Int? = nil) {
|
|
||||||
self.impl = impl
|
self.impl = impl
|
||||||
self.maxDatagrams = maxDatagrams ?? 200
|
|
||||||
|
|
||||||
isActive = false
|
isActive = false
|
||||||
isShutdown = false
|
isShutdown = false
|
||||||
|
@ -58,13 +55,13 @@ class NEUDPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl.addObserver(self, forKeyPath: #keyPath(NWUDPSession.state), options: [.initial, .new], context: &NEUDPInterface.linkContext)
|
impl.addObserver(self, forKeyPath: #keyPath(NWUDPSession.state), options: [.initial, .new], context: &NEUDPSocket.linkContext)
|
||||||
impl.addObserver(self, forKeyPath: #keyPath(NWUDPSession.hasBetterPath), options: .new, context: &NEUDPInterface.linkContext)
|
impl.addObserver(self, forKeyPath: #keyPath(NWUDPSession.hasBetterPath), options: .new, context: &NEUDPSocket.linkContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unobserve() {
|
func unobserve() {
|
||||||
impl.removeObserver(self, forKeyPath: #keyPath(NWUDPSession.state), context: &NEUDPInterface.linkContext)
|
impl.removeObserver(self, forKeyPath: #keyPath(NWUDPSession.state), context: &NEUDPSocket.linkContext)
|
||||||
impl.removeObserver(self, forKeyPath: #keyPath(NWUDPSession.hasBetterPath), context: &NEUDPInterface.linkContext)
|
impl.removeObserver(self, forKeyPath: #keyPath(NWUDPSession.hasBetterPath), context: &NEUDPSocket.linkContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shutdown() {
|
func shutdown() {
|
||||||
|
@ -75,17 +72,17 @@ class NEUDPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
guard impl.hasBetterPath else {
|
guard impl.hasBetterPath else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return NEUDPInterface(impl: NWUDPSession(upgradeFor: impl))
|
return NEUDPSocket(impl: NWUDPSession(upgradeFor: impl))
|
||||||
}
|
}
|
||||||
|
|
||||||
func link() -> LinkInterface {
|
func link(withMTU mtu: Int) -> LinkInterface {
|
||||||
return self
|
return NEUDPLink(impl: impl, mtu: mtu)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Connection KVO (any queue)
|
// MARK: Connection KVO (any queue)
|
||||||
|
|
||||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||||
guard (context == &NEUDPInterface.linkContext) else {
|
guard (context == &NEUDPSocket.linkContext) else {
|
||||||
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -150,12 +147,28 @@ class NEUDPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NEUDPLink: LinkInterface {
|
||||||
|
private let impl: NWUDPSession
|
||||||
|
|
||||||
|
private let maxDatagrams: Int
|
||||||
|
|
||||||
|
init(impl: NWUDPSession, mtu: Int, maxDatagrams: Int? = nil) {
|
||||||
|
self.impl = impl
|
||||||
|
self.mtu = mtu
|
||||||
|
self.maxDatagrams = maxDatagrams ?? 200
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: LinkInterface
|
// MARK: LinkInterface
|
||||||
|
|
||||||
let isReliable: Bool = false
|
let isReliable: Bool = false
|
||||||
|
|
||||||
let mtu: Int = 1000
|
var remoteAddress: String? {
|
||||||
|
return (impl.resolvedEndpoint as? NWHostEndpoint)?.hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
let mtu: Int
|
||||||
|
|
||||||
var packetBufferSize: Int {
|
var packetBufferSize: Int {
|
||||||
return maxDatagrams
|
return maxDatagrams
|
||||||
|
@ -191,7 +204,7 @@ class NEUDPInterface: NSObject, GenericSocket, LinkInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NEUDPInterface {
|
extension NEUDPSocket {
|
||||||
override var description: String {
|
override var description: String {
|
||||||
guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else {
|
guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else {
|
||||||
return impl.endpoint.description
|
return impl.endpoint.description
|
||||||
|
|
|
@ -125,8 +125,8 @@ extension TunnelKitProvider {
|
||||||
/// The optional CA certificate to validate server against. Set to `nil` to disable CA validation (default).
|
/// The optional CA certificate to validate server against. Set to `nil` to disable CA validation (default).
|
||||||
public var ca: Certificate?
|
public var ca: Certificate?
|
||||||
|
|
||||||
/// The MTU of the tunnel.
|
/// The MTU of the link.
|
||||||
public var mtu: NSNumber
|
public var mtu: Int
|
||||||
|
|
||||||
/// Enables LZO framing (deprecated).
|
/// Enables LZO framing (deprecated).
|
||||||
// @available(*, deprecated)
|
// @available(*, deprecated)
|
||||||
|
@ -214,7 +214,7 @@ extension TunnelKitProvider {
|
||||||
self.cipher = cipher
|
self.cipher = cipher
|
||||||
self.digest = digest
|
self.digest = digest
|
||||||
self.ca = ca
|
self.ca = ca
|
||||||
mtu = providerConfiguration[S.mtu] as? NSNumber ?? 1500
|
mtu = providerConfiguration[S.mtu] as? Int ?? 1250
|
||||||
LZOFraming = providerConfiguration[S.LZOFraming] as? Bool ?? false
|
LZOFraming = providerConfiguration[S.LZOFraming] as? Bool ?? false
|
||||||
renegotiatesAfterSeconds = providerConfiguration[S.renegotiatesAfter] as? Int
|
renegotiatesAfterSeconds = providerConfiguration[S.renegotiatesAfter] as? Int
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ extension TunnelKitProvider {
|
||||||
public let ca: Certificate?
|
public let ca: Certificate?
|
||||||
|
|
||||||
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.mtu`
|
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.mtu`
|
||||||
public let mtu: NSNumber
|
public let mtu: Int
|
||||||
|
|
||||||
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.LZOFraming`
|
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.LZOFraming`
|
||||||
public let LZOFraming: Bool
|
public let LZOFraming: Bool
|
||||||
|
|
|
@ -335,10 +335,10 @@ extension TunnelKitProvider: GenericSocketDelegate {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if proxy.canRebindLink() {
|
if proxy.canRebindLink() {
|
||||||
proxy.rebindLink(socket.link())
|
proxy.rebindLink(socket.link(withMTU: cfg.mtu))
|
||||||
reasserting = false
|
reasserting = false
|
||||||
} else {
|
} else {
|
||||||
proxy.setLink(socket.link())
|
proxy.setLink(socket.link(withMTU: cfg.mtu))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +446,6 @@ extension TunnelKitProvider: SessionProxyDelegate {
|
||||||
let newSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: tunnel)
|
let newSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: tunnel)
|
||||||
newSettings.ipv4Settings = ipv4Settings
|
newSettings.ipv4Settings = ipv4Settings
|
||||||
newSettings.dnsSettings = dnsSettings
|
newSettings.dnsSettings = dnsSettings
|
||||||
newSettings.mtu = cfg.mtu
|
|
||||||
|
|
||||||
setTunnelNetworkSettings(newSettings, completionHandler: completionHandler)
|
setTunnelNetworkSettings(newSettings, completionHandler: completionHandler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class AppExtensionTests: XCTestCase {
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.cipherAlgorithm] as? String, cfg.cipher.rawValue)
|
XCTAssertEqual(proto?.providerConfiguration?[K.cipherAlgorithm] as? String, cfg.cipher.rawValue)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.digestAlgorithm] as? String, cfg.digest.rawValue)
|
XCTAssertEqual(proto?.providerConfiguration?[K.digestAlgorithm] as? String, cfg.digest.rawValue)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.ca] as? String, cfg.ca?.pem)
|
XCTAssertEqual(proto?.providerConfiguration?[K.ca] as? String, cfg.ca?.pem)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.mtu] as? NSNumber, cfg.mtu)
|
XCTAssertEqual(proto?.providerConfiguration?[K.mtu] as? Int, cfg.mtu)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.renegotiatesAfter] as? Int, cfg.renegotiatesAfterSeconds)
|
XCTAssertEqual(proto?.providerConfiguration?[K.renegotiatesAfter] as? Int, cfg.renegotiatesAfterSeconds)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.debug] as? Bool, cfg.shouldDebug)
|
XCTAssertEqual(proto?.providerConfiguration?[K.debug] as? Bool, cfg.shouldDebug)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.debugLogKey] as? String, cfg.debugLogKey)
|
XCTAssertEqual(proto?.providerConfiguration?[K.debugLogKey] as? String, cfg.debugLogKey)
|
||||||
|
|
Loading…
Reference in New Issue