o
    ]i2                     @   s  U d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZmZ ddlmZ dZdZd	Zd
ZdZdZdZdZdZdededefddZdedefddZdededefddZdededefddZdd fdeeef deegef defd d!Z dedefd"d#Z!deeef defd$d%Z"dddefd&d'Z#dedefd(d)Z$dedefd*d+Z%dedefd,d-Z&dedefd.d/Z'deeef dedefd0d1Z(d2d fdedeegef deeef fd3d4Z)dededeeef fd5d6Z*dedefd7d8Z+dedeeef fd9d:Z,deddfd;d<Z-dedefd=d>Z.dedefd?d@Z/dedefdAdBZ0dedefdCdDZ1eeeeef Z2ddEe e)fdFdGe%e/fdHdIe e)fdJdKe e)fddLe$e.fddMe!e+fdNdOe"e,fdPdQe&e0fdRdSe%e/fdTdUe(e*fd
dVe$e.fdWdXe!e+fdYdZe(e*fd[d\e%e/fd]d^e(e*fd_d`e%e/fdadbe#e-fdcdde$e.fdedfe%e/fdgdhe'e1fdidje'e1fdkdle e)fdmdne e)fgZ3e4e2 e5do< i Z6e7ee2f e5dp< i Z8e7ee2f e5dq< e3D ]Z9e9e6e9d  < e9e8e9d < qG drds dsej:Z;G dtdu duej:Z<G dvdw dwZ=G dxdy dye>Z?G dzd{ d{e?Z@G d|d} d}e?ZAG d~d deZBG dd dZCdedefddZDddedee de=fddZEdS )    N)Callable)packunpack)OptionalProtocol   )random_transaction_idiB!   iNUTS            g      ?datalengthreturnc                 C   s"   | dd t d| | dd   S )Nr   r   !H   r   )r   r    r   ?/home/ubuntu/.local/lib/python3.10/site-packages/aioice/stun.pyset_body_length   s   "r   c                 C   s$   t | t| t t }t|tA S N)r   lenHEADER_LENGTHFINGERPRINT_LENGTHbinasciicrc32FINGERPRINT_XOR)r   
check_datar   r   r   message_fingerprint   s   r   keyc                 C   s(   t | t| t t }t||d S )Nsha1)r   r   r   INTEGRITY_LENGTHhmacnewdigest)r   r    r   r   r   r   message_integrity!   s   r&   transaction_idc                 C   sP   t dtd? t| }d}tt| D ]}|tj| | || A dddd7 }q|S )Nz!HI       r   bigF)signed)r   COOKIEranger   intto_bytes)r   r'   xpadxdatair   r   r   xor_data&   s
   $r3   c                 C      | S r   r   xr   r   r   <lambda>0       r7   valuexorc                 C   sH   t | d }t|t jrt}nt}tdd||td| d |j  S )Nr   !BBr   r   )	ipaddress
ip_address
isinstanceIPv4AddressIPV4_PROTOCOLIPV6_PROTOCOLr   packed)r9   r:   r=   protocolr   r   r   pack_address.   s
   $rD   c                 C   r4   r   r   r9   r   r   r   
pack_bytes:      rF   c                 C   s,   t dd| d d | d d | d d S )N!HBBr   d   r   utf8)r   encoderE   r   r   r   pack_error_code>   s   ,rL   c                 C      dS )Nr)   r   rE   r   r   r   	pack_noneB   rG   rN   c                 C   
   |  dS NrJ   )rK   rE   r   r   r   pack_stringF      
rQ   c                 C   
   t d| S )N!Ir   rE   r   r   r   pack_unsignedJ   rR   rU   c                 C   s   t d| d S )Nr   s     r   rE   r   r   r   pack_unsigned_shortN      rV   c                 C   rS   )N!Qr   rE   r   r   r   pack_unsigned_64R   rR   rY   c                       t |  fddS )Nc                    
   t |  S r   r3   r5   r'   r   r   r7   W      
 z"pack_xor_address.<locals>.<lambda>)rD   )r9   r'   r   r]   r   pack_xor_addressV      r_   c                 C   r4   r   r   r5   r   r   r   r7   \   r8   c                 C   s   t | dk r
tdtd| dd \}}| dd  }|tkrCt |dkr)td||}tt|dd  td|dd d fS |tkrkt |d	krQtd
||}tt|dd  td|dd d fS td)Nr   z(STUN address length is less than 4 bytesr;   r   r   r   z(STUN address has invalid length for IPv4r      z(STUN address has invalid length for IPv6z!STUN address has unknown protocol)	r   
ValueErrorr   r@   strr<   r?   rA   IPv6Address)r   r:   reservedrC   port_addressr   r   r   unpack_addressZ   s&   rg   c                    rZ   )Nc                    r[   r   r\   r5   r]   r   r   r7   }   r^   z$unpack_xor_address.<locals>.<lambda>)rg   )r   r'   r   r]   r   unpack_xor_address|   r`   rh   c                 C   r4   r   r   r   r   r   r   unpack_bytes   rG   rj   c                 C   sN   t | dk r
tdtd| dd \}}}| dd  d}|d | |fS )Nr   z$STUN error code is less than 4 bytesrH   r   rJ   rI   )r   rb   r   decode)r   re   	code_highcode_lowreasonr   r   r   unpack_error_code   s
   ro   c                 C      d S r   r   ri   r   r   r   unpack_none   rG   rq   c                 C   rO   rP   )rk   ri   r   r   r   unpack_string   rR   rr   c                 C      t d| d S )NrT   r   r   ri   r   r   r   unpack_unsigned   rW   ru   c                 C   s   t d| dd d S )Nr   r   r   rt   ri   r   r   r   unpack_unsigned_short   s   rv   c                 C   rs   )NrX   r   rt   ri   r   r   r   unpack_unsigned_64   rW   rw   zMAPPED-ADDRESS   zCHANGE-REQUESTr   zSOURCE-ADDRESS   zCHANGED-ADDRESSUSERNAMEMESSAGE-INTEGRITY	   
