Esempio n. 1
0
    def _send(self,
              command: 'stem.client.datatype.RelayCommand',
              data: Union[bytes, str] = b'',
              stream_id: int = 0) -> None:
        """
    Sends a message over the circuit.

    :param command: command to be issued
    :param data: message payload
    :param stream_id: specific stream this concerns
    """

        with self.relay._orport_lock:
            # Encrypt and send the cell. Our digest/key only updates if the cell is
            # successfully sent.

            cell = stem.client.cell.RelayCell(self.id,
                                              command,
                                              data,
                                              stream_id=stream_id)
            payload, forward_key, forward_digest = cell.encrypt(
                self.relay.link_protocol, self.forward_key,
                self.forward_digest)
            self.relay._orport.send(payload)

            self.forward_digest = forward_digest
            self.forward_key = forward_key
Esempio n. 2
0
  def send(self, command, data = '', stream_id = 0):
    """
    Sends a message over the circuit.

    :param stem.client.datatype.RelayCommand command: command to be issued
    :param bytes data: message payload
    :param int stream_id: specific stream this concerns

    :returns: **list** of :class:`~stem.client.cell.RelayCell` responses
    """

    with self.relay._orport_lock:
      # Encrypt and send the cell. Our digest/key only updates if the cell is
      # successfully sent.

      cell = stem.client.cell.RelayCell(self.id, command, data, stream_id = stream_id)
      payload, forward_key, forward_digest = cell.encrypt(self.relay.link_protocol, self.forward_key, self.forward_digest)
      self.relay._orport.send(payload)

      self.forward_digest = forward_digest
      self.forward_key = forward_key

      # Decrypt relay cells received in response. Again, our digest/key only
      # updates when handled successfully.

      reply = self.relay._orport.recv()
      reply_cells = []

      if len(reply) % self.relay.link_protocol.fixed_cell_length != 0:
        raise stem.ProtocolError('Circuit response should be a series of RELAY cells, but received an unexpected size for a response: %i' % len(reply))

      while reply:
        encrypted_cell, reply = split(reply, self.relay.link_protocol.fixed_cell_length)
        decrypted_cell, backward_key, backward_digest = stem.client.cell.RelayCell.decrypt(self.relay.link_protocol, encrypted_cell, self.backward_key, self.backward_digest)

        if self.id != decrypted_cell.circ_id:
          raise stem.ProtocolError('Response should be for circuit id %i, not %i' % (self.id, decrypted_cell.circ_id))

        self.backward_digest = backward_digest
        self.backward_key = backward_key

        reply_cells.append(decrypted_cell)

      return reply_cells