twisted.transit: handle multiple records in one chunk
I made the classic dataReceived() mistake, and exited the function after delivering the first record. Keep at it until there are no complete records left.
This commit is contained in:
parent
84749dd8b3
commit
7234e25897
|
@ -867,9 +867,9 @@ class Connection(unittest.TestCase):
|
|||
# and that we can receive records properly
|
||||
inbound_records = []
|
||||
c.recordReceived = inbound_records.append
|
||||
send_box = SecretBox(owner._receiver_record_key())
|
||||
|
||||
RECORD3 = b"record3"
|
||||
send_box = SecretBox(owner._receiver_record_key())
|
||||
nonce_buf = unhexlify("%048x" % 0) # first nonce must be 0
|
||||
encrypted = send_box.encrypt(RECORD3, nonce_buf)
|
||||
length = unhexlify("%08x" % len(encrypted)) # always 4 bytes long
|
||||
|
@ -881,7 +881,6 @@ class Connection(unittest.TestCase):
|
|||
self.assertEqual(inbound_records, [RECORD3])
|
||||
|
||||
RECORD4 = b"record4"
|
||||
send_box = SecretBox(owner._receiver_record_key())
|
||||
nonce_buf = unhexlify("%048x" % 1) # nonces increment
|
||||
encrypted = send_box.encrypt(RECORD4, nonce_buf)
|
||||
length = unhexlify("%08x" % len(encrypted)) # always 4 bytes long
|
||||
|
@ -892,6 +891,21 @@ class Connection(unittest.TestCase):
|
|||
c.dataReceived(encrypted[-2:])
|
||||
self.assertEqual(inbound_records, [RECORD3, RECORD4])
|
||||
|
||||
# receiving two records at the same time: deliver both
|
||||
inbound_records[:] = []
|
||||
RECORD5 = b"record5"
|
||||
nonce_buf = unhexlify("%048x" % 2) # nonces increment
|
||||
encrypted = send_box.encrypt(RECORD5, nonce_buf)
|
||||
length = unhexlify("%08x" % len(encrypted)) # always 4 bytes long
|
||||
r5 = length+encrypted
|
||||
RECORD6 = b"record6"
|
||||
nonce_buf = unhexlify("%048x" % 3) # nonces increment
|
||||
encrypted = send_box.encrypt(RECORD6, nonce_buf)
|
||||
length = unhexlify("%08x" % len(encrypted)) # always 4 bytes long
|
||||
r6 = length+encrypted
|
||||
c.dataReceived(r5+r6)
|
||||
self.assertEqual(inbound_records, [RECORD5, RECORD6])
|
||||
|
||||
def corrupt(self, orig):
|
||||
last_byte = orig[-1:]
|
||||
num = int(hexlify(last_byte).decode("ascii"), 16)
|
||||
|
|
|
@ -143,15 +143,16 @@ class Connection(protocol.Protocol, policies.TimeoutMixin):
|
|||
d.callback(self)
|
||||
|
||||
def dataReceivedRECORDS(self):
|
||||
if len(self.buf) < 4:
|
||||
return
|
||||
length = int(hexlify(self.buf[:4]), 16)
|
||||
if len(self.buf) < 4+length:
|
||||
return
|
||||
encrypted, self.buf = self.buf[4:4+length], self.buf[4+length:]
|
||||
while True:
|
||||
if len(self.buf) < 4:
|
||||
return
|
||||
length = int(hexlify(self.buf[:4]), 16)
|
||||
if len(self.buf) < 4+length:
|
||||
return
|
||||
encrypted, self.buf = self.buf[4:4+length], self.buf[4+length:]
|
||||
|
||||
record = self._decrypt_record(encrypted)
|
||||
self.recordReceived(record)
|
||||
record = self._decrypt_record(encrypted)
|
||||
self.recordReceived(record)
|
||||
|
||||
def _decrypt_record(self, encrypted):
|
||||
nonce_buf = encrypted[:SecretBox.NONCE_SIZE] # assume it's prepended
|
||||
|
|
Loading…
Reference in New Issue
Block a user