ERROR-CODE   zCHANNEL-NUMBER   LIFETIMEra   zXOR-PEER-ADDRESSREALM   NONCE   zXOR-RELAYED-ADDRESS   zREQUESTED-TRANSPORT    zXOR-MAPPED-ADDRESS$   PRIORITY%   zUSE-CANDIDATEi"  SOFTWAREi(  FINGERPRINTi)  zICE-CONTROLLEDi*  zICE-CONTROLLINGi+  zRESPONSE-ORIGINi,  zOTHER-ADDRESS
ATTRIBUTESATTRIBUTES_BY_TYPEATTRIBUTES_BY_NAMEc                   @   s   e Zd ZdZdZdZdZdS )Classr   r(        N)__name__
__module____qualname__REQUEST
INDICATIONRESPONSEERRORr   r   r   r   r      s
    r   c                   @   s,   e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
Methodr   r   rx   r   r      r	   r|   N)r   r   r   BINDINGSHARED_SECRETALLOCATEREFRESHSENDDATACREATE_PERMISSIONCHANNEL_BINDr   r   r   r   r      s    r   c                   @   sf   e Zd Z		ddededee dee ddf
ddZd	eddfd
dZ	defddZ
defddZdS )MessageNmessage_methodmessage_classr'   
attributesr   c                 C   s&   || _ || _|p
t | _|pi | _d S r   )r   r   r   r'   r   )selfr   r   r'   r   r   r   r   __init__   s   zMessage.__init__r    c                 C   sF   | j dd | j dd tt| || j d< tt| | j d< dS )z
        Add MESSAGE-INTEGRITY and FINGERPRINT attributes to the message.

        This must be the last step before sending out the message.
        r{   Nr   )r   popr&   bytesr   )r   r    r   r   r   add_message_integrity   s   zMessage.add_message_integrityc                 C   s   d}| j  D ]1\}}t| \}}}}|tkr||| j}n||}t|}	t|	}
|td||	| t|
 7 }qtd| j	| j
