def make(circ_id, stream_id, reason=DEF.REASON_DONE, reason_data='', link_version=3): '''Construct and return a RelayEnd cell, using default values where possible. Create a FixedLenCell.Header and a RelayCell.RelayHeader. :param int circ_id: Circuit ID to use in this cell :param int stream_id: Stream ID to use in this cell :param int reason: Single byte that describes the reason this stream was closed :param str reason_data: with REASON_EXITPOLICY, this optional field may be filled in :returns: :class:`~oppy.cell.relay.RelayEndCell` ''' h = FixedLenCell.Header(circ_id=circ_id, cmd=DEF.RELAY_CMD, link_version=link_version) r = RelayCell.RelayHeader(cmd=DEF.RELAY_END_CMD, recognized=DEF.RECOGNIZED, stream_id=stream_id, digest=DEF.EMPTY_DIGEST, rpayload_len=REASON_SIZE + len(reason_data)) return RelayEndCell(h, rheader=r, reason=reason, reason_data=reason_data)
def getBytes(self, trimmed=False): """TODO""" ret = self.header.getBytes() + self.rheader.getBytes() ret += struct.pack('!B', self.reason) if trimmed is True: return ret else: return FixedLenCell.padCellBytes(ret, self.header.link_version)
def getBytes(self, trimmed=False): '''Construct and return the byte string represented by this cell. :param bool trimmed: If **True**, return the non-padded payload. Otherwise pad the payload with null bytes to the fixed-size length in use according to the Link Protocol version. :returns: **str** byte string represented by this cell ''' ret = self.header.getBytes() + self.rheader.getBytes() + self.rpayload return FixedLenCell.padCellBytes(ret, self.header.link_version)
def getBytes(self, trimmed=False): '''Build and return the raw byte string this cell represents. :param bool trimmed: if **True**, do not pad payload bytes :returns: **str** raw bytes this cell represents ''' ret = self.header.getBytes() + self.rheader.getBytes() ret += struct.pack('!B', self.reason) if trimmed is True: return ret else: return FixedLenCell.padCellBytes(ret, self.header.link_version)
def make(circ_id, reason=TRUNCATE_REASON, link_version=3): """TODO""" h = FixedLenCell.Header(circ_id=circ_id, cmd=DEF.RELAY_CMD, link_version=link_version) r = RelayCell.RelayHeader(cmd=DEF.RELAY_TRUNCATE_CMD, recognized=DEF.RECOGNIZED, stream_id=TRUNCATE_STREAM_ID, digest=DEF.EMPTY_DIGEST, rpayload_len=TRUNCATE_RPAYLOAD_LEN) return RelayTruncateCell(h, r, reason)
def getBytes(self, trimmed=False): '''Build and return the raw byte string this cell represents. :param bool trimmed: If **True**, do not pad this cell's payload. :returns: **str** raw byte string represented by this cell ''' ret = self.header.getBytes() + self.rheader.getBytes() ret += self.addr ret += self.flags if trimmed is True: return ret else: return FixedLenCell.padCellBytes(ret, self.header.link_version)
def make(circ_id, stream_id, request, flags=None, link_version=3): '''Build and return a RelayBegin cell, filling in default values when possible. Automatically create a default FixedLenCell.Header and RelayCell.RelayHeader. :param int circ_id: Circuit ID to use in this cell :param int stream_id: Stream ID to use in this cell :param oppy.util.ExitRequest request: destination this cell will request a connection to :param list, int flags: flags to use for this connection :param int link_version: Link Protocol version in use on this connection :returns: :class:`~cell.relay.RelayBeginCell` ''' addr = str(request) if flags is None: flags = [DEF.BEGIN_FLAG_IPv6_OK] f = 0 for flag in flags: if flag not in DEF.RELAY_BEGIN_FLAGS: msg = 'Unrecognized Relay Begin flag: {}'.format(flag) raise BadPayloadData(msg) f |= (1 << (flag - 1)) flags = struct.pack('!I', f) h = FixedLenCell.Header(circ_id=circ_id, cmd=DEF.RELAY_CMD, link_version=link_version) r = RelayCell.RelayHeader(cmd=DEF.RELAY_BEGIN_CMD, recognized=DEF.RECOGNIZED, stream_id=stream_id, digest=DEF.EMPTY_DIGEST, rpayload_len=len(addr + flags)) return RelayBeginCell(h, rheader=r, addr=addr, flags=flags)
def make(circ_id, stream_id, rpayload, link_version=3): '''Construct and return a RelayData cell, using default values where possible. Create a FixedLenCell.Header and a RelayCell.RelayHeader. :param int circ_id: Circuit ID to use in this cell :param int stream_id: Stream ID to use in this cell :param str rpayload: data to use as the relay payload :param int link_version: Link Protocol version in use ''' if len(rpayload) > DEF.MAX_RPAYLOAD_LEN: raise BadPayloadData() h = FixedLenCell.Header(circ_id=circ_id, cmd=DEF.RELAY_CMD, link_version=link_version) r = RelayCell.RelayHeader(cmd=DEF.RELAY_DATA_CMD, recognized=DEF.RECOGNIZED, stream_id=stream_id, digest=DEF.EMPTY_DIGEST, rpayload_len=len(rpayload)) return RelayDataCell(h, rheader=r, rpayload=rpayload)
def make(circ_id, stream_id=0, link_version=3): '''Construct and return a RelaySendMeCell, using default values where possible. Create a FixedLenCell.Header and a RelayCell.RelayHeader for use in this cell. :param int circ_id: Circuit ID to use in this cell :param int stream_id: Stream ID to use in this cell. A Stream ID of zero indicates a 'circuit-level' SendMe cell, and a non-zero Stream ID indicates a 'stream-level' SendMe cell. :param int link_version: Link Protocol version in use :returns: :class:`~oppy.cell.relay.RelaySendMeCell` ''' h = FixedLenCell.Header(circ_id=circ_id, cmd=DEF.RELAY_CMD, link_version=link_version) r = RelayCell.RelayHeader(cmd=DEF.RELAY_SENDME_CMD, recognized=DEF.RECOGNIZED, stream_id=stream_id, digest=DEF.EMPTY_DIGEST, rpayload_len=0) return RelaySendMeCell(h, r)
CIRC_ID = 1 # Unit tests and constants for Create2Cell CREATE2_CMD = 10 CREATE2_NTOR_HTYPE = 2 CREATE2_NTOR_HLEN = 84 CREATE2_NTOR_HDATA_DUMMY = "\x00" * CREATE2_NTOR_HLEN create2_bytes_good = struct.pack( "!HBHH{}s".format(CREATE2_NTOR_HLEN), CIRC_ID, CREATE2_CMD, CREATE2_NTOR_HTYPE, CREATE2_NTOR_HLEN, CREATE2_NTOR_HDATA_DUMMY, ) create2_bytes_good_padded = FixedLenCell.padCellBytes(create2_bytes_good) assert len(create2_bytes_good_padded) == 512 create2_parse_bad_htype = struct.pack( "!HBHH{}s".format(CREATE2_NTOR_HLEN), CIRC_ID, CREATE2_CMD, # ntor should be 2 1, CREATE2_NTOR_HLEN, CREATE2_NTOR_HDATA_DUMMY, ) create2_parse_bad_htype = FixedLenCell.padCellBytes(create2_parse_bad_htype) assert len(create2_parse_bad_htype) == 512 create2_parse_bad_hlen = struct.pack( "!HBHH{}s".format(CREATE2_NTOR_HLEN), CIRC_ID, CREATE2_CMD, # hlen should be 84 for ntor
def make(circ_id, stream_id=0, nspec=None, lspecs=None, htype=DEF.NTOR_HTYPE, hlen=DEF.NTOR_HLEN, hdata='', link_version=3, early=True): '''Construct and return a RelayExtend2Cell, using default values where possible. Create a FixedLenCell.Header and a RelayCell.RelayHeader for use in this cell. .. note:: oppy currently only supports the NTor handshake and will reject unrecognized htype's and hlen's. :param int circ_id: Circuit ID to use in this cell :param int stream_id: Stream ID to use in this cell (should be zero) :param int nspec: the number of Link Specifiers in this cell :param list, oppy.cell.util.LinkSpecifier lspecs: list of Link Specifiers to include in this cell :param int htype: Type of handshake in use :param int hlen: length of the handshake data field :param str hdata: handshake data (*onion skin*) :param int link_version: Link Protocol version in use :param bool early: if **True**, use a RELAY_EARLY cmd instead of RELAY cmd :returns: :class:`~oppy.cell.relay.RelayExtend2Cell` ''' if lspecs is None: lspecs = [] if stream_id != 0: msg = "EXTEND2 cells should use stream_id=0." raise BadPayloadData(msg) if htype != DEF.NTOR_HTYPE: msg = 'htype was {}, but we currently only support ' msg += '{} (NTor) handshakes.' msg = msg.format(htype, DEF.NTOR_HTYPE) raise BadPayloadData(msg) if hlen != DEF.NTOR_HLEN: msg = 'htype was NTor and hlen was {} but expecting {}' msg = msg.format(hlen, DEF.NTOR_HLEN) raise BadPayloadData(msg) if hlen != len(hdata): msg = 'hlen {} neq len(hdata) {}'.format(hlen, len(hdata)) raise BadPayloadData(msg) cmd = DEF.RELAY_EARLY_CMD if early is True else DEF.RELAY_CMD h = FixedLenCell.Header(circ_id=circ_id, cmd=cmd, link_version=link_version) if nspec is None: nspec = len(lspecs) if len(lspecs) == 0: msg = 'No Link Specifiers found. At least 1 Link Specifier ' msg += 'is required.' raise BadPayloadData(msg) if nspec != len(lspecs): msg = 'Expected {} LinkSpecifiers but found {}' msg = msg.format(nspec, len(lspecs)) raise BadPayloadData(msg) rpayload_len = NSPEC_LEN for lspec in lspecs: rpayload_len += len(lspec) rpayload_len += HTYPE_LEN + HLEN_LEN + hlen r = RelayCell.RelayHeader(cmd=DEF.RELAY_EXTEND2_CMD, recognized=DEF.RECOGNIZED, stream_id=stream_id, digest=DEF.EMPTY_DIGEST, rpayload_len=rpayload_len) return RelayExtend2Cell(h, rheader=r, nspec=nspec, lspecs=lspecs, htype=htype, hlen=hlen, hdata=hdata)