thanhnc19's picture
Upload folder using huggingface_hub
15b8951 verified
Raw
History Blame Contribute Delete
9.61 kB
import unittest
from binascii import unhexlify
from collections import OrderedDict
from aioice import stun
from .utils import asynctest, read_message
class AttributeTest(unittest.TestCase):
def test_unpack_error_code(self):
data = unhexlify("00000457526f6c6520436f6e666c696374")
code, reason = stun.unpack_error_code(data)
self.assertEqual(code, 487)
self.assertEqual(reason, "Role Conflict")
def test_unpack_error_code_too_short(self):
data = unhexlify("000004")
with self.assertRaises(ValueError) as cm:
stun.unpack_error_code(data)
self.assertEqual(str(cm.exception), "STUN error code is less than 4 bytes")
def test_unpack_xor_address_ipv4(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
address, port = stun.unpack_xor_address(
unhexlify("0001a147e112a643"), transaction_id
)
self.assertEqual(address, "192.0.2.1")
self.assertEqual(port, 32853)
def test_unpack_xor_address_ipv4_truncated(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
with self.assertRaises(ValueError) as cm:
stun.unpack_xor_address(unhexlify("0001a147e112a6"), transaction_id)
self.assertEqual(str(cm.exception), "STUN address has invalid length for IPv4")
def test_unpack_xor_address_ipv6(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
address, port = stun.unpack_xor_address(
unhexlify("0002a1470113a9faa5d3f179bc25f4b5bed2b9d9"), transaction_id
)
self.assertEqual(address, "2001:db8:1234:5678:11:2233:4455:6677")
self.assertEqual(port, 32853)
def test_unpack_xor_address_ipv6_truncated(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
with self.assertRaises(ValueError) as cm:
stun.unpack_xor_address(
unhexlify("0002a1470113a9faa5d3f179bc25f4b5bed2b9"), transaction_id
)
self.assertEqual(str(cm.exception), "STUN address has invalid length for IPv6")
def test_unpack_xor_address_too_short(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
with self.assertRaises(ValueError) as cm:
stun.unpack_xor_address(unhexlify("0001"), transaction_id)
self.assertEqual(str(cm.exception), "STUN address length is less than 4 bytes")
def test_unpack_xor_address_unknown_protocol(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
with self.assertRaises(ValueError) as cm:
stun.unpack_xor_address(unhexlify("0003a147e112a643"), transaction_id)
self.assertEqual(str(cm.exception), "STUN address has unknown protocol")
def test_pack_error_code(self):
data = stun.pack_error_code((487, "Role Conflict"))
self.assertEqual(data, unhexlify("00000457526f6c6520436f6e666c696374"))
def test_pack_xor_address_ipv4(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
data = stun.pack_xor_address(("192.0.2.1", 32853), transaction_id)
self.assertEqual(data, unhexlify("0001a147e112a643"))
def test_pack_xor_address_ipv6(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
data = stun.pack_xor_address(
("2001:db8:1234:5678:11:2233:4455:6677", 32853), transaction_id
)
self.assertEqual(data, unhexlify("0002a1470113a9faa5d3f179bc25f4b5bed2b9d9"))
def test_pack_xor_address_unknown_protocol(self):
transaction_id = unhexlify("b7e7a701bc34d686fa87dfae")
with self.assertRaises(ValueError) as cm:
stun.pack_xor_address(("foo", 32853), transaction_id)
self.assertEqual(
str(cm.exception), "'foo' does not appear to be an IPv4 or IPv6 address"
)
class MessageTest(unittest.TestCase):
def test_binding_request(self):
data = read_message("binding_request.bin")
message = stun.parse_message(data)
self.assertEqual(message.message_method, stun.Method.BINDING)
self.assertEqual(message.message_class, stun.Class.REQUEST)
self.assertEqual(message.transaction_id, b"Nvfx3lU7FUBF")
self.assertEqual(message.attributes, OrderedDict())
self.assertEqual(bytes(message), data)
self.assertEqual(
repr(message),
"Message(message_method=Method.BINDING, message_class=Class.REQUEST, "
"transaction_id=b'Nvfx3lU7FUBF')",
)
def test_binding_request_ice_controlled(self):
data = read_message("binding_request_ice_controlled.bin")
message = stun.parse_message(data)
self.assertEqual(message.message_method, stun.Method.BINDING)
self.assertEqual(message.message_class, stun.Class.REQUEST)
self.assertEqual(message.transaction_id, b"wxaNbAdXjwG3")
self.assertEqual(
message.attributes,
OrderedDict(
[
("USERNAME", "AYeZ:sw7YvCSbcVex3bhi"),
("PRIORITY", 1685987071),
("SOFTWARE", "FreeSWITCH (-37-987c9b9 64bit)"),
("ICE-CONTROLLED", 5491930053772927353),
(
"MESSAGE-INTEGRITY",
unhexlify("1963108a4f764015a66b3fea0b1883dfde1436c8"),
),
("FINGERPRINT", 3230414530),
]
),
)
self.assertEqual(bytes(message), data)
def test_binding_request_ice_controlled_bad_fingerprint(self):
data = read_message("binding_request_ice_controlled.bin")[0:-1] + b"z"
with self.assertRaises(ValueError) as cm:
stun.parse_message(data)
self.assertEqual(str(cm.exception), "STUN message fingerprint does not match")
def test_binding_request_ice_controlled_bad_integrity(self):
data = read_message("binding_request_ice_controlled.bin")
with self.assertRaises(ValueError) as cm:
stun.parse_message(data, integrity_key=b"bogus-key")
self.assertEqual(str(cm.exception), "STUN message integrity does not match")
def test_binding_request_ice_controlling(self):
data = read_message("binding_request_ice_controlling.bin")
message = stun.parse_message(data)
self.assertEqual(message.message_method, stun.Method.BINDING)
self.assertEqual(message.message_class, stun.Class.REQUEST)
self.assertEqual(message.transaction_id, b"JEwwUxjLWaa2")
self.assertEqual(
message.attributes,
OrderedDict(
[
("USERNAME", "sw7YvCSbcVex3bhi:AYeZ"),
("ICE-CONTROLLING", 5943294521425135761),
("USE-CANDIDATE", None),
("PRIORITY", 1853759231),
(
"MESSAGE-INTEGRITY",
unhexlify("c87b58eccbacdbc075d497ad0c965a82937ab587"),
),
("FINGERPRINT", 1347006354),
]
),
)
def test_binding_response(self):
data = read_message("binding_response.bin")
message = stun.parse_message(data)
self.assertEqual(message.message_method, stun.Method.BINDING)
self.assertEqual(message.message_class, stun.Class.RESPONSE)
self.assertEqual(message.transaction_id, b"Nvfx3lU7FUBF")
self.assertEqual(
message.attributes,
OrderedDict(
[
("XOR-MAPPED-ADDRESS", ("80.200.136.90", 53054)),
("MAPPED-ADDRESS", ("80.200.136.90", 53054)),
("RESPONSE-ORIGIN", ("52.17.36.97", 3478)),
("OTHER-ADDRESS", ("52.17.36.97", 3479)),
("SOFTWARE", "Citrix-3.2.4.5 'Marshal West'"),
]
),
)
self.assertEqual(bytes(message), data)
def test_message_body_length_mismatch(self):
data = read_message("binding_response.bin") + b"123"
with self.assertRaises(ValueError) as cm:
stun.parse_message(data)
self.assertEqual(str(cm.exception), "STUN message length does not match")
def test_message_shorter_than_header(self):
with self.assertRaises(ValueError) as cm:
stun.parse_message(b"123")
self.assertEqual(str(cm.exception), "STUN message length is less than 20 bytes")
def test_message_with_unknown_method(self):
with self.assertRaises(ValueError) as cm:
stun.parse_message(bytes(20))
self.assertEqual(str(cm.exception), "0 is not a valid Method")
class TransactionTest(unittest.TestCase):
def setUp(self):
stun.RETRY_MAX = 0
stun.RETRY_RTO = 0
def tearDown(self):
stun.RETRY_MAX = 6
stun.RETRY_RTO = 0.5
@asynctest
async def test_timeout(self):
class DummyProtocol:
def send_stun(self, message, address):
pass
request = stun.Message(
message_method=stun.Method.BINDING, message_class=stun.Class.REQUEST
)
transaction = stun.Transaction(request, ("127.0.0.1", 1234), DummyProtocol())
# timeout
with self.assertRaises(stun.TransactionTimeout):
await transaction.run()
# receive response after timeout
response = stun.Message(
message_method=stun.Method.BINDING, message_class=stun.Class.RESPONSE
)
transaction.response_received(response, ("127.0.0.1", 1234))