
    <ij                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKJr  SSK	J
r
JrJrJrJrJrJrJrJr  SSKJrJr  SrSr\R.                  r\R2                  r\R6                  r\R:                  \R<                  \R>                  \R@                  \RB                  \RD                  \RF                  4r$\RJ                  \RL                  \RN                  \RP                  \RR                  \RT                  \RV                  4r, " S S	\-5      r. " S
 S\.5      r/ " S S\.5      r0 " S S\/5      r1 " S S\/5      r2 " S S\/5      r3 " S S\/5      r4 " S S\/5      r5 " S S\/5      r6 " S S\.5      r7 " S S\.5      r8 " S S\/5      r9 " S  S!\/5      r: " S" S#\.5      r; " S$ S%\.5      r< " S& S'\.5      r= " S( S)\.5      r> " S* S+\.5      r? " S, S-\.5      r@ " S. S/\.5      rAg)0a  
Messages communicated over a Tor relay's ORPort.

.. versionadded:: 1.7.0

**Module Overview:**

::

  Cell - Base class for ORPort messages.
    |- CircuitCell - Circuit management.
    |  |- CreateCell - Create a circuit.              (section 5.1)
    |  |- CreatedCell - Acknowledge create.           (section 5.1)
    |  |- RelayCell - End-to-end data.                (section 6.1)
    |  |- DestroyCell - Stop using a circuit.         (section 5.4)
    |  |- CreateFastCell - Create a circuit, no PK.   (section 5.1)
    |  |- CreatedFastCell - Circuit created, no PK.   (section 5.1)
    |  |- RelayEarlyCell - End-to-end data; limited.  (section 5.6)
    |  |- Create2Cell - Extended CREATE cell.         (section 5.1)
    |  +- Created2Cell - Extended CREATED cell.       (section 5.1)
    |
    |- PaddingCell - Padding negotiation.             (section 7.2)
    |- VersionsCell - Negotiate proto version.        (section 4)
    |- NetinfoCell - Time and address info.           (section 4.5)
    |- PaddingNegotiateCell - Padding negotiation.    (section 7.2)
    |- VPaddingCell - Variable-length padding.        (section 7.2)
    |- CertsCell - Relay certificates.                (section 4.2)
    |- AuthChallengeCell - Challenge value.           (section 4.3)
    |- AuthenticateCell - Client authentication.      (section 4.5)
    |- AuthorizeCell - Client authorization.          (not yet used)
    |
    |- pack - encodes cell into bytes
    |- unpack - decodes series of cells
    +- pop - decodes cell with remainder
    N)	UNDEFINED)	HASH_LENZEROLinkProtocolAddressCertificateCloseReasonRelayCommandSizesplit)datetime_to_unix	str_toolsi      c                      ^  \ rS rSrSrSrSrSrSU 4S jjr\	S 5       r
\	S 5       rS	 r\	S
 5       r\	S 5       r\SS j5       r\S 5       rS rS rSrU =r$ )CellP   a  
Metadata for ORPort cells.

Unused padding are **not** used in equality checks or hashing. If two cells
differ only in their *unused* attribute they are functionally equal.

The following cell types explicitly don't have *unused* content:
  * PaddingCell (we consider all content part of payload)
  * VersionsCell (all content is unpacked and treated as a version specification)
  * VPaddingCell (we consider all content part of payload)

