/// <summary> /// Decode the raw packet. /// </summary> /// <param name="data">The raw packet</param> /// <returns>Number of bits read</returns> public override int Decode(byte[] data) { // Decode the Long Header int cursor = base.Decode(data); // Verify Packet type and read reserved bits if (PacketType != 0) { throw new CorruptedPacketException("Wrong packet type"); } _reservedBits = BitUtils.ReadNBits(_reservedBitsIndex, data, 2); // Read and verify the range for PacketNumberLength (1 to 4) PacketNumberLength = BitUtils.ReadNBits(_packetNumberLengthBitsIndex, data, 2) + 1; if (PacketNumberLength >= 5 || PacketNumberLength == 0) { throw new Exception("Invalid packet Number Length"); } // Read and decode both token length and actual token cursor += TokenLength.Decode(cursor, data); Token = new byte[TokenLength.Value]; Array.Copy(data, cursor / 8, Token, 0, (uint)TokenLength.Value); cursor += 8 * Convert.ToInt32(TokenLength.Value); // Verify that the packet length is the announced length cursor += Length.Decode(cursor, data); if ((UInt64)data.Length != Length.Value + (UInt64)cursor / 8) { throw new CorruptedPacketException($"Initial packet does not have the correct size. Expected: {Length.Value + (UInt64)cursor / 8} | Actual: {data.Length}"); } // Read the packet number PacketNumber = (uint)BitUtils.ReadNBytes(cursor, data, PacketNumberLength); cursor += (Int32)PacketNumberLength * 8; // Read the rest of the payload Payload = new byte[data.Length - (cursor / 8)]; Array.Copy(data, cursor / 8, Payload, 0, Payload.Length); cursor += 8 * Payload.Length; return(cursor); }
/* +-+-+-+-+-+-+-+-+ |1|1| 2 |R R|P P| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DCID Len (8) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Connection ID (0..160) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SCID Len (8) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Connection ID (0..160) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Length (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Packet Number (8/16/24/32) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Payload (*) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ /// <summary> /// Decode the raw packet to a HandshakePacket. /// </summary> /// <param name="data">The raw packet</param> /// <returns>Number of bits read</returns> public override int Decode(byte[] data) { int cursor = base.Decode(data); // Verify the PacketType if (PacketType != 2) { throw new CorruptedPacketException("Wrong packet type"); } // Read the reserved bits (though they currently are not used) _reservedBits = BitUtils.ReadNBits(_reservedBitsIndex, data, 2); // Read and verify the range for PacketNumberLength (1 to 4) PacketNumberLength = BitUtils.ReadNBits(_packetNumberLengthBitsIndex, data, 2) + 1; if (PacketNumberLength >= 5 || PacketNumberLength == 0) { throw new Exception("Invalid packet Number Length"); } // Verify that the packet length is the announced length cursor += Length.Decode(cursor, data); if ((UInt64)data.Length != Length.Value + (UInt64)cursor / 8) { throw new CorruptedPacketException($"Handshake packet does not have the correct size. Expected: {Length.Value + (UInt64)cursor / 8} | Actual: {data.Length}"); } // Read the packet number PacketNumber = (uint)BitUtils.ReadNBytes(cursor, data, PacketNumberLength); cursor += (Int32)PacketNumberLength * 8; // Read the rest of the payload Payload = new byte[data.Length - (cursor / 8)]; Array.Copy(data, cursor / 8, Payload, 0, Payload.Length); cursor += 8 * Payload.Length; return(cursor); }
/// <summary> /// Decode the raw packet to a RTTPacket. /// </summary> /// <param name="data">The raw packet</param> /// <returns>Number of bits read</returns> public override int Decode(byte[] data) { // Decode the Long Header int cursor = base.Decode(data); // Verify Packet Type, read reserved bits if (PacketType != 1) { throw new CorruptedPacketException("Wrong packet type"); } _reservedBits = BitUtils.ReadNBits(_reservedBitsIndex, data, 2); // Verify that PacketNumberLength is between 1 and 4 PacketNumberLength = BitUtils.ReadNBits(_packetNumberLengthBitsIndex, data, 2) + 1; if (PacketNumberLength >= 5 || PacketNumberLength == 0) { throw new Exception("Invalid packet Number Length"); } // Verify that the length of the received packet is the same as announced cursor += Length.Decode(cursor, data); if ((UInt64)data.Length != Length.Value + (UInt64)cursor / 8) { throw new CorruptedPacketException($"0-RTT packet does not have the correct size. Expected: {Length.Value + (UInt64)cursor / 8} | Actual: {data.Length}"); } // Read Packet Number PacketNumber = (uint)BitUtils.ReadNBytes(cursor, data, PacketNumberLength); cursor += (Int32)PacketNumberLength * 8; // Read the rest of the payload. Payload = new byte[data.Length - (cursor / 8)]; Array.Copy(data, cursor / 8, Payload, 0, Payload.Length); cursor += 8 * Payload.Length; return(cursor); }