Merge pull request #169 from roop/mojave-ipv4-and-ipv6

Fix how NETunnelInterface handles IP protocol number
This commit is contained in:
Davide De Rosa 2020-05-08 20:19:16 +02:00 committed by GitHub
commit aa580240b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 14 deletions

View File

@ -41,21 +41,12 @@ import NetworkExtension
public class NETunnelInterface: TunnelInterface { public class NETunnelInterface: TunnelInterface {
private weak var impl: NEPacketTunnelFlow? private weak var impl: NEPacketTunnelFlow?
private let protocolNumber: NSNumber private static let protocolNumberForIPv4 = NSNumber(value: AF_INET)
private static let protocolNumberForIPv6 = NSNumber(value: AF_INET6)
/// :nodoc: /// :nodoc:
public init(impl: NEPacketTunnelFlow, isIPv6: Bool) { public init(impl: NEPacketTunnelFlow) {
self.impl = impl self.impl = impl
#if os(macOS)
if #available(OSX 10.15, *) {
protocolNumber = (isIPv6 ? AF_INET6 : AF_INET) as NSNumber
} else {
// Force IPv4 on Mojave otherwise it breaks
protocolNumber = AF_INET as NSNumber
}
#else
protocolNumber = (isIPv6 ? AF_INET6 : AF_INET) as NSNumber
#endif
} }
// MARK: TunnelInterface // MARK: TunnelInterface
@ -85,14 +76,31 @@ public class NETunnelInterface: TunnelInterface {
/// :nodoc: /// :nodoc:
public func writePacket(_ packet: Data, completionHandler: ((Error?) -> Void)?) { public func writePacket(_ packet: Data, completionHandler: ((Error?) -> Void)?) {
let protocolNumber = NETunnelInterface.ipProtocolNumber(inPacket: packet)
impl?.writePackets([packet], withProtocols: [protocolNumber]) impl?.writePackets([packet], withProtocols: [protocolNumber])
completionHandler?(nil) completionHandler?(nil)
} }
/// :nodoc: /// :nodoc:
public func writePackets(_ packets: [Data], completionHandler: ((Error?) -> Void)?) { public func writePackets(_ packets: [Data], completionHandler: ((Error?) -> Void)?) {
let protocols = [NSNumber](repeating: protocolNumber, count: packets.count) let protocols = packets.map {
NETunnelInterface.ipProtocolNumber(inPacket: $0)
}
impl?.writePackets(packets, withProtocols: protocols) impl?.writePackets(packets, withProtocols: protocols)
completionHandler?(nil) completionHandler?(nil)
} }
private static func ipProtocolNumber(inPacket packet: Data) -> NSNumber {
// 'packet' contains the decrypted incoming IP packet data
// The first 4 bits identify the IP version
let ipVersion = ((packet[0] & 0xf0) >> 4)
assert(ipVersion == 4 || ipVersion == 6)
if ipVersion == 6 {
return NETunnelInterface.protocolNumberForIPv6
} else {
return NETunnelInterface.protocolNumberForIPv4
}
}
} }

View File

@ -565,7 +565,7 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate {
log.info("Tunnel interface is now UP") log.info("Tunnel interface is now UP")
session.setTunnel(tunnel: NETunnelInterface(impl: self.packetFlow, isIPv6: options.ipv6 != nil)) session.setTunnel(tunnel: NETunnelInterface(impl: self.packetFlow))
self.pendingStartHandler?(nil) self.pendingStartHandler?(nil)
self.pendingStartHandler = nil self.pendingStartHandler = nil