:var bytes unused: unused filler that padded the cell to the expected size
UNKNOWNFc                 6   > [         [        U ]  5         Xl        g N)superr   __init__unused)selfr   	__class__s     J/home/james-whalen/.local/lib/python3.13/site-packages/stem/client/cell.pyr   Cell.__init__c   s    	$ K    c                     [         R                  " [        R                  [           5       H  u  pU [        US[        5      :X  d  M  Us  $    [        SU -  5      e)z
Provides cell attributes by its name.

:param str name: cell command to fetch

:raises: **ValueError** if cell type is invalid
NAMEz'%s' isn't a valid cell typeinspect
getmemberssysmodules__name__getattrr   
ValueError)name_clss      r   by_nameCell.by_nameg   sM     $$S[[%:;	fi0	0
 < 3d:
;;r   c                     [         R                  " [        R                  [           5       H  u  pU [        US[        5      :X  d  M  Us  $    [        SU -  5      e)z
Provides cell attributes by its value.

:param int value: cell value to fetch

:raises: **ValueError** if cell type is invalid
VALUEz'%s' isn't a valid cell valuer!   )valuer*   r+   s      r   by_valueCell.by_valuew   sM     $$S[[%:;	'#w	2	2
 < 4u<
==r   c                 D    [        S[        U 5      R                  -  5      e)Nz(Packing not yet implemented for %s cells)NotImplementedErrortyper    r   link_protocols     r   pack	Cell.pack   s    
H4PT:??Z
[[r   c              #   d   #    U (       a%  [         R                  X5      u  p Uv   U (       a  M$  gg7f)a%  
Unpacks all cells from a response.

:param bytes content: payload to decode
:param int link_protocol: link protocol version

:returns: :class:`~stem.client.cell.Cell` generator

:raises:
  * ValueError if content is malformed
  * NotImplementedError if unable to unpack any of the cell types
N)r   pop)contentr7   cells      r   unpackCell.unpack   s&      hhw6mdj 's   *00c                    [        U5      nUR                  R                  U 5      u  p [        R                  U 5      u  p0[        R                  U5      nUR                  (       a  [        nO[        R                  U 5      u  pP[        U 5      U:  a$  [        SUR                  U[        U 5      4-  5      e[        X5      u  p`UR                  XbU5      U 4$ )a  
Unpacks the first cell.

:param bytes content: payload to decode
:param int link_protocol: link protocol version

:returns: (:class:`~stem.client.cell.Cell`, remainder) tuple

:raises:
  * ValueError if content is malformed
  * NotImplementedError if unable to unpack this cell type
z:%s cell should have a payload of %i bytes, but only had %i)r   circ_id_sizer;   CELL_TYPE_SIZEr   r1   IS_FIXED_SIZEFIXED_PAYLOAD_LENPAYLOAD_LEN_SIZElenr(   r    r   _unpack)r<   r7   circ_idcommandr+   payload_lenpayloads          r   r;   Cell.pop   s     !/M$1155g>G%))'2G
--
 C
%k-11':k
7|k!SWZW_W_alnqrynzV{{||W2G;;w7@@r   c           	      B   [        U [        5      (       a0  Uc  [        SU R                  -  5      eUS:  a  [        SU-  5      eOUb  [        SU R                  -  5      eSn[	        U5      n[        5       nXQR                  R                  U5      -  nU[        R                  R                  U R                  5      -  nXPR                  (       a  SO3[        R                  R                  [        U5      [        U5      -   5      -  nXR-  nXS-  nU R                  (       as  [        U5      UR                  :  a8  [        SU R                  [        U5      UR                  [        U5      4-  5      eU[        UR                  [        U5      -
  -  -  n[!        U5      $ )a.  
Provides bytes that can be used on the wire for these cell attributes.
Format of a properly packed cell depends on if it's fixed or variable
sized...

::

  Fixed:    [ CircuitID ][ Command ][ Payload ][ Padding ]
  Variable: [ CircuitID ][ Command ][ Size ][ Payload ]

:param str name: cell command
:param int link_protocol: link protocol version
:param bytes payload: cell payload
:param int circ_id: circuit id, if a CircuitCell

:returns: **bytes** with the encoded payload

:raises: **ValueError** if cell type invalid or payload makes cell too large
z%%s cells require a circuit identifier   z3Circuit identifiers must a positive integer, not %sz0%s cells should not specify a circuit identifierr   r   zdCell of type %s is too large (%i bytes), must not be more than %i. Check payload size (was %i bytes))
issubclassCircuitCellr(   r    r   	bytearrayrA   r8   r   CHARr/   rC   SHORTrF   fixed_cell_lengthr   bytes)r+   r7   rK   r   rH   r=   s         r   _pack
Cell._pack   s   , #{##	@388KLLQ;NQXXYY  
	KchhVWWg /M;D&&++G44DDIINN399%%D$$C$**//#g,V:T*UUDOD 	ND 	T]44	4  DG  DL  DL  NQ  RV  NW  Yf  Yx  Yx  z}  ~E  zF  CG  G  H  	H
dm55D	ABBd;r   c                 2    [        SU R                  -  5      e)a.  
Subclass implementation for unpacking cell content.

:param bytes content: payload to decode
:param stem.client.datatype.LinkProtocol link_protocol: link protocol version
:param int circ_id: circuit id cell is for

:returns: instance of this cell type

:raises: **ValueError** if content is malformed
z*Unpacking not yet implemented for %s cells)r4   r    r+   r<   rH   r7   s       r   rG   Cell._unpack   s     JSXXU
VVr   c                 ^    [        U[        5      (       a  [        U 5      [        U5      :H  $ S$ )NF)
isinstancer   hashr   others     r   __eq__Cell.__eq__  s&    (25$(?(?4:e$JUJr   c                     X:X  + $ r    r^   s     r   __ne__Cell.__ne__  s    r   r   r   )r   N)r&   
__module____qualname____firstlineno____doc__r    r/   rC   r   staticmethodr,   r1   r8   r>   r;   classmethodrV   rG   r`   rd   __static_attributes____classcell__r   s   @r   r   r   P   s     
$
%- < < > >\  $ A A> 3 3j W WK r   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )rP   i
  z9
Cell concerning circuits.

:var int circ_id: circuit id
c                 8   > [         [        U ]  U5        Xl        g r   )r   rP   r   rH   )r   rH   r   r   s      r   r   CircuitCell.__init__  s    	+t%f-Lr   )rH   rg   )r&   rh   ri   rj   rk   r   rn   ro   rp   s   @r   rP   rP   
  s     r   rP   c                   X   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 rS
rU =r$ )PaddingCelli  zh
Randomized content to either keep activity going on a circuit.

:var bytes payload: randomized payload
PADDINGr   Tc                    > U(       d  [         R                  " [        5      nO0[        U5      [        :w  a  [	        S[        [        U5      4-  5      e[
        [        U ]  5         Xl        g )Nz.Padding payload should be %i bytes, but was %i)	osurandomrD   rF   r(   r   ru   r   rK   )r   rK   r   s     r   r   PaddingCell.__init__!  sR    

,-g	W*	*GK\^abi^jJkkll	+t%'Lr   c                 @    [         R                  XR                  5      $ r   )ru   rV   rK   r6   s     r   r8   PaddingCell.pack*  s    ]LL99r   c                     [        U5      $ r   )ru   rY   s       r   rG   PaddingCell._unpack-  s    wr   c                 @    [         R                  R                  U SSS9$ NrK   Tcachestemutil
_hash_attrr   s    r   __hash__PaddingCell.__hash__1      99i>>r   rK   r   r&   rh   ri   rj   rk   r    r/   rC   r   r8   rm   rG   r   rn   ro   rp   s   @r   ru   ru     sA     
$
%-:    ? ?r   ru   c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )
CreateCelli5  CREATErN   Tc                 *   > [         [        U ]  5         g r   )r   r   r   r   r   s    r   r   CreateCell.__init__:  s    	*d$&r   rc   
r&   rh   ri   rj   r    r/   rC   r   rn   ro   rp   s   @r   r   r   5  s    	$
%-' 'r   r   c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )CreatedCelli>  CREATED   Tc                 *   > [         [        U ]  5         g r   )r   r   r   r   s    r   r   CreatedCell.__init__C      	+t%'r   rc   r   rp   s   @r   r   r   >  s    	$
%-( (r   r   c                   n   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 r\S
 5       rS rSrU =r$ )	RelayCelliG  a  
Command concerning a relay circuit.

Our 'recognized' attribute provides a cheap (but incomplete) check for if our
cell payload is encrypted. If non-zero our payload *IS* encrypted, but if
zero we're *PROBABLY* fully decrypted. This uncertainty is because encrypted
cells have a small chance of coincidently producing zero for this value as
well.

:var stem.client.RelayCommand command: command to be issued
:var int command_int: integer value of our command
:var bytes data: payload of the cell
:var int recognized: non-zero if payload is encrypted
:var int digest: running digest held with the relay
:var int stream_id: specific stream this concerns
RELAY   Tc                   > S[        [        U5      5      R                  5       ;   a7  UR                  5       S [        R
                   n[        R                  U5      nO[        R                  R                  U5      (       a)  US [        R
                   n[        R                  U5      nOF[        R                  R                  U5      (       a  O![        S[        U5      R                  -  5      e[        [        U ]?  X5        [         R"                  " U5      u  U l        U l        X`l        XPl        X@l        [,        R.                  " U5      U l        US:X  ah  U(       d,  U R$                  [2        ;   a  [        SU R$                  -  5      eU(       a-  U R$                  [4        ;   a  [        SU R$                  -  5      eg g g )Nr]   z=RELAY cell digest must be a hash, string, or int but was a %sr   z"%s relay cells require a stream idzE%s relay cells concern the circuit itself and cannot have a stream id)strr5   lowerdigestRELAY_DIGEST_SIZEsizer>   r   r   _is_str_is_intr(   r&   r   r   r   r
   getrI   command_int
recognized	stream_idr   	_to_bytesdataSTREAM_ID_REQUIREDSTREAM_ID_DISALLOWED)
r   rH   rI   r   r   r   r   r   digest_packedr   s
            r   r   RelayCell.__init__]  s`   T&\"((**
 mmo&='8'='=>m ''6f			6	"	"4/445m ''6f			6	"	"
VY]^dYeYnYnnoo	)T#G4%1%5%5g%>"DL$" ONK##D)DI{4<<+===LMM)==`cgcocoopp >9 r   c                 f   [        5       nU[        R                  R                  U R                  5      -  nU[        R
                  R                  U R                  5      -  nU[        R
                  R                  U R                  5      -  nU[        R                  R                  U R                  5      -  nU[        R
                  R                  [        U R                  5      5      -  nX R                  -  n[        R                  U[        U5      U R                  U R                   5      $ r   )rQ   r   rR   r8   r   rS   r   r   LONGr   rF   r   r   rV   rU   r   rH   )r   r7   rK   s      r   r8   RelayCell.packz  s    kGtyy~~d..//Gtzzt//Gtzzt~~..Gtyy~~dkk**Gtzzs499~..GyyG??=%.$++t||TTr   c                    [         R                   " U5      nUR                  5       n[        U5      U R                  :w  a.  [        R                  " SU R                  [        U5      4-  5      eU R
                  R                  U5      u  pa[        R                  R                  U5      u  pxU[        R                  :w  a  [        R                  " SU-  5      eUR                  U5      n	[        R                  XU 5      n
XU4$ )aY  
Decrypts content as a relay cell addressed to us. This provides back a
tuple of the form...

::

  (cell (RelayCell), new_key (CipherContext), new_digest (HASH))

:param int link_protocol: link protocol version
:param bytes content: cell content to be decrypted
:param cryptography.hazmat.primitives.ciphers.CipherContext key:
  key established with the relay we received this cell from
:param hashlib.HASH digest: running digest held with the relay

:returns: **tuple** with our decrypted cell and updated key/digest

:raises: :class:`stem.ProtocolError` if content doesn't belong to a relay
  cell
z/RELAY cells should be %i bytes, but received %iz<Cannot decrypt as a RELAY cell. This had command %i instead.)copyrF   rT   r   ProtocolErrorrA   r;   r   rR   r   r/   updaterG   )r7   r<   keyr   new_key
new_digestrH   rI   encrypted_payloadrK   r=   s              r   decryptRelayCell.decrypt  s    , iinGJ
7|}666PTaTsTsux  zA  vB  TC   C  D  D$1155g>G!%w!7G)//!]`gghhnn./GW}=D" *$$r   c           	         [         R                   " U5      nUR                  5       nUR                  R                  S-   nU R                  U5      US nUR	                  U5        [        U R                  U R                  U R                  XPR                  U R                  U R                  5      n[        UR                  U5      U5      u  pXR	                  U
5      -   XE4$ )a  
Encrypts our cell content to be sent with the given key. This provides back
a tuple of the form...

::

  (payload (bytes), new_key (CipherContext), new_digest (HASH))

:param int link_protocol: link protocol version
:param cryptography.hazmat.primitives.ciphers.CipherContext key:
  key established with the relay we're sending this cell to
:param hashlib.HASH digest: running digest held with the relay

:returns: **tuple** with our encrypted payload and updated key/digest
rN   N)r   rA   r   r8   r   r   rH   rI   r   r   r   r   r   )r   r7   r   r   r   r   header_sizepayload_without_digestr=   headerrK   s              r   encryptRelayCell.encrypt  s    " iinGJ
  ,,11A5K!YY}5klC,-
 T\\4<<JX\XgXgimitituDDIIm4kBOFNN7++W@@r   c           	         [         R                  R                  U5      u  pA[         R                  R                  U5      u  pQ[         R                  R                  U5      u  pa[         R                  R                  U5      u  pq[         R                  R                  U5      u  p[        X5      u  p[        U	5      U:w  a$  [        SU R                  U[        U	5      4-  5      e[        X$XXeU
5      $ )Nz5%s cell said it had %i bytes of data, but only had %i)
r   rR   r;   rS   r   r   rF   r(   r    r   )r+   r<   rH   r7   rI   r   r   r   data_lenr   r   s              r   rG   RelayCell._unpack  s    yy}}W-G**..1J0IiimmG,OF

w/H+LD
4yHNRURZRZ\dfijnfoQppqqWtYFSSr   c           	      F    [         R                  R                  U SSSSSS9$ )Nr   r   r   r   Tr   r   r   s    r   r   RelayCell.__hash__  s%    99m[(F\`aar   )rI   r   r   r   r   r   )r   r   r   r   )r&   rh   ri   rj   rk   r    r/   rC   r   r8   rl   r   r   rm   rG   r   rn   ro   rp   s   @r   r   r   G  sc    " 
$
%-q:	U 4% 4%l!AF T Tb br   r   c                   p   ^  \ rS rSrSrSrSrSr\R                  S4U 4S jjr
S r\S	 5       rS
 rSrU =r$ )DestroyCelli  z
Closes the given circuit.

:var stem.client.CloseReason reason: reason the circuit is being closed
:var int reason_int: integer value of our closure reason
DESTROY   Tr   c                 r   > [         [        U ]  X5        [        R                  " U5      u  U l        U l        g r   )r   r   r   r	   r   reason
reason_int)r   rH   r   r   r   s       r   r   DestroyCell.__init__  s)    	+t%g6#.??6#: DKr   c                     [         R                  U[        R                  R	                  U R
                  5      U R                  U R                  5      $ r   )r   rV   r   rR   r8   r   r   rH   r6   s     r   r8   DestroyCell.pack  s5    ]DIINN4??,KT[[Z^ZfZfggr   c                 \    [         R                  R                  U5      u  pE[        X$U5      $ r   )r   rR   r;   r   )r+   r<   rH   r7   r   r   s         r   rG   DestroyCell._unpack  s#    YY]]7+NFw//r   c                 B    [         R                  R                  U SSSS9$ )NrH   r   Tr   r   r   s    r   r   DestroyCell.__hash__	  s     99itLLr   )r   r   )r&   rh   ri   rj   rk   r    r/   rC   r	   NONEr   r8   rm   rG   r   rn   ro   rp   s   @r   r   r     sO     
$
%-'2'7'7# ;h 0 0M Mr   r   c                   X   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 rS
rU =r$ )CreateFastCelli  z
Create a circuit with our first hop. This is lighter weight than further hops
because we've already established the relay's identity and secret key.

:var bytes key_material: randomized key material
CREATE_FAST   Tc                    > U(       d  [         R                  " [        5      nO0[        U5      [        :w  a  [	        S[        [        U5      4-  5      e[
        [        U ]  X5        X l        g N+Key material should be %i bytes, but was %i)	rx   ry   r   rF   r(   r   r   r   key_material)r   rH   r   r   r   s       r   r   CreateFastCell.__init__  sS    ZZ)l	\	h	&DRUVbRcGddee	.$(9$r   c                 l    [         R                  XR                  U R                  U R                  5      $ r   )r   rV   r   r   rH   r6   s     r   r8   CreateFastCell.pack"  s%    /@/@$++t||\\r   c                     [        U[        5      u  pE[        U5      [        :w  a  [        S[        [        U5      4-  5      e[	        X$U5      $ r   )r   r   rF   r(   r   )r+   r<   rH   r7   r   r   s         r   rG   CreateFastCell._unpack%  sH     (3L
<H$DRUVbRcGddee'88r   c                 B    [         R                  R                  U SSSS9$ )NrH   r   Tr   r   r   s    r   r   CreateFastCell.__hash__.  s     99iNNr   )r   Nr   r   rp   s   @r   r   r     sD     
$
%-%] 9 9O Or   r   c                   X   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 rS
rU =r$ )CreatedFastCelli2  z
CREATE_FAST reply.

:var bytes key_material: randomized key material
:var bytes derivative_key: hash proving the relay knows our shared key
CREATED_FAST   Tc                 H  > U(       d  [         R                  " [        5      nO0[        U5      [        :w  a  [	        S[        [        U5      4-  5      e[        U5      [        :w  a  [	        S[        [        U5      4-  5      e[
        [        U ]  X5        X0l        X l	        g )Nr   z.Derivatived key should be %i bytes, but was %i)
rx   ry   r   rF   r(   r   r   r   r   derivative_key)r   rH   r   r   r   r   s        r   r   CreatedFastCell.__init__>  s    ZZ)l	\	h	&DRUVbRcGddee
>h&G8UXYgUhJiijj	/4)':$(r   c                     [         R                  XR                  U R                  -   U R                  U R
                  5      $ r   )r   rV   r   r   r   rH   r6   s     r   r8   CreatedFastCell.packK  s6      0A0ADDWDW0WY]YdYdfjfrfrssr   c                     [        U5      [        S-  :  a   [        S[        S-  [        U5      4-  5      e[        U[        5      u  pA[        U[        5      u  pQ[	        X%XA5      $ )Nr   z?Key material and derivatived key should be %i bytes, but was %i)rF   r   r(   r   r   )r+   r<   rH   r7   r   r   s         r   rG   CreatedFastCell._unpackN  sa    
7|hl"X\dgh\hjmnujv[wwxx!'84L#GX6N7LJJr   c                 D    [         R                  R                  U SSSSS9$ )NrH   r   r   Tr   r   r   s    r   r   CreatedFastCell.__hash__X  s$    99i1A>[_``r   )r   r   r   r   rp   s   @r   r   r   2  sF     
$
%-)t K Ka ar   r   c                   T   ^  \ rS rSrSrSrSrSrU 4S jrS r	\
S 5       rS	 rS
rU =r$ )VersionsCelli\  zC
Link version negotiation cell.

:var list versions: link versions
VERSIONS   Fc                 6   > [         [        U ]  5         Xl        g r   )r   r   r   versions)r   r   r   s     r   r   VersionsCell.__init__g  s    	,&(Mr   c                     SR                  U R                   Vs/ s H"  n[        R                  R	                  U5      PM$     sn5      n[
        R                  X5      $ s  snf r   )joinr   r   rS   r8   r   rV   )r   r7   vrK   s       r   r8   VersionsCell.packk  sG    hhDMMBMq

*MBCGm55 Cs   )Ac                     / nU(       a;  [         R                  R                  U5      u  pQUR                  U5        U(       a  M;  [	        U5      $ r   )r   rS   r;   appendr   )r+   r<   rH   r7   link_protocolsversions         r   rG   VersionsCell._unpacko  sA    N
0gG$ ' ''r   c                 @    [         R                  R                  U SSS9$ )Nr   Tr   r   r   s    r   r   VersionsCell.__hash__y  s    99j$??r   )r   r   rp   s   @r   r   r   \  sC     
$
%-6 ( (@ @r   r   c                   X   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 rS
rU =r$ )NetinfoCelli}  z
Information relays exchange about each other.

:var datetime timestamp: current time
:var stem.client.datatype.Address receiver_address: receiver's OR address
:var list sender_addresses: sender's OR addresses
NETINFO   Tc                    > [         [        U ]  U5        U(       a  UO[        R                  R	                  5       U l        Xl        X l        g r   )r   r  r   datetimenow	timestampreceiver_addresssender_addresses)r   r  r  r  r   r   s        r   r   NetinfoCell.__init__  s8    	+t%f-"+Y1B1B1F1F1HDN,,r   c                    [        5       nU[        R                  R                  [	        [        U R                  5      5      5      -  nX R                  R                  5       -  nU[        R                  R                  [        U R                  5      5      -  nU R                   H  nX#R                  5       -  nM     [        R                  U[        U5      U R                  5      $ r   )rQ   r   r   r8   intr   r  r  rR   rF   r  r  rV   rU   r   )r   r7   rK   addrs       r   r8   NetinfoCell.pack  s    kGtyy~~c"24>>"BCDDG$$))++Gtyy~~c$"7"7899G%%g & ]E'NDKKHHr   c                    [         R                  R                  U5      u  pA[        R                  " U5      u  pQ/ n[         R                  R                  U5      u  pq[        U5       H,  n[        R                  " U5      u  pUR                  U	5        M.     [        XV[        R                  R                  U5      US9$ )Nrf   )
r   r   r;   r   rR   ranger  r  r  utcfromtimestamp)
r+   r<   rH   r7   r  r  r  sender_addr_countir  s
             r   rG   NetinfoCell._unpack  s    w/I 'G 4!%w!7$%kk'*mdd# & '8;L;L;];]^g;hsz{{r   c                 D    [         R                  R                  U SSSSS9$ )Nr  r  r  Tr   r   r   s    r   r   NetinfoCell.__hash__  s%    99k3EGYcghhr   )r  r  r  r   r   rp   s   @r   r  r  }  sF     
$
%--	I | |i ir   r  c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )RelayEarlyCelli  RELAY_EARLY	   Tc                 *   > [         [        U ]  5         g r   )r   r  r   r   s    r   r   RelayEarlyCell.__init__  s    	.$(*r   rc   r   rp   s   @r   r  r    s    	$
%-+ +r   r  c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )Create2Celli  CREATE2
   Tc                 *   > [         [        U ]  5         g r   )r   r%  r   r   s    r   r   Create2Cell.__init__  r   r   rc   r   rp   s   @r   r%  r%    s    	$
%-( (r   r%  c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )Created2Celli  CREATED2   Tc                 *   > [         [        U ]  5         g r   )r   r+  r   r   s    r   r   Created2Cell.__init__  s    	,&(r   rc   r   rp   s   @r   r+  r+    s    	$
%-) )r   r+  c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )PaddingNegotiateCelli  PADDING_NEGOTIATE   Tc                 *   > [         [        U ]  5         g r   )r   r1  r   r   s    r   r   PaddingNegotiateCell.__init__  s    	
.0r   rc   r   rp   s   @r   r1  r1    s    	$
%-1 1r   r1  c                   X   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 rS
rU =r$ )VPaddingCelli  zx
Variable length randomized content to either keep activity going on a circuit.

:var bytes payload: randomized payload
VPADDING   Fc                    > Uc  Uc  [        S5      eUb  US:  a  [        SU-  5      eUb+  Ub(  U[        U5      :w  a  [        SU[        U5      4-  5      e[        [        U ]  5         Ub  X l        g [
        R                  " U5      U l        g )Nz5VPaddingCell constructor must specify payload or sizer   z)VPaddingCell size (%s) cannot be negativezRVPaddingCell constructor specified both a size of %i bytes and payload of %i bytes)r(   rF   r   r7  r   rx   ry   rK   )r   r   rK   r   s      r   r   VPaddingCell.__init__  s    |NOO		dQhBTIJJ		g1dc'l6Jkosux  zA  vB  oC  C  D  D	,&(%17Lrzz$7GDLr   c                 @    [         R                  XR                  5      $ r   )r7  rV   rK   r6   s     r   r8   VPaddingCell.pack  s    m\\::r   c                     [        US9$ )Nr   )r7  rY   s       r   rG   VPaddingCell._unpack  s    '**r   c                 @    [         R                  R                  U SSS9$ r   r   r   s    r   r   VPaddingCell.__hash__  r   r   r   )NNr   rp   s   @r   r7  r7    sB     
$
%-	H; + +? ?r   r7  c                   X   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 rS
rU =r$ )	CertsCelli  z
Certificate held by the relay we're communicating with.

:var list certificates: :class:`~stem.client.Certificate` of the relay
CERTS   Fc                 8   > [         [        U ]  U5        Xl        g r   )r   rC  r   certificates)r   certsr   r   s      r   r   CertsCell.__init__  s    	)T#F+r   c                 "   [         R                  U[        R                  R	                  [        U R                  5      5      SR                  U R                   Vs/ s H  o"R	                  5       PM     sn5      -   U R                  5      $ s  snf r   )	rC  rV   r   rR   r8   rF   rG  r   r   )r   r7   certs      r   r8   CertsCell.pack  s    ??=$))..T=N=N9O*PSVS[S[uy  vG  vG  ]H  vGmq]f]f]h  vG  ]H  TI  +I  KO  KV  KV  W  W  ]Hs   Bc                    [         R                  R                  U5      u  pA/ n[        U5       HL  nU(       d  [	        SU[        U5      4-  5      e[        R                  " U5      u  pqUR                  U5        MN     [        XQS9$ )NzJCERTS cell indicates it should have %i certificates, but only contained %irf   )	r   rR   r;   r  r(   rF   r   r  rC  )r+   r<   rH   r7   
cert_countrH  r  rK  s           r   rG   CertsCell._unpack  s    ))--0JE:eisuxy~u  iA  A  B  	B!oog.mdll4  U--r   c                 @    [         R                  R                  U SSS9$ )NrG  Tr   r   r   s    r   r   CertsCell.__hash__  s    99ndCCr   )rG  rg   r   rp   s   @r   rC  rC    sD     
$
%-W . .D Dr   rC  c                   X   ^  \ rS rSrSrSrSrSrSU 4S jjrS r	\
S 5       rS	 rS
rU =r$ )AuthChallengeCelli  z
First step of the authentication handshake.

:var bytes challenge: random bytes for us to sign to authenticate
:var list methods: authentication methods supported by the relay we're
  communicating with
AUTH_CHALLENGE   Fc                    > U(       d  [         R                  " [        5      nO0[        U5      [        :w  a  [	        S[        [        U5      4-  5      e[
        [        U ]  U5        X l        Xl	        g )Nz+AUTH_CHALLENGE must be %i bytes, but was %i)
rx   ry   AUTH_CHALLENGE_SIZErF   r(   r   rS  r   	challengemethods)r   rY  rX  r   r   s       r   r   AuthChallengeCell.__init__#  sZ    **01i	Y.	.DH[]`aj]kGllmm	
T+F3NLr   c                 Z   [        5       nX R                  -  nU[        R                  R	                  [        U R                  5      5      -  nU R                   H%  nU[        R                  R	                  U5      -  nM'     [        R                  U[        U5      U R                  5      $ r   )rQ   rX  r   rS   r8   rF   rY  rS  rV   rU   r   )r   r7   rK   methods       r   r8   AuthChallengeCell.pack-  sy    kG~~Gtzzs4<<011G,,((g  ""=%.$++NNr   c                     [         [        R                  R                  -   n[	        U5      U:  a  [        SU[	        U5      4-  5      e[        U[         5      u  pQ[        R                  R                  U5      u  pa[	        U5      U[        R                  R                  -  :  a  [        SU[	        U5      4-  5      e/ n[        U5       H5  n[        R                  R                  U5      u  pUR                  U	5        M7     [        XuUS9$ )Nz>AUTH_CHALLENGE payload should be at least %i bytes, but was %izCAUTH_CHALLENGE should have %i methods, but only had %i bytes for itrf   )rW  r   rS   r   rF   r(   r   r;   r  r  rS  )
r+   r<   rH   r7   min_sizerX  method_countrY  r  r\  s
             r   rG   AuthChallengeCell._unpack7  s    "TZZ__4H
7|hW[cehipeqZrrssw(;<I JJNN73L
7|lTZZ__44\`lnqrynz_{{||G< 

w/ofnnV ! W'BBr   c                 B    [         R                  R                  U SSSS9$ )NrX  rY  Tr   r   r   s    r   r   AuthChallengeCell.__hash__K  s     99k9dKKr   )rX  rY  r   r   rp   s   @r   rS  rS    sF     
$
%-O C C&L Lr   rS  c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )AuthenticateCelliO  AUTHENTICATE   Fc                 *   > [         [        U ]  5         g r   )r   re  r   r   s    r   r   AuthenticateCell.__init__T  s    	
D*,r   rc   r   rp   s   @r   re  re  O  s    	$
%-- -r   re  c                   4   ^  \ rS rSrSrSrSrU 4S jrSrU =r	$ )AuthorizeCelliX  	AUTHORIZE   Fc                 *   > [         [        U ]  5         g r   )r   rk  r   r   s    r   r   AuthorizeCell.__init__]  s    	-')r   rc   r   rp   s   @r   rk  rk  X  s    	$
%-* *r   rk  )Brk   r   r  r"   rx   r$   	stem.utilr   r   stem.client.datatyper   r   r   r   r   r	   r
   r   r   r   r   rD   rW  rR   rB   rS   rE   r   r   BEGINDATAEND	CONNECTEDRESOLVERESOLVED	BEGIN_DIRr   EXTENDEXTENDEDTRUNCATE	TRUNCATEDDROPEXTEND2	EXTENDED2r   objectr   rP   ru   r   r   r   r   r   r   r   r  r  r%  r+  r1  r7  rC  rS  re  rk  rc   r   r   <module>r     s  "H    	 
   { { { 1  :: II     w6 wt	$ 	?$ ?>' '(+ (gb gbTM+ M8"O[ "OJ'ak 'aT@4 @B-i$ -i`+[ +(+ ()4 )14 1?4 ?B!D !DH6L 6Lr-t -*D *r   