From e3ce38e47ee9a33f2112fbe15c727df7cd88107e Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sun, 27 Dec 2020 22:51:19 +0100 Subject: [PATCH 1/4] Remove MTU from AppExtension layer --- .../OpenVPNTunnelProvider+Configuration.swift | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift index 6daa5cc..37c5812 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift @@ -52,7 +52,6 @@ extension OpenVPNTunnelProvider { sessionConfiguration: OpenVPN.ConfigurationBuilder().build(), prefersResolvedAddresses: false, resolvedAddresses: nil, - mtu: 1250, shouldDebug: false, debugLogFormat: nil, masksPrivateData: true, @@ -69,9 +68,6 @@ extension OpenVPNTunnelProvider { /// Resolved addresses in case DNS fails or `prefersResolvedAddresses` is `true` (IPv4 only). public var resolvedAddresses: [String]? - - /// The MTU of the link. - public var mtu: Int /// Optional version identifier about the client pushed to server in peer-info as `IV_UI_VER`. public var versionIdentifier: String? @@ -98,7 +94,6 @@ extension OpenVPNTunnelProvider { self.sessionConfiguration = sessionConfiguration prefersResolvedAddresses = ConfigurationBuilder.defaults.prefersResolvedAddresses resolvedAddresses = nil - mtu = ConfigurationBuilder.defaults.mtu shouldDebug = ConfigurationBuilder.defaults.shouldDebug debugLogFormat = ConfigurationBuilder.defaults.debugLogFormat masksPrivateData = ConfigurationBuilder.defaults.masksPrivateData @@ -111,7 +106,6 @@ extension OpenVPNTunnelProvider { sessionConfiguration = try OpenVPN.Configuration.with(providerConfiguration: providerConfiguration) prefersResolvedAddresses = providerConfiguration[S.prefersResolvedAddresses] as? Bool ?? ConfigurationBuilder.defaults.prefersResolvedAddresses resolvedAddresses = providerConfiguration[S.resolvedAddresses] as? [String] - mtu = providerConfiguration[S.mtu] as? Int ?? ConfigurationBuilder.defaults.mtu shouldDebug = providerConfiguration[S.debug] as? Bool ?? ConfigurationBuilder.defaults.shouldDebug if shouldDebug { debugLogFormat = providerConfiguration[S.debugLogFormat] as? String @@ -134,7 +128,6 @@ extension OpenVPNTunnelProvider { sessionConfiguration: sessionConfiguration, prefersResolvedAddresses: prefersResolvedAddresses, resolvedAddresses: resolvedAddresses, - mtu: mtu, shouldDebug: shouldDebug, debugLogFormat: shouldDebug ? debugLogFormat : nil, masksPrivateData: masksPrivateData, @@ -208,8 +201,6 @@ extension OpenVPNTunnelProvider { static let resolvedAddresses = "ResolvedAddresses" - static let mtu = "MTU" - // MARK: Debugging static let debug = "Debug" @@ -228,9 +219,6 @@ extension OpenVPNTunnelProvider { /// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.resolvedAddresses` public let resolvedAddresses: [String]? - /// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.mtu` - public let mtu: Int - /// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.shouldDebug` public let shouldDebug: Bool @@ -367,7 +355,6 @@ extension OpenVPNTunnelProvider { S.prefersResolvedAddresses: prefersResolvedAddresses, S.ca: ca.pem, S.endpointProtocols: endpointProtocols.map { $0.rawValue }, - S.mtu: mtu, S.debug: shouldDebug ] sessionConfiguration.store(to: &dict) @@ -440,7 +427,6 @@ extension OpenVPNTunnelProvider.Configuration { var builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionConfiguration) builder.prefersResolvedAddresses = prefersResolvedAddresses builder.resolvedAddresses = resolvedAddresses - builder.mtu = mtu builder.shouldDebug = shouldDebug builder.debugLogFormat = debugLogFormat builder.masksPrivateData = masksPrivateData From 6cb04da05d088e612c799821c10d3cc00cc15fec Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sun, 27 Dec 2020 22:56:09 +0100 Subject: [PATCH 2/4] Add MTU to OpenVPN layer --- .../OpenVPNTunnelProvider+Configuration.swift | 10 +++++++++- .../AppExtension/OpenVPNTunnelProvider.swift | 6 +++--- .../Sources/Protocols/OpenVPN/Configuration.swift | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift index 37c5812..6ab514d 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift @@ -181,6 +181,8 @@ extension OpenVPNTunnelProvider { static let usesPIAPatches = "UsesPIAPatches" + static let mtu = "MTU" + static let dnsServers = "DNSServers" static let searchDomains = "SearchDomains" @@ -407,7 +409,6 @@ extension OpenVPNTunnelProvider { log.info("App version: \(appVersion)") } sessionConfiguration.print() - log.info("\tMTU: \(mtu)") log.info("\tDebug: \(shouldDebug)") log.info("\tMasks private data: \(masksPrivateData ?? true)") } @@ -528,6 +529,9 @@ private extension OpenVPN.Configuration { if let usesPIAPatches = providerConfiguration[S.usesPIAPatches] as? Bool { builder.usesPIAPatches = usesPIAPatches } + if let mtu = providerConfiguration[S.mtu] as? Int { + builder.mtu = mtu + } if let dnsServers = providerConfiguration[S.dnsServers] as? [String] { builder.dnsServers = dnsServers } @@ -614,6 +618,9 @@ private extension OpenVPN.Configuration { if let usesPIAPatches = usesPIAPatches { dict[S.usesPIAPatches] = usesPIAPatches } + if let mtu = mtu { + dict[S.mtu] = mtu + } if let dnsServers = dnsServers { dict[S.dnsServers] = dnsServers } @@ -718,5 +725,6 @@ private extension OpenVPN.Configuration { if let proxyBypassDomains = proxyBypassDomains { log.info("\tProxy bypass domains: \(proxyBypassDomains.maskedDescription)") } + log.info("\tMTU: \(fallbackMTU)") } } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift index 2cad1a4..7449035 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift @@ -451,10 +451,10 @@ extension OpenVPNTunnelProvider: GenericSocketDelegate { return } if session.canRebindLink() { - session.rebindLink(producer.link(withMTU: cfg.mtu)) + session.rebindLink(producer.link(withMTU: cfg.sessionConfiguration.fallbackMTU)) reasserting = false } else { - session.setLink(producer.link(withMTU: cfg.mtu)) + session.setLink(producer.link(withMTU: cfg.sessionConfiguration.fallbackMTU)) } } @@ -788,7 +788,7 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate { newSettings.ipv6Settings = ipv6Settings newSettings.dnsSettings = dnsSettings newSettings.proxySettings = proxySettings - newSettings.mtu = NSNumber(value: cfg.mtu) + newSettings.mtu = NSNumber(value: cfg.sessionConfiguration.fallbackMTU) setTunnelNetworkSettings(newSettings, completionHandler: completionHandler) } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift b/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift index 438af7c..4f250db 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift @@ -165,6 +165,8 @@ extension OpenVPN { static let digest: Digest = .sha1 static let compressionFraming: CompressionFraming = .disabled + + static let mtu = 1250 } /// The way to create a `Configuration` object for a `OpenVPNSession`. @@ -231,6 +233,9 @@ extension OpenVPN { /// Server is patched for the PIA VPN provider. public var usesPIAPatches: Bool? + /// The tunnel MTU. + public var mtu: Int? + // MARK: Server /// The auth-token returned by the server. @@ -310,6 +315,7 @@ extension OpenVPN { sanHost: sanHost, randomizeEndpoint: randomizeEndpoint, usesPIAPatches: usesPIAPatches, + mtu: mtu, authToken: authToken, peerId: peerId, ipv4: ipv4, @@ -402,6 +408,9 @@ extension OpenVPN { /// - Seealso: `ConfigurationBuilder.usesPIAPatches` public let usesPIAPatches: Bool? + /// - Seealso: `ConfigurationBuilder.mtu` + public let mtu: Int? + /// - Seealso: `ConfigurationBuilder.authToken` public let authToken: String? @@ -451,6 +460,11 @@ extension OpenVPN { public var fallbackCompressionFraming: CompressionFraming { return compressionFraming ?? Fallback.compressionFraming } + + /// :nodoc: + public var fallbackMTU: Int { + return mtu ?? Fallback.mtu + } } } @@ -484,6 +498,7 @@ extension OpenVPN.Configuration { builder.sanHost = sanHost builder.randomizeEndpoint = randomizeEndpoint builder.usesPIAPatches = usesPIAPatches + builder.mtu = mtu builder.authToken = authToken builder.peerId = peerId builder.ipv4 = ipv4 From 1966143fe9905755dbe0f0683435c0fee8b1c4a7 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sun, 27 Dec 2020 23:40:20 +0100 Subject: [PATCH 3/4] Parse MTU from --tun-mtu --- CHANGELOG.md | 4 ++++ .../Protocols/OpenVPN/ConfigurationParser.swift | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63303fc..223fbdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Parse `--tun-mtu` option. + ### Changed - Update API to access current Wi-Fi SSID. diff --git a/TunnelKit/Sources/Protocols/OpenVPN/ConfigurationParser.swift b/TunnelKit/Sources/Protocols/OpenVPN/ConfigurationParser.swift index 08bcca9..6a15ae7 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/ConfigurationParser.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/ConfigurationParser.swift @@ -72,6 +72,8 @@ extension OpenVPN { static let remoteRandom = NSRegularExpression("^remote-random") + static let mtu = NSRegularExpression("^tun-mtu +\\d+") + // MARK: Server static let authToken = NSRegularExpression("^auth-token +[a-zA-Z0-9/=+]+") @@ -216,6 +218,7 @@ extension OpenVPN { var optRemotes: [(String, UInt16?, SocketType?)] = [] // address, port, socket var optChecksEKU: Bool? var optRandomizeEndpoint: Bool? + var optMTU: Int? // var optAuthToken: String? var optPeerId: UInt32? @@ -468,6 +471,13 @@ extension OpenVPN { isHandled = true optRandomizeEndpoint = true } + Regex.mtu.enumerateArguments(in: line) { + isHandled = true + guard let str = $0.first else { + return + } + optMTU = Int(str) + } // MARK: Server @@ -677,6 +687,7 @@ extension OpenVPN { sessionBuilder.checksEKU = optChecksEKU sessionBuilder.randomizeEndpoint = optRandomizeEndpoint + sessionBuilder.mtu = optMTU // MARK: Server From e923382c8146441eb302d5e8eef80ac3c0db7920 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Mon, 28 Dec 2020 12:45:00 +0100 Subject: [PATCH 4/4] Default to unspecified MTU Hardcode control channel packets to 1000 bytes. --- TunnelKit/Sources/AppExtension/LinkProducer.swift | 4 +--- TunnelKit/Sources/Core/LinkInterface.swift | 3 --- .../Protocols/OpenVPN/AppExtension/NETCPLink.swift | 9 +++------ .../Protocols/OpenVPN/AppExtension/NEUDPLink.swift | 9 +++------ .../OpenVPNTunnelProvider+Configuration.swift | 6 +++++- .../OpenVPN/AppExtension/OpenVPNTunnelProvider.swift | 8 +++++--- TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift | 7 ------- TunnelKit/Sources/Protocols/OpenVPN/OpenVPNSession.swift | 4 ++-- 8 files changed, 19 insertions(+), 31 deletions(-) diff --git a/TunnelKit/Sources/AppExtension/LinkProducer.swift b/TunnelKit/Sources/AppExtension/LinkProducer.swift index f87126b..0c76bc9 100644 --- a/TunnelKit/Sources/AppExtension/LinkProducer.swift +++ b/TunnelKit/Sources/AppExtension/LinkProducer.swift @@ -30,8 +30,6 @@ public protocol LinkProducer { /** Returns a `LinkInterface`. - - - Parameter mtu: The MTU value. **/ - func link(withMTU mtu: Int) -> LinkInterface + func link() -> LinkInterface } diff --git a/TunnelKit/Sources/Core/LinkInterface.swift b/TunnelKit/Sources/Core/LinkInterface.swift index 2c1526d..077047a 100644 --- a/TunnelKit/Sources/Core/LinkInterface.swift +++ b/TunnelKit/Sources/Core/LinkInterface.swift @@ -45,9 +45,6 @@ public protocol LinkInterface: IOInterface { /// The literal address of the remote host. var remoteAddress: String? { get } - /// The maximum size of a packet. - var mtu: Int { get } - /// The number of packets that this interface is able to bufferize. var packetBufferSize: Int { get } } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NETCPLink.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NETCPLink.swift index 3cefbc2..b15e2f9 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NETCPLink.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NETCPLink.swift @@ -32,9 +32,8 @@ class NETCPLink: LinkInterface { private let maxPacketSize: Int - init(impl: NWTCPConnection, mtu: Int, maxPacketSize: Int? = nil) { + init(impl: NWTCPConnection, maxPacketSize: Int? = nil) { self.impl = impl - self.mtu = mtu self.maxPacketSize = maxPacketSize ?? (512 * 1024) } @@ -46,8 +45,6 @@ class NETCPLink: LinkInterface { return (impl.remoteAddress as? NWHostEndpoint)?.hostname } - let mtu: Int - var packetBufferSize: Int { return maxPacketSize } @@ -98,7 +95,7 @@ class NETCPLink: LinkInterface { /// :nodoc: extension NETCPSocket: LinkProducer { - public func link(withMTU mtu: Int) -> LinkInterface { - return NETCPLink(impl: impl, mtu: mtu) + public func link() -> LinkInterface { + return NETCPLink(impl: impl) } } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NEUDPLink.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NEUDPLink.swift index ba5a7f6..73d7b3c 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NEUDPLink.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/NEUDPLink.swift @@ -31,9 +31,8 @@ class NEUDPLink: LinkInterface { private let maxDatagrams: Int - init(impl: NWUDPSession, mtu: Int, maxDatagrams: Int? = nil) { + init(impl: NWUDPSession, maxDatagrams: Int? = nil) { self.impl = impl - self.mtu = mtu self.maxDatagrams = maxDatagrams ?? 200 } @@ -45,8 +44,6 @@ class NEUDPLink: LinkInterface { return (impl.resolvedEndpoint as? NWHostEndpoint)?.hostname } - let mtu: Int - var packetBufferSize: Int { return maxDatagrams } @@ -79,7 +76,7 @@ class NEUDPLink: LinkInterface { /// :nodoc: extension NEUDPSocket: LinkProducer { - public func link(withMTU mtu: Int) -> LinkInterface { - return NEUDPLink(impl: impl, mtu: mtu) + public func link() -> LinkInterface { + return NEUDPLink(impl: impl) } } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift index 6ab514d..ceb7130 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider+Configuration.swift @@ -725,6 +725,10 @@ private extension OpenVPN.Configuration { if let proxyBypassDomains = proxyBypassDomains { log.info("\tProxy bypass domains: \(proxyBypassDomains.maskedDescription)") } - log.info("\tMTU: \(fallbackMTU)") + if let mtu = mtu { + log.info("\tMTU: \(mtu)") + } else { + log.info("\tMTU: default") + } } } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift index 7449035..87f56bf 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/AppExtension/OpenVPNTunnelProvider.swift @@ -451,10 +451,10 @@ extension OpenVPNTunnelProvider: GenericSocketDelegate { return } if session.canRebindLink() { - session.rebindLink(producer.link(withMTU: cfg.sessionConfiguration.fallbackMTU)) + session.rebindLink(producer.link()) reasserting = false } else { - session.setLink(producer.link(withMTU: cfg.sessionConfiguration.fallbackMTU)) + session.setLink(producer.link()) } } @@ -788,7 +788,9 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate { newSettings.ipv6Settings = ipv6Settings newSettings.dnsSettings = dnsSettings newSettings.proxySettings = proxySettings - newSettings.mtu = NSNumber(value: cfg.sessionConfiguration.fallbackMTU) + if let mtu = cfg.sessionConfiguration.mtu { + newSettings.mtu = NSNumber(value: mtu) + } setTunnelNetworkSettings(newSettings, completionHandler: completionHandler) } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift b/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift index 4f250db..43de035 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift @@ -165,8 +165,6 @@ extension OpenVPN { static let digest: Digest = .sha1 static let compressionFraming: CompressionFraming = .disabled - - static let mtu = 1250 } /// The way to create a `Configuration` object for a `OpenVPNSession`. @@ -460,11 +458,6 @@ extension OpenVPN { public var fallbackCompressionFraming: CompressionFraming { return compressionFraming ?? Fallback.compressionFraming } - - /// :nodoc: - public var fallbackMTU: Int { - return mtu ?? Fallback.mtu - } } } diff --git a/TunnelKit/Sources/Protocols/OpenVPN/OpenVPNSession.swift b/TunnelKit/Sources/Protocols/OpenVPN/OpenVPNSession.swift index 00158e1..4f453dd 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/OpenVPNSession.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/OpenVPNSession.swift @@ -1015,12 +1015,12 @@ public class OpenVPNSession: Session { // Ruby: q_ctrl private func enqueueControlPackets(code: PacketCode, key: UInt8, payload: Data) { - guard let link = link else { + guard let _ = link else { log.warning("Not writing to LINK, interface is down") return } - controlChannel.enqueueOutboundPackets(withCode: code, key: key, payload: payload, maxPacketSize: link.mtu) + controlChannel.enqueueOutboundPackets(withCode: code, key: key, payload: payload, maxPacketSize: 1000) flushControlQueue() }