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/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 6daa5cc..ceb7130 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, @@ -188,6 +181,8 @@ extension OpenVPNTunnelProvider { static let usesPIAPatches = "UsesPIAPatches" + static let mtu = "MTU" + static let dnsServers = "DNSServers" static let searchDomains = "SearchDomains" @@ -208,8 +203,6 @@ extension OpenVPNTunnelProvider { static let resolvedAddresses = "ResolvedAddresses" - static let mtu = "MTU" - // MARK: Debugging static let debug = "Debug" @@ -228,9 +221,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 +357,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) @@ -420,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)") } @@ -440,7 +428,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 @@ -542,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 } @@ -628,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 } @@ -732,5 +725,10 @@ private extension OpenVPN.Configuration { if let proxyBypassDomains = proxyBypassDomains { log.info("\tProxy bypass domains: \(proxyBypassDomains.maskedDescription)") } + 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 2cad1a4..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.mtu)) + session.rebindLink(producer.link()) reasserting = false } else { - session.setLink(producer.link(withMTU: cfg.mtu)) + 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.mtu) + 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 438af7c..43de035 100644 --- a/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift +++ b/TunnelKit/Sources/Protocols/OpenVPN/Configuration.swift @@ -231,6 +231,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 +313,7 @@ extension OpenVPN { sanHost: sanHost, randomizeEndpoint: randomizeEndpoint, usesPIAPatches: usesPIAPatches, + mtu: mtu, authToken: authToken, peerId: peerId, ipv4: ipv4, @@ -402,6 +406,9 @@ extension OpenVPN { /// - Seealso: `ConfigurationBuilder.usesPIAPatches` public let usesPIAPatches: Bool? + /// - Seealso: `ConfigurationBuilder.mtu` + public let mtu: Int? + /// - Seealso: `ConfigurationBuilder.authToken` public let authToken: String? @@ -484,6 +491,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 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 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() }