// // ControlChannelSerializer.swift // TunnelKit // // Created by Davide De Rosa on 9/10/18. // Copyright (c) 2018 Davide De Rosa. All rights reserved. // // https://github.com/keeshux // // 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 . // import Foundation import __TunnelKitNative import SwiftyBeaver private let log = SwiftyBeaver.self protocol ControlChannelSerializer { func reset() func serialize(packet: ControlPacket) throws -> Data func deserialize(data: Data, start: Int, end: Int?) throws -> ControlPacket } extension ControlChannel { class PlainSerializer: ControlChannelSerializer { func reset() { } func serialize(packet: ControlPacket) throws -> Data { return packet.serialized() } func deserialize(data packet: Data, start: Int, end: Int?) throws -> ControlPacket { var offset = start let end = end ?? packet.count guard end >= offset + PacketOpcodeLength else { throw ControlChannelError("Missing opcode") } let codeValue = packet[offset] >> 3 guard let code = PacketCode(rawValue: codeValue) else { throw ControlChannelError("Unknown code: \(codeValue))") } let key = packet[offset] & 0b111 offset += PacketOpcodeLength log.debug("Control: Try read packet with code \(code) and key \(key)") guard end >= offset + PacketSessionIdLength else { throw ControlChannelError("Missing sessionId") } let sessionId = packet.subdata(offset: offset, count: PacketSessionIdLength) offset += PacketSessionIdLength guard end >= offset + 1 else { throw ControlChannelError("Missing ackSize") } let ackSize = packet[offset] offset += 1 var ackIds: [UInt32]? var ackRemoteSessionId: Data? if ackSize > 0 { guard end >= (offset + Int(ackSize) * PacketIdLength) else { throw ControlChannelError("Missing acks") } var ids: [UInt32] = [] for _ in 0..= offset + PacketSessionIdLength else { throw ControlChannelError("Missing remoteSessionId") } let remoteSessionId = packet.subdata(offset: offset, count: PacketSessionIdLength) offset += PacketSessionIdLength ackIds = ids ackRemoteSessionId = remoteSessionId } if code == .ackV1 { guard let ackIds = ackIds else { throw ControlChannelError("Ack packet without ids") } guard let ackRemoteSessionId = ackRemoteSessionId else { throw ControlChannelError("Ack packet without remoteSessionId") } return ControlPacket(key: key, sessionId: sessionId, ackIds: ackIds as [NSNumber], ackRemoteSessionId: ackRemoteSessionId) } guard end >= offset + PacketIdLength else { throw ControlChannelError("Missing packetId") } let packetId = packet.networkUInt32Value(from: offset) offset += PacketIdLength var payload: Data? if offset < end { payload = packet.subdata(in: offset..