diff options
| author | Damian Johnson <atagar@torproject.org> | 2018-08-24 03:49:17 -0700 |
|---|---|---|
| committer | Damian Johnson <atagar@torproject.org> | 2018-08-24 03:51:24 -0700 |
| commit | 0b51f29d2385d26f62e16689f19e15e95027f461 (patch) | |
| tree | 6d233ea94723b347a5733f33b9a1c5a0e0bb3b57 | |
| parent | aba8c022ff917ac12419859f0a8d7bdc419d59e0 (diff) | |
Simplify rollback of key/digest during errorsdmr_review
The reason I asked for our functions to return a new copy of our key/digest is
because it lets us simplify this calling code a bit.
Rather than explicitly reverting the key/digest we can simply wait to record
the new values until cells are successfully sent and received.
| -rw-r--r-- | stem/client/__init__.py | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/stem/client/__init__.py b/stem/client/__init__.py index 8c96b8c2..0ee8cbf0 100644 --- a/stem/client/__init__.py +++ b/stem/client/__init__.py @@ -25,7 +25,6 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as +- close - closes this circuit """ -import copy import hashlib import threading @@ -234,18 +233,16 @@ class Circuit(object): """ with self.relay._orport_lock: - orig_forward_digest = self.forward_digest.copy() - orig_forward_key = copy.copy(self.forward_key) + cell = stem.client.cell.RelayCell(self.id, command, data, stream_id = stream_id) + encrypted_cell, new_forward_digest, new_forward_key = cell.encrypt(self.forward_digest, self.forward_key) - try: - cell = stem.client.cell.RelayCell(self.id, command, data, stream_id = stream_id) - encrypted_cell, self.forward_digest, self.forward_key = cell.encrypt(self.forward_digest, self.forward_key) + self.relay._orport.send(encrypted_cell.pack(self.relay.link_protocol)) - self.relay._orport.send(encrypted_cell.pack(self.relay.link_protocol)) - except: - self.forward_digest = orig_forward_digest - self.forward_key = orig_forward_key - raise + # Only recoding our new digest/key if the cell's successfully sent. If + # the above raises we should leave them alone. + + self.forward_digest = new_forward_digest + self.forward_key = new_forward_key reply = self.relay._orport.recv() reply_cells = [] @@ -253,24 +250,22 @@ class Circuit(object): relay_cell_cmd = stem.client.cell.RelayCell.VALUE while reply: - orig_backward_digest = self.backward_digest.copy() - orig_backward_key = copy.copy(self.backward_key) - - try: - raw_cell, reply = stem.client.cell.Cell.pop(reply, self.relay.link_protocol) - - if raw_cell.VALUE != relay_cell_cmd: - raise stem.ProtocolError('RELAY cell responses should be %i but was %i' % (relay_cell_cmd, raw_cell.VALUE)) - elif raw_cell.circ_id != self.id: - raise stem.ProtocolError('Response should be for circuit id %i, not %i' % (self.id, raw_cell.circ_id)) - - decrypted_cell, fully_decrypted, self.backward_digest, self.backward_key = raw_cell.decrypt(self.backward_digest, self.backward_key, interpret = True) - if not fully_decrypted: - raise stem.ProtocolError('Response for circuit id %i was not fully decrypted, when expected to be' % self.id) - except: - self.backward_digest = orig_backward_digest - self.backward_key = orig_backward_key - raise + raw_cell, reply = stem.client.cell.Cell.pop(reply, self.relay.link_protocol) + + if raw_cell.VALUE != relay_cell_cmd: + raise stem.ProtocolError('RELAY cell responses should be %i but was %i' % (relay_cell_cmd, raw_cell.VALUE)) + elif raw_cell.circ_id != self.id: + raise stem.ProtocolError('Response should be for circuit id %i, not %i' % (self.id, raw_cell.circ_id)) + + decrypted_cell, fully_decrypted, new_backward_digest, new_backward_key = raw_cell.decrypt(self.backward_digest, self.backward_key, interpret = True) + + if not fully_decrypted: + raise stem.ProtocolError('Response for circuit id %i was not fully decrypted, when expected to be' % self.id) + + # Again, if the above raises the digest/key should remain unchanged. + + self.backward_digest = new_backward_digest + self.backward_key = new_backward_key reply_cells.append(decrypted_cell) |
