nim-eth/tests/utp/test_packets.nim

163 lines
4.6 KiB
Nim

# Copyright (c) 2020-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.used.}
import
std/options,
unittest2,
../../eth/utp/packets,
../../eth/keys
suite "uTP Packet Encoding":
test "Encode/decode SYN packet":
let synPacket = synPacket(5, 10, 20)
let encoded = encodePacket(synPacket)
let decoded = decodePacket(encoded)
check:
len(encoded) == 20
decoded.isOk()
let synPacketDec = decoded.get()
check:
synPacketDec == synPacket
test "Encode/decode FIN packet":
let finPacket = finPacket(5, 10, 20, 30, 40)
let encoded = encodePacket(finPacket)
let decoded = decodePacket(encoded)
check:
len(encoded) == 20
decoded.isOk()
let finPacketDec = decoded.get()
check:
finPacketDec == finPacket
test "Encode/decode RESET packet":
let resetPacket = resetPacket(5, 10, 20)
let encoded = encodePacket(resetPacket)
let decoded = decodePacket(encoded)
check:
len(encoded) == 20
decoded.isOk()
let resetPacketDec = decoded.get()
check:
resetPacketDec == resetPacket
test "Encode/decode ACK packet: without extensions":
let ackPacket = ackPacket(5, 10, 20, 30, 40)
let encoded = encodePacket(ackPacket)
let decoded = decodePacket(encoded)
check:
len(encoded) == 20
decoded.isOk()
let ackPacketDec = decoded.get()
check:
ackPacketDec == ackPacket
test "Encode/decode ACK packet: with extensions":
let bitMask: array[4, byte] = [1'u8, 2, 3, 4]
let ackPacket = ackPacket(5, 10, 20, 30, 40, some(bitMask))
let encoded = encodePacket(ackPacket)
let decoded = decodePacket(encoded)
check:
len(encoded) == 26
decoded.isOk()
let ackPacketDec = decoded.get()
check:
ackPacketDec == ackPacket
ackPacketDec.eack.isSome()
test "Fail to decode packet with malformed extensions":
let bitMask: array[4, byte] = [1'u8, 2, 3, 4]
let ackPacket = ackPacket(5, 10, 20, 30, 40, some(bitMask))
var encoded1 = encodePacket(ackPacket)
# change nextExtension to non zero
encoded1[20] = 1
let err1 = decodePacket(encoded1)
check:
err1.isErr()
err1.error() == "Bad format of selective ack extension"
var encoded2 = encodePacket(ackPacket)
# change len of extension to value different than 4
encoded2[21] = 7
let err2 = decodePacket(encoded2)
check:
err2.isErr()
err2.error() == "Bad format of selective ack extension"
var encoded3 = encodePacket(ackPacket)
# delete last byte, now packet is to short
encoded3.del(encoded3.high)
let err3 = decodePacket(encoded3)
check:
err3.isErr()
err3.error() == "Packet too short for selective ack extension"
var encoded4 = encodePacket(ackPacket)
# change change extension field to something other than 0 or 1
encoded4[1] = 2
let err4 = decodePacket(encoded4)
check:
err4.isErr()
err4.error() == "Invalid extension type"
test "Decode STATE packet":
# Packet obtained by interaction with c reference implementation
let pack: array[20, uint8] = [
0x21'u8, 0x0, 0x15, 0x72, 0x00, 0xBA, 0x4D, 0x71, 0x0, 0x0,
0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x41, 0xA7, 0x00, 0x01]
let decoded = decodePacket(pack)
check:
decoded.isOk()
let packet = decoded.get()
check:
packet.header.pType == ST_STATE
packet.header.version == 1
packet.header.extension == 0
packet.header.connectionId == 5490
packet.header.timestamp == 12209521
packet.header.timestampDiff == 0
packet.header.wndSize == 1048576
packet.header.seqNr == 16807
packet.header.ackNr == 1
test "Modify timestamp of encoded packet":
let synPacket = synPacket(5, 10, 20)
let initialTimestamp = synPacket.header.timestamp
let initialAckNr = synPacket.header.ackNr
let modifiedTimeStamp = initialTimestamp + 120324
let modifiedAckNr = initialAckNr + 20
var encoded = encodePacket(synPacket)
modifyTimeStampAndAckNr(encoded, modifiedTimeStamp, modifiedAckNr)
let decoded = decodePacket(encoded)
check:
decoded.isOk()
decoded.get().header.timestamp == modifiedTimeStamp
decoded.get().header.ackNr == modifiedAckNr