B t|t| j| S )Nr)   !HH!HHI12s)r   itemsr   r_   r'   r   padding_lengthr   r   r   r   r,   )r   r   	attr_name
attr_value	attr_type_	attr_packattr_unpackvattr_lenpad_lenr   r   r   	__bytes__   s&   
zMessage.__bytes__c                 C   s&   d| j j d| jj dt| j dS )NzMessage(message_method=Method.z, message_class=Class.z, transaction_id=))r   namer   reprr'   r   r   r   r   __repr__  s   zMessage.__repr__)NN)r   r   r   r   r   r   r   dictr   r   r   rc   r   r   r   r   r   r      s"    
r   c                   @   s   e Zd ZU dZee ed< dS )TransactionErrorNresponse)r   r   r   r   r   r   __annotations__r   r   r   r   r     s   
 r   c                   @   s,   e Zd ZdeddfddZdefddZdS )TransactionFailedr   r   Nc                 C   s
   || _ d S r   )r   )r   r   r   r   r   r     rR   zTransactionFailed.__init__c                 C   s(   d}d| j jv r|d| j jd  7 }|S )NzSTUN transaction failedr}   z
 (%s - %s))r   r   )r   outr   r   r   __str__  s   zTransactionFailed.__str__)r   r   r   r   r   rc   r   r   r   r   r   r     s    r   c                   @   s   e Zd ZdefddZdS )TransactionTimeoutr   c                 C   rM   )NzSTUN transaction timed outr   r   r   r   r   r     rG   zTransactionTimeout.__str__N)r   r   r   rc   r   r   r   r   r   r     s    r   c                   @   s*   e Zd Zdedeeef ddfddZdS )TransactionSendermessageaddrr   Nc                 C   rp   r   r   r   r   r   r   r   r   	send_stun!  r8   zTransactionSender.send_stun)r   r   r   r   tuplerc   r.   r   r   r   r   r   r      s    "r   c                   @   s   e Zd Z	ddedeeef dedee ddf
ddZ	d	edeeef ddfd
dZ
deeeeef f fddZdddZdS )TransactionNrequestr   rC   retransmissionsr   c                 C   sH   || _ t | _|| _t| _d | _|| _d| _	d|d ur|nt
 | _d S )Nr   r   )_Transaction__addrasyncioFuture_Transaction__future_Transaction__request	RETRY_RTO_Transaction__timeout_delay_Transaction__timeout_handle_Transaction__protocol_Transaction__tries	RETRY_MAX_Transaction__tries_max)r   r   r   rC   r   r   r   r   r   %  s   
zTransaction.__init__r   c                 C   sB   | j  s|jtjkr| j ||f d S | j t| d S d S r   )r   doner   r   r   
set_resultset_exceptionr   r   r   r   r   response_received9  s
   
zTransaction.response_receivedc                    s@   z|    | jI d H W | jr| j  S S | jr| j  w w r   )_Transaction__retryr   r   cancelr   r   r   r   run@  s   zTransaction.runc                 C   sj   | j | jkr| jt  d S | j| j| j t	
 }|| j| j| _|  jd9  _|  j d7  _ d S )Nr   r   )r   r   r   r   r   r   r   r   r   r   get_event_loop
call_laterr   r   r   )r   loopr   r   r   __retryH  s   zTransaction.__retryr   )r   N)r   r   r   r   r   rc   r.   r   r   r   r   r   r   r   r   r   r   r   $  s     

r   c                 C   s   | d }|dkr
dS d| S )zB
    STUN message attributes are padded to a 4-byte boundary.
    r   r   r   )r   restr   r   r   r   U  s   r   integrity_keyc                 C   sr  t | tk r
tdtd| dt \}}}}t | t| kr#tdi }t}|t | d krtd| ||d  \}}	| |d |d |	  }
t|	}|tv rt| \}}}}|tkre||
|d||< n||
||< |dkr|| t| d| krtd	n|d
kr|dur|| t| d| |krtd|d|	 | 7 }|t | d ks/t	t
|d@ t|d@ ||dS )zw
    Parses a STUN message.

    If the ``integrity_key`` parameter is given, the message's HMAC will be verified.
    z)STUN message length is less than 20 bytesr   r   z"STUN message length does not matchr   r   r]   r   z'STUN message fingerprint does not matchr{   Nz%STUN message integrity does not matchi>  r   )r   r   r'   r   )r   r   rb   r   r   r   rh   r   r&   r   r   r   )r   r   message_typer   cookier'   r   posr   r   r   r   r   r   r   r   r   r   r   parse_message`  sJ   


r   r   )Fr   r   enumr#   r<   collections.abcr   structr   r   typingr   r   utilsr   r,   r   r   r   r"   r@   rA   r   r   r   r.   r   r   r&   r3   r   rc   rD   rF   rL   rN   rQ   rU   rV   rY   r_   rg   rh   rj   ro   rq   rr   ru   rv   rw   AttributeEntryr   listr   r   r   r   attrIntEnumr   r   r   	Exceptionr   r   r   r   r   r   r   r   r   r   r   <module>   s   
 




"






















71 