from twnet_parser.packet import parse7, TwPacket from twnet_parser.messages7.control.keep_alive import CtrlKeepAlive from twnet_parser.messages7.control.connect import CtrlConnect from twnet_parser.messages7.control.accept import CtrlAccept from twnet_parser.messages7.control.close import CtrlClose from twnet_parser.messages7.control.token import CtrlToken def test_parse_7_close(): packet = parse7(b'\x04\x0a\x00\xcf\x2e\xde\x1d\04') # 0.7 close assert packet.version == '0.7' assert packet.header.flags.control is True assert packet.messages[0].message_name == 'close' assert len(packet.messages) == 1 def test_pack_7_close_packet_defaults(): packet: TwPacket = TwPacket() close = CtrlClose() packet.messages.append(close) data = packet.pack() assert data == b'\x04\x00\x00\xff\xff\xff\xff\x04' def test_pack_7_close_packet_token(): packet: TwPacket = TwPacket() packet.header.token = b'\xaa\xbb\xcc\xdd' close = CtrlClose() packet.messages.append(close) data = packet.pack() assert data == b'\x04\x00\x00\xaa\xbb\xcc\xdd\x04' def test_pack_7_close_packet_token_and_reason(): packet: TwPacket = TwPacket() packet.header.token = b'\xaa\xbb\xcc\xdd' close = CtrlClose(reason = "timeout") packet.messages.append(close) data = packet.pack() assert data == b'\x04\x00\x00\xaa\xbb\xcc\xdd\x04timeout\x00' def test_pack_7_close_packet_set_control_false(): """ This packet is wrong according to tw spec because control is sent but flag not set """ packet: TwPacket = TwPacket() packet.header.token = b'\xaa\xbb\xcc\xdd' packet.header.flags.control = False close = CtrlClose() packet.messages.append(close) data = packet.pack() assert data == b'\x00\x00\x00\xaa\xbb\xcc\xdd\x04' def test_pack_7_close_packet_set_control_false_and_num_chunks2(): """ This packet is wrong according to tw spec because control is sent but flag not set and because num chunks is not set to zero """ packet: TwPacket = TwPacket() packet.header.token = b'\xaa\xbb\xcc\xdd' packet.header.flags.control = False packet.header.num_chunks = 2 close = CtrlClose() packet.messages.append(close) data = packet.pack() assert data == b'\x00\x00\x02\xaa\xbb\xcc\xdd\x04' def test_pack_7_close_packet_set_control_true(): packet: TwPacket = TwPacket() packet.header.token = b'\xaa\xbb\xcc\xdd' packet.header.flags.control = True close = CtrlClose() packet.messages.append(close) data = packet.pack() assert data == b'\x04\x00\x00\xaa\xbb\xcc\xdd\x04' def test_pack_7_close(): close = CtrlClose() data = close.pack() assert data == b'' def test_parse_7_close_with_reason(): packet = parse7(b'\x04\x0a\x00\xcf\x2e\xde\x1d\04shutdown\x00') # 0.7 close assert packet.version == '0.7' assert packet.header.flags.control is True assert packet.messages[0].message_name == 'close' assert len(packet.messages) == 1 assert packet.messages[0].reason == 'shutdown' def test_pack_7_close_with_reason(): close = CtrlClose(reason='foo') data = close.pack() assert data == b'foo\x00' close.unpack(b'hello world\x00') assert close.reason == 'hello world' def test_parse_keep_alive7(): packet = parse7(b'\x04\x04\x00\x5d\x95\xd6\x80\x00') # < packet header > assert packet.version == '0.7' assert packet.header.num_chunks == 0 assert packet.header.flags.control is True assert packet.header.token == b'\x5d\x95\xd6\x80' assert packet.messages[0].message_name == 'keep_alive' assert len(packet.messages) == 1 def test_pack_keep_alive7(): keep_alive = CtrlKeepAlive() data = keep_alive.pack() assert data == b'' def test_parse_7_ctrl_connect(): packet = parse7(b'\x04\x00\x00\xcf\x2e\xde\x1d' \ b'\x01' \ b'\x58\xeb\x9a\xf4' \ b'\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00') assert packet.version == '0.7' assert packet.header.num_chunks == 0 assert packet.header.flags.control is True assert packet.header.token == b'\xcf\x2e\xde\x1d' assert packet.messages[0].response_token == b'\x58\xeb\x9a\xf4' def test_pack_ctrl_connect7(): connect = CtrlConnect() data = connect.pack() assert 512 == len(data) assert connect.unpack(data) is True assert connect.response_token == b'\xff\xff\xff\xff' # drop too short anti reflection attack payloads assert connect.unpack(b'\xff\xff\xff\xff\x00\x00\x00') is False # allow too long anti reflection attack payloads assert connect.unpack(b'\xaa\xbb\xcc\xff' + bytes(900)) is True assert connect.response_token == b'\xaa\xbb\xcc\xff' def test_parse_7_accept(): packet = parse7(b'\x04\x00\x00\x58\xeb\x9a\xf4\x02') assert packet.version == '0.7' assert packet.header.num_chunks == 0 assert packet.header.flags.control is True assert packet.header.token == b'\x58\xeb\x9a\xf4' assert packet.messages[0].message_name == 'accept' def test_pack_ctrl_accept7(): accept = CtrlAccept() assert accept.pack() == b'' def test_parse_7_ctrl_token_sent_by_client(): data = b'\x04\x00\x00\xff\xff\xff\xff' \ b'\x05' \ b'\x58\xeb\x9a\xf4' \ b'\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00' packet = parse7(data=data, we_are_a_client = False) assert packet.version == '0.7' assert packet.header.num_chunks == 0 assert packet.header.flags.control is True assert packet.header.token == b'\xff\xff\xff\xff' assert packet.messages[0].message_name == 'token' assert packet.messages[0].response_token == b'\x58\xeb\x9a\xf4' def test_pack_token_sent_by_client7(): token = CtrlToken() token.response_token = b'\x01\xaa\xff\xff' data = token.pack(we_are_a_client = True) expected = b'\x01\xaa\xff\xff' \ b'\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00' assert expected == data def test_parse_7_ctrl_token_sent_by_server(): data = b'\x04\x00\x00\x58\xeb\x9a\xf4' \ b'\x05' \ b'\xcf\x2e\xde\x1d' # TODO: uncomment this when this issue is solved # https://gitlab.com/teeworlds-network/twnet_parser/-/issues/2 # should we insert some ErrMsg object into messages? # should we raise an error? # should the messages array be empty? # packet = parse7(data=data, we_are_a_client = False) # assert len(packet.messages) == 0 packet = parse7(data=data, we_are_a_client = True) assert packet.version == '0.7' assert packet.header.num_chunks == 0 assert packet.header.flags.control is True assert packet.header.token == b'\x58\xeb\x9a\xf4' assert packet.messages[0].response_token == b'\xcf\x2e\xde\x1d' def test_pack_token_sent_by_server7(): token = CtrlToken() data = token.pack(we_are_a_client = False) assert data == b'\xff\xff\xff\xff'