diff --git a/.jazzy.yaml b/.jazzy.yaml index 1bff291..d8abcdb 100644 --- a/.jazzy.yaml +++ b/.jazzy.yaml @@ -17,6 +17,7 @@ custom_categories: - IOInterface - LinkInterface - TunnelInterface + - PacketStream - SessionProxy - SessionProxyDelegate - SessionReply diff --git a/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift b/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift index 1d801b8..c6ece48 100644 --- a/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift +++ b/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift @@ -224,7 +224,7 @@ class NETCPLink: LinkInterface { var newBuffer = buffer newBuffer.append(contentsOf: data) - let (until, packets) = CommonPacket.parsed(newBuffer) + let (until, packets) = PacketStream.packets(from: newBuffer) newBuffer = newBuffer.subdata(in: until.. Void)?) { - let stream = CommonPacket.stream(packet) + let stream = PacketStream.stream(from: packet) impl.write(stream) { (error) in completionHandler?(error) } } func writePackets(_ packets: [Data], completionHandler: ((Error?) -> Void)?) { - let stream = CommonPacket.stream(packets) + let stream = PacketStream.stream(from: packets) impl.write(stream) { (error) in completionHandler?(error) } diff --git a/TunnelKit/Sources/Core/Packet.swift b/TunnelKit/Sources/Core/Packet.swift index ca9fd04..a585e1c 100644 --- a/TunnelKit/Sources/Core/Packet.swift +++ b/TunnelKit/Sources/Core/Packet.swift @@ -38,20 +38,18 @@ import Foundation import __TunnelKitNative -class CommonPacket { - let packetId: UInt32 +/// Reads and writes packets as a stream. Useful for stream-oriented links (e.g TCP/IP). +public class PacketStream { - let code: PacketCode - - let key: UInt8 - - let sessionId: Data? - - let payload: Data? - - var sentDate: Date? - - static func parsed(_ stream: Data) -> (Int, [Data]) { + /** + Parses packets from a stream. + + - Parameter stream: The data stream. + - Returns: A pair where the first value is the `Int` offset up to which + the stream could be parsed, and the second value is an array containing + the parsed packets up to such offset. + */ + public static func packets(from stream: Data) -> (Int, [Data]) { var ni = 0 var parsed: [Data] = [] while (ni + 2 <= stream.count) { @@ -68,14 +66,26 @@ class CommonPacket { return (ni, parsed) } - static func stream(_ packet: Data) -> Data { - var stream = Data(capacity: 2 + packet.count) - stream.append(UInt16(packet.count).bigEndian) - stream.append(contentsOf: packet) - return stream + /** + Creates a contiguous stream of packets. + + - Parameter packet: The packet. + - Returns: A stream made of the packet. + */ + public static func stream(from packet: Data) -> Data { + var raw = Data(capacity: 2 + packet.count) + raw.append(UInt16(packet.count).bigEndian) + raw.append(contentsOf: packet) + return raw } - static func stream(_ packets: [Data]) -> Data { + /** + Creates a contiguous stream of packets. + + - Parameter packets: The array of packets. + - Returns: A stream made of the array of packets. + */ + public static func stream(from packets: [Data]) -> Data { var raw = Data() for payload in packets { raw.append(UInt16(payload.count).bigEndian) @@ -84,6 +94,23 @@ class CommonPacket { return raw } + private init() { + } +} + +class CommonPacket { + let packetId: UInt32 + + let code: PacketCode + + let key: UInt8 + + let sessionId: Data? + + let payload: Data? + + var sentDate: Date? + init(_ packetId: UInt32, _ code: PacketCode, _ key: UInt8, _ sessionId: Data?, _ payload: Data?) { self.packetId = packetId self.code = code diff --git a/TunnelKitTests/LinkTests.swift b/TunnelKitTests/LinkTests.swift index df89d2e..5697caf 100644 --- a/TunnelKitTests/LinkTests.swift +++ b/TunnelKitTests/LinkTests.swift @@ -77,27 +77,27 @@ class LinkTests: XCTestCase { bytes.append(contentsOf: [0xaa]) XCTAssertEqual(bytes.count, 21) - (until, packets) = CommonPacket.parsed(Data(bytes: bytes)) + (until, packets) = PacketStream.packets(from: Data(bytes: bytes)) XCTAssertEqual(until, 18) XCTAssertEqual(packets.count, 3) bytes.append(contentsOf: [0xbb, 0xcc]) - (until, packets) = CommonPacket.parsed(Data(bytes: bytes)) + (until, packets) = PacketStream.packets(from: Data(bytes: bytes)) XCTAssertEqual(until, 23) XCTAssertEqual(packets.count, 4) bytes.append(contentsOf: [0x00, 0x05]) - (until, packets) = CommonPacket.parsed(Data(bytes: bytes)) + (until, packets) = PacketStream.packets(from: Data(bytes: bytes)) XCTAssertEqual(until, 23) XCTAssertEqual(packets.count, 4) bytes.append(contentsOf: [0x11, 0x22, 0x33, 0x44]) - (until, packets) = CommonPacket.parsed(Data(bytes: bytes)) + (until, packets) = PacketStream.packets(from: Data(bytes: bytes)) XCTAssertEqual(until, 23) XCTAssertEqual(packets.count, 4) bytes.append(contentsOf: [0x55]) - (until, packets) = CommonPacket.parsed(Data(bytes: bytes)) + (until, packets) = PacketStream.packets(from: Data(bytes: bytes)) XCTAssertEqual(until, 30) XCTAssertEqual(packets.count, 5) @@ -108,7 +108,7 @@ class LinkTests: XCTestCase { bytes.append(contentsOf: [0x00, 0x04]) bytes.append(contentsOf: [0x10, 0x20]) - (until, packets) = CommonPacket.parsed(Data(bytes: bytes)) + (until, packets) = PacketStream.packets(from: Data(bytes: bytes)) XCTAssertEqual(until, 0) XCTAssertEqual(packets.count, 0) bytes.removeSubrange(0..