Move IP header logic to separate struct

This commit is contained in:
Davide De Rosa 2020-05-12 13:02:37 +02:00
parent f1a28a8d32
commit 01554713b8
3 changed files with 65 additions and 25 deletions

View File

@ -164,6 +164,8 @@
0E58BF5922411FEF006FB157 /* LZO.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF5822411FEF006FB157 /* LZO.m */; };
0E58BF5A22411FEF006FB157 /* LZO.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF5822411FEF006FB157 /* LZO.m */; };
0E749F622178911D00BB2701 /* pia-2048.pem in Resources */ = {isa = PBXBuildFile; fileRef = 0E749F612178911C00BB2701 /* pia-2048.pem */; };
0E7F3F6A246ABA0F006BE77F /* IPHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F3F69246ABA0F006BE77F /* IPHeader.swift */; };
0E7F3F6B246ABA0F006BE77F /* IPHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F3F69246ABA0F006BE77F /* IPHeader.swift */; };
0EA82A282190B220007960EB /* TunnelKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E3251C51F95770D00C108D9 /* TunnelKit.framework */; };
0EA82A3E2190B2BC007960EB /* pia-2048.pem in Resources */ = {isa = PBXBuildFile; fileRef = 0E749F612178911C00BB2701 /* pia-2048.pem */; };
0ECAF84A246697DA00D8266A /* TunnelKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E17D7F91F730D9F009EE129 /* TunnelKit.framework */; };
@ -418,6 +420,7 @@
0E6479DD212EAC96008E6888 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0E6479E0212EACD6008E6888 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0E749F612178911C00BB2701 /* pia-2048.pem */ = {isa = PBXFileReference; lastKnownFileType = text; path = "pia-2048.pem"; sourceTree = "<group>"; };
0E7F3F69246ABA0F006BE77F /* IPHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPHeader.swift; sourceTree = "<group>"; };
0E85A25B202CCA3D0059E9F9 /* TunnelKitHost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TunnelKitHost.entitlements; sourceTree = "<group>"; };
0EA82A232190B220007960EB /* TunnelKitTests-macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TunnelKitTests-macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
0EA82A272190B220007960EB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -839,6 +842,7 @@
0EFEB44B2006D3C800F81029 /* Errors.m */,
0EE2F9792291817300F56F49 /* Errors.swift */,
0EFEB4452006D3C800F81029 /* IOInterface.swift */,
0E7F3F69246ABA0F006BE77F /* IPHeader.swift */,
0EE2F96D2291636B00F56F49 /* IPv4Settings.swift */,
0EE2F9702291638600F56F49 /* IPv6Settings.swift */,
0EFEB4492006D3C800F81029 /* LinkInterface.swift */,
@ -1455,6 +1459,7 @@
0EE2F9FA22918DA100F56F49 /* DNSResolver.swift in Sources */,
0E23B43322982AF800304C30 /* ControlChannel.swift in Sources */,
0E23B48522982AF800304C30 /* ReplayProtector.m in Sources */,
0E7F3F6A246ABA0F006BE77F /* IPHeader.swift in Sources */,
0E23B44122982AF800304C30 /* OpenVPNSession+PIA.swift in Sources */,
0E23B42D22982AF800304C30 /* ControlChannelSerializer.swift in Sources */,
0EE2F9F622918DA100F56F49 /* NEUDPSocket.swift in Sources */,
@ -1537,6 +1542,7 @@
0EE2F9FB22918DA100F56F49 /* DNSResolver.swift in Sources */,
0E23B43422982AF800304C30 /* ControlChannel.swift in Sources */,
0E23B48622982AF800304C30 /* ReplayProtector.m in Sources */,
0E7F3F6B246ABA0F006BE77F /* IPHeader.swift in Sources */,
0E23B44222982AF800304C30 /* OpenVPNSession+PIA.swift in Sources */,
0E23B42E22982AF800304C30 /* ControlChannelSerializer.swift in Sources */,
0EE2F9F722918DA100F56F49 /* NEUDPSocket.swift in Sources */,

View File

@ -42,16 +42,6 @@ private let log = SwiftyBeaver.self
/// `TunnelInterface` implementation via NetworkExtension.
public class NETunnelInterface: TunnelInterface {
private static let ipV4: UInt8 = 4
private static let ipV6: UInt8 = 6
private static let ipV4ProtocolNumber = AF_INET as NSNumber
private static let ipV6ProtocolNumber = AF_INET6 as NSNumber
private static let fallbackProtocolNumber = ipV4ProtocolNumber
private weak var impl: NEPacketTunnelFlow?
/// :nodoc:
@ -86,7 +76,7 @@ public class NETunnelInterface: TunnelInterface {
/// :nodoc:
public func writePacket(_ packet: Data, completionHandler: ((Error?) -> Void)?) {
let protocolNumber = NETunnelInterface.ipProtocolNumber(inPacket: packet)
let protocolNumber = IPHeader.protocolNumber(inPacket: packet)
impl?.writePackets([packet], withProtocols: [protocolNumber])
completionHandler?(nil)
}
@ -94,22 +84,9 @@ public class NETunnelInterface: TunnelInterface {
/// :nodoc:
public func writePackets(_ packets: [Data], completionHandler: ((Error?) -> Void)?) {
let protocols = packets.map {
NETunnelInterface.ipProtocolNumber(inPacket: $0)
IPHeader.protocolNumber(inPacket: $0)
}
impl?.writePackets(packets, withProtocols: protocols)
completionHandler?(nil)
}
private static func ipProtocolNumber(inPacket packet: Data) -> NSNumber {
guard !packet.isEmpty else {
return fallbackProtocolNumber
}
// 'packet' contains the decrypted incoming IP packet data
// The first 4 bits identify the IP version
let ipVersion = (packet[0] & 0xf0) >> 4
assert(ipVersion == ipV4 || ipVersion == ipV6)
return (ipVersion == ipV6) ? ipV6ProtocolNumber : ipV4ProtocolNumber
}
}

View File

@ -0,0 +1,57 @@
//
// IPHeader.swift
// TunnelKit
//
// Created by Davide De Rosa on 5/12/20.
// Copyright (c) 2020 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
import Foundation
/// Helper for handling IP headers.
public struct IPHeader {
private static let ipV4: UInt8 = 4
private static let ipV6: UInt8 = 6
private static let ipV4ProtocolNumber = AF_INET as NSNumber
private static let ipV6ProtocolNumber = AF_INET6 as NSNumber
private static let fallbackProtocolNumber = ipV4ProtocolNumber
/**
Returns the protocol number from the IP header of a data packet.
- Parameter packet: The data to inspect.
- Returns: A protocol number between `AF_INET` and `AF_INET6`.
*/
public static func protocolNumber(inPacket packet: Data) -> NSNumber {
guard !packet.isEmpty else {
return fallbackProtocolNumber
}
// 'packet' contains the decrypted incoming IP packet data
// The first 4 bits identify the IP version
let ipVersion = (packet[0] & 0xf0) >> 4
assert(ipVersion == ipV4 || ipVersion == ipV6)
return (ipVersion == ipV6) ? ipV6ProtocolNumber : ipV4ProtocolNumber
}
}