o
    ]iW                     @   sb  d dl Z d dlZd dlZd dlZd dlZd dlZ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mZ d dlZddlmZmZmZ ddlmZmZmZ ddlmZ eeZdZdZ d	Z!d
Z"e# Z$e# Z%e
& Z'G dd dej(Z)de*dej+fddZ,de*ddfddZ-dedede.de/fddZ0de.de.de1e2 fddZ3de/deg df de4e2e/f d ee2 d!ee2 d"e.d#e2de4edf fd$d%Z5d&dd'e4e2e/f de4edf fd(d)Z6d*e1d+ de.ddfd,d-Z7d.e2ddfd/d0Z8d1edefd2d3Z9d.e2ddfd4d5Z:G d6d+ d+Z;G d7d de j<Z=G d8d9 d9Z>G d:d; d;e>Z?G d<d= d=Z@dS )>    N)Callable)OptionalUnioncast   )mdnsstunturn)	Candidatecandidate_foundationcandidate_priority)random_string         c                   @   s   e Zd ZdZ	 dZdS )TransportPolicyr   r   N)__name__
__module____qualname__ALLRELAY r   r   >/home/ubuntu/.local/lib/python3.10/site-packages/aioice/ice.pyr   #   s
    r   
subscriberreturnc              	      s   t tdst t_d t_t t_tj4 I d H   tjd u r't	 I d H t_tj
|  W d   I d H  tjS 1 I d H s?w   Y  tjS Nlock)hasattr_mdnsasyncioLockr   protocolsetsubscribersr   create_mdns_protocoladdr   r   r   r   get_or_create_mdns_protocol1   s   


r'   c              	      s~   t tdr=tj4 I d H # tj|  tjr%tjs%tj I d H  d t_W d   I d H  d S 1 I d H s6w   Y  d S d S r   )r   r   r   r#   discardr!   closer&   r   r   r   unref_mdns_protocol=   s   
.r*   localremoteice_controllingc                 C   sL   |r| j p|j }|r|j p| j }dt|| dt||  ||kr#dp$d S )zJ
    See RFC 5245 - 5.7.2. Computing Pair Priority and Ordering Pairs
    l        r   r   r   )priorityminmax)r+   r,   r-   GDr   r   r   candidate_pair_priorityF   s   ,r3   use_ipv4use_ipv6c                 C   sz   g }t  D ]4}|jD ].}t|jtr!| r!|jdkr!||j q|r9|jd dkr9|jd dkr9||jd  qq|S )z!
    Get local IP addresses.
    z	127.0.0.1r   z::1r   )ifaddrget_adaptersips
isinstanceipstrappend)r4   r5   	addressesadapterr:   r   r   r   get_host_addressesQ   s   
 r?   	componentprotocol_factoryStunProtocolturn_serverturn_usernameturn_passwordturn_sslturn_transportc                    s   t j||||||dI dH \}}|jd}	|jd}
ttdd|	d | dt| d|	d |	d d|
d |
d d		|_|j|fS )
zA
    Connect to a TURN server to obtain a relayed candidate.
    )server_addrusernamepasswordssl	transportNsocknamerelated_addressrelayudpr   r   	
foundationr@   rL   r.   hostporttyperN   related_port)r	   create_turn_endpointrL   get_extra_infor
   r   r   local_candidate)r@   rA   rC   rD   rE   rF   rG   _r!   candidate_addressrN   r   r   r   relayed_candidate_   s.   

r\   r!   stun_serverc                    s   t  }|dtj|d I dH |d f}tjtjjtj	j
d}| ||I dH \}}| j}ttdd|j|j|jt|jd|jd d |jd d d|j|jd	dfS )	zC
    Query STUN server to obtain a server-reflexive candidate.
    Nr   r   message_methodmessage_classsrflxrP   XOR-MAPPED-ADDRESSrQ   )r   get_event_looprun_in_executorsocketgethostbynamer   MessageMethodBINDINGClassREQUESTrequestrY   r
   r   rS   r@   rL   r   
attributesrT   )r!   r]   looprl   responserZ   rY   r   r   r   server_reflexive_candidate   s.   

rp   pairsCandidatePairc                    s&   dt dtf fdd}| j|d dS )z)
    Sort a list of candidate pairs.
    pairr   c                    s   t | j| j  S N)r3   rY   remote_candidate)rs   r-   r   r   pair_priority   s   
z+sort_candidate_pairs.<locals>.pair_prioritykeyN)rr   intsort)rq   r-   rw   r   rv   r   sort_candidate_pairs   s   r|   valuec                 C      t d| s
tddS )zk
    Check the password is well-formed.

    See RFC 5245 - 15.4. "ice-ufrag" and "ice-pwd" Attributes
    z^[a-zA-Z0-9+/]{22,256}$z$Password must satisfy 22*256ice-charNrematch
ValueErrorr}   r   r   r   validate_password      r   	candidatec                 C   s(   | j dvrtd| j  t| j | S )z2
    Check the remote candidate is supported.
    )rS   rO   ra   zUnexpected candidate type "%s")rU   r   	ipaddress
ip_addressrS   )r   r   r   r   validate_remote_candidate   s   
r   c                 C   r~   )zk
    Check the username is well-formed.

    See RFC 5245 - 15.4. "ice-ufrag" and "ice-pwd" Attributes
    z^[a-zA-Z0-9+/]{4,256}$z#Username must satisfy 4*256ice-charNr   r   r   r   r   validate_username   r   r   c                   @   s   e Zd ZdddeddfddZdefdd	Zedefd
dZ	ede
eef fddZedefddZede
eef fddZG dd dejZdS )rr   r!   rB   ru   r   Nc                 C   s,   d | _ d| _|| _|| _d| _tjj| _d S )NF)	task	nominatedr!   ru   remote_nominatedrr   StateFROZENstate)selfr!   ru   r   r   r   __init__   s   zCandidatePair.__init__c                 C   s   d| j | jf S )NzCandidatePair(%s -> %s))
local_addrremote_addrr   r   r   r   __repr__      zCandidatePair.__repr__c                 C      | j jS rt   )rY   r@   r   r   r   r   r@         zCandidatePair.componentc                 C      | j j| j jfS rt   )rY   rS   rT   r   r   r   r   r         zCandidatePair.local_addrc                 C   r   rt   )r!   rY   r   r   r   r   rY      r   zCandidatePair.local_candidatec                 C   r   rt   )ru   rS   rT   r   r   r   r   r      r   zCandidatePair.remote_addrc                   @   s    e Zd ZdZdZdZdZdZdS )zCandidatePair.Stater   r   r         N)r   r   r   r   WAITINGIN_PROGRESS	SUCCEEDEDFAILEDr   r   r   r   r      s    r   )r   r   r   r
   r   r;   r   propertyrz   r@   tupler   rY   r   enumEnumr   r   r   r   r   rr      s    c                   @   s   e Zd Zd%ddZdeddfdd	Zd
ejddfddZde	e
ef deddfddZdeddfddZd&ddZ		d'dejdeeef dee
 dee deejeeef f f
ddZde
deeef ddfddZdejdeeef ddfddZded eddfd!d"Zdefd#d$ZdS )(rB   receiver
Connectionr   Nc                 C   s0   t  | _tt| _d | _|| _d | _i | _	d S rt   )
r   Future_StunProtocol__closednextprotocol_ididrY   r   rL   transactions)r   r   r   r   r   r      s   


zStunProtocol.__init__excc                 C   s8   |  d| | j s| jd d  | jd d S d S )Nzconnection_lost(%s)T)_StunProtocol__log_debugr   doner   data_received
set_resultr   r   r   r   r   connection_lost   s
   
zStunProtocol.connection_lostrL   c                 C   s   |  d| ttj|| _d S )Nzconnection_made(%s))r   r   r   DatagramTransportrL   )r   rL   r   r   r   connection_made  s   zStunProtocol.connection_madedataaddrc                 C   s   |d |d f}t t|}zt|}| d|| W n ty.   | j|| jj	 Y d S w |j
tjjks=|j
tjjkrQ|j| jv rQ| j|j }||| d S |j
tjjkrc| j||| | d S d S )Nr   r   z< %s %s)r   bytesr   parse_messager   r   r   r   rY   r@   r`   rj   RESPONSEERRORtransaction_idr   response_receivedrk   request_received)r   r   r   messagetransactionr   r   r   datagram_received	  s"   

zStunProtocol.datagram_receivedc                 C   s   |  d| d S )Nzerror_received(%s))r   r   r   r   r   error_received  r   zStunProtocol.error_receivedc                    s   | j   | jI d H  d S rt   )rL   r)   r   r   r   r   r   r)   #  s   
zStunProtocol.closerl   integrity_keyretransmissionsc                    sj   |j | jvs	J |dur|| tj||| |d}|| j|j < z| I dH W | j|j = S | j|j = w )zE
        Execute a STUN transaction and return the response.
        N)r   )r   r   add_message_integrityr   Transactionrun)r   rl   r   r   r   r   r   r   r   rl   '  s   

zStunProtocol.requestc                    s   | j || d S rt   )rL   sendto)r   r   r   r   r   r   	send_data?  s   zStunProtocol.send_datar   c                 C   s$   |  d|| | jt|| dS )z&
        Send a STUN message.
        z> %s %sN)r   rL   r   r   )r   r   r   r   r   r   	send_stunB  s   zStunProtocol.send_stunmsgargsc                 G   s    t jd| | j| g|R   d S )Nz%s %s )loggerdebugr   r   r   r   r   r   r   __log_debugI  s    zStunProtocol.__log_debugc                 C   
   d| j  S )Nzprotocol(%s))r   r   r   r   r   r   L     
zStunProtocol.__repr__)r   r   r   Nr   NNN)r   r   r   r   	Exceptionr   r   BaseTransportr   r   r   r;   r   r   r   r)   r   rg   rz   r   rl   r   r   objectr   r   r   r   r   r   rB      s0    



 c                   @      e Zd ZdS )ConnectionEventNr   r   r   r   r   r   r   r   P      r   c                   @   r   )ConnectionClosedNr   r   r   r   r   r   T  r   r   c                   @   sf  e Zd ZdZdddddddddejddfdeded	ee	e
ef  d
ee	e
ef  dee
 dee
 dede
dedededee
 dee
 ddfddZedee fddZede
fddZede
fddZedee fddZdee ddfd d!Zdqd"d#Zd$edee fd%d&Zdqd'd(Zdqd)d*Zdee fd+d,Zdefd-d.Zde	eef fd/d0Zd1eddfd2d3Zd1ed$eddfd4d5Zd$ed6e
d7e
ddfd8d9Zd:e d;ede!j"fd<d=Z#d:e ddfd>d?Z$d@e!j"dAe	e
ef dBe%ddfdCdDZ&defdEdFZ'd:e ddfdGdHZ(d:e ddfdIdJZ)d:e dKe j*ddfdLdMZ+dNeddfdOdPZ,dBe%dedee  fdQdRZ-	Sdrd$edTee
 dUedee fdVdWZ.dqdXdYZ/dqdZd[Z0d1ee d$ee ddfd\d]Z1d@e!j"dAe	e
ef dBe%d^eddf
d_d`Z2dae!j"dAe	e
ef dBe%dbe	ee
f ddf
dcddZ3dqdedfZ4deddfdgdhZ5dqdidjZ6dke
dle7ddfdmdnZ8de
fdodpZ9dS )sr   a  
    An ICE connection for a single media stream.

    :param ice_controlling: Whether the local peer has the controlling role.
    :param components: The number of components.
    :param stun_server: The address of the STUN server or `None`.
    :param turn_server: The address of the TURN server or `None`.
    :param turn_username: The username for the TURN server.
    :param turn_password: The password for the TURN server.
    :param turn_ssl: Whether to use TLS for the TURN server.
    :param turn_transport: The transport for TURN server, `"udp"` or `"tcp"`.
    :param use_ipv4: Whether to use IPv4 candidates.
    :param use_ipv6: Whether to use IPv6 candidates.
    :param transport_policy: Transport policy.
    :param local_username: An optional local username, otherwise a random one
                           will be generated.
    :param local_password: An optional local password, otherwise a random one
                           will be generated.
    r   NFrP   Tr-   
componentsr]   rC   rD   rE   rF   rG   r4   r5   transport_policylocal_usernamelocal_passwordr   c                 C   sN  || _ |d u rtd}nt| |d u rtd}nt| d| _d | _d | _|| _|| _|| _	|| _
|| _|| _d| _ttd|d | _g | _d| _t | _g | _d| _d | _tt| _g | _d| _d| _|| _|| _ i | _!t | _"g | _#g | _$d| _%d | _&t | _'t()d| _*|	| _+|
| _,|d u r|d u r|t-j.krt/d|| _0d S )Nr      Fr   @   z:Relay transport policy requires a STUN and/or TURN server.)1r-   r   r   r   remote_is_literemote_usernameremote_passwordr]   rC   rD   rE   rF   rG   _closedr"   range_components_check_list_check_list_doner   Queue_check_list_state_early_checks_early_checks_done_event_waiterr   connection_id_id_local_candidates_local_candidates_end_local_candidates_start_local_password_local_username
_nominated_nominating
_protocols_remote_candidates_remote_candidates_end_query_consent_task_queuesecretsrandbits_tie_breaker	_use_ipv4	_use_ipv6r   r   r   _transport_policy)r   r-   r   r]   rC   rD   rE   rF   rG   r4   r5   r   r   r   r   r   r   r   m  sb   





zConnection.__init__c                 C      | j dd S )zS
        Local candidates, automatically set by :meth:`gather_candidates`.
        N)r   r   r   r   r   local_candidates  s   zConnection.local_candidatesc                 C      | j S )z;
        Local password, set at construction time.
        )r   r   r   r   r   r        zConnection.local_passwordc                 C   r  )z;
        Local username, set at construction time.
        )r   r   r   r   r   r     r  zConnection.local_usernamec                 C   r  )zk
        Remote candidates, which you need to populate using
        :meth:`add_remote_candidate`.
        N)r   r   r   r   r   remote_candidates  s   zConnection.remote_candidatesru   c              
      sP  | j rtd|du r|   d| _ dS t|jrYt| I dH }||jI dH }|du r;| d|j d dS | d|j d|  t		|}||_| 
|I dH  dS zt| W n ty~ } z| d|j d|  W Y d}~dS d}~ww | j| | jD ]}|j|r| ||st||}| j| q|   dS )z
        Add a remote candidate or signal end-of-candidates.

        To signal end-of-candidates, pass `None`.

        :param remote_candidate: A :class:`Candidate` instance or `None`.
        z4Cannot add remote candidate after end-of-candidates.NTzRemote candidate "z" could not be resolvedz" resolved to z" is not valid: )r   r   _prune_componentsr   is_mdns_hostnamerS   r'   resolve_Connection__log_infocopyadd_remote_candidater   r   r<   r   rY   can_pair_with
_find_pairrr   r   sort_check_list)r   ru   mdns_protocolr   copy_candidateer!   rs   r   r   r   r    sT   



zConnection.add_remote_candidatec                    sf   j s1d_ tjjd  fddjD }tj| I dH D ]	} j|7  _q"d_dS dS )zt
        Gather local candidates.

        You **must** call this coroutine before calling :meth:`connect`.
        T)r4   r5   c                    s   g | ]	}j | d qS ))r@   r=   )get_component_candidates).0r@   r=   r   r   r   
<listcomp>  s    z0Connection.gather_candidates.<locals>.<listcomp>N)	r   r?   r  r  r   r   gatherr   r   )r   coros
candidatesr   r  r   gather_candidates  s   
zConnection.gather_candidatesr@   c                 C   s.   t | jdd dD ]}|j|kr|  S q	dS )z
        Get the default local candidate for the specified component.

        :param component: The component whose default candidate is requested.
        c                 S   r  rt   )r.   xr   r   r   <lambda>,      z2Connection.get_default_candidate.<locals>.<lambda>rx   N)sortedr   r@   )r   r@   r   r   r   r   get_default_candidate&  s
   
z Connection.get_default_candidatec                    s  | j std| jdu s| jdu rtd| jD ]}| jD ]}|j|r7| ||s7t	||}| j
| qq|   |   | jD ]}| j|  qDg | _d| _	 |  sXn	tdI dH  qS| j
rm| j I dH }nt}| j
D ]
}|jr||j  qr|tkrtdt|  | _dS )z
        Perform ICE handshake.

        This coroutine returns if a candidate pair was successfuly nominated
        and raises an exception otherwise.
        z,Local candidates gathering was not performedNz&Remote username or password is missingTg{Gz?zICE negotiation failed)r   ConnectionErrorr   r   r   r   rY   r  r  rr   r   r<   r  _unfreeze_initialr   check_incomingr   check_periodicr   sleepr   get
ICE_FAILEDr   cancelICE_COMPLETEDcreate_taskquery_consentr   )r   ru   r!   rs   early_checkrescheckr   r   r   connect1  sJ   






zConnection.connectc                    s   | j r!| j  s!| j   z| j I dH  W n
 tjy    Y nw | jr-| js-| jt	 t
| I dH  | j  | jD ]	}| I dH  q<| j  | j  | js^| t  d| _dS dS )z'
        Close the connection.
        NT)r   r   r+  r   CancelledErrorr   r   r   
put_nowaitr*  r*   r   clearr   r)   r   r   _emit_eventr   )r   r!   r   r   r   r)   g  s(   





zConnection.closec                    sB   | j du s
J d| jrdS t }| | _ t| j I dH S )z
        Return the next `ConnectionEvent` or `None` if the connection is
        already closed.

        This method may only be called once at a time.
        Nzalready awaiting event)r   r   r   rc   create_futureshield)r   rn   r   r   r   	get_event  s   
zConnection.get_eventc                    s   |   I dH \}}|S )z
        Receive the next datagram.

        The return value is a `bytes` object representing the data received.

        If the connection is not established, a `ConnectionError` is raised.
        N)recvfromr   r   r@   r   r   r   recv  s   zConnection.recvc                    s<   t | js
td| j I dH }|d du rtd|S )aD  
        Receive the next datagram.

        The return value is a `(bytes, component)` tuple where `bytes` is a
        bytes object representing the data received and `component` is the
        component on which the data was received.

        If the connection is not established, a `ConnectionError` is raised.
        z"Cannot receive data, not connectedNr   z$Connection lost while receiving data)lenr   r$  r   r)  )r   resultr   r   r   r:    s   

zConnection.recvfromr   c                    s   |  |dI dH  dS )z
        Send a datagram on the first component.

        If the connection is not established, a `ConnectionError` is raised.

        :param data: The data to be sent.
        r   N)r   )r   r   r   r   r   send  s   zConnection.sendc                    s4   | j |}|r|j||jI dH  dS td)z
        Send a datagram on the specified component.

        If the connection is not established, a `ConnectionError` is raised.

        :param data: The data to be sent.
        :param component: The component on which to send the data.
        NzCannot send data, not connected)r   r)  r!   r   r   r$  )r   r   r@   active_pairr   r   r   r     s
   	zConnection.sendtolocal_foundationremote_foundationc                 C   sx   d}| j D ]}|jj|kr|jj|kr|} nqd}| jD ]}|j|kr+|j|kr+|}q|r0|s2J t||| j|< dS )z
        Force the selected candidate pair.

        If the remote party does not support ICE, you should using this
        instead of calling :meth:`connect`.
        N)r   rY   r@   rR   r   rr   r   )r   r@   rA  rB  r!   pru   cr   r   r   set_selected_pair  s   


zConnection.set_selected_pairrs   nominatec                 C   sv   d| j | jf }tjtjjtjjd}||jd< t	|j
d|jd< | jr3| j|jd< |r1d |jd< |S | j|jd< |S )	N%s:%sr^   USERNAMEprflxPRIORITYICE-CONTROLLINGUSE-CANDIDATEICE-CONTROLLED)r   r   r   rg   rh   ri   rj   rk   rm   r   r@   r-   r  )r   rs   rF  tx_usernamerl   r   r   r   build_request  s   

zConnection.build_requestc                 C   sP  d |_ |jtjjkrl|jr2|| j|j< | jD ]}|j|jkr1|jtjj	tjj
fv r1| |tjj qt| jt| jkrO| jsM| d | jt d| _d S | jD ]}|jj|jjkrk|jtjj
krk| |tjj	 qR| jD ]}|jtjjtjjfvr d S qo| js| jD ]}|jtjjkr d S q| js| d | jt d| _d S d S )NzICE completedTz
ICE failed)r   r   rr   r   r   r   r   r@   r   r   r   check_stater   r=  r   r   r  r   r4  r,  rY   rR   r-   r*  )r   rs   rC  r   r   r   check_complete  sN   






zConnection.check_completer   r   r!   c              	   C   s2  |j j}d}| jD ]}|j|d kr$|j|d kr$|}|j|ks"J  nq	|du rIttd|d|jd |d |d dd}| j| | 	d	| | 
||}|du rgt||}tjj|_| j| |   |jtjjtjjfv rw| | d
|jv r| jsd|_|jtjjkrd|_| | dS dS dS dS )z4
        Handle a succesful incoming check.
        Nr   r   
   rP   rJ  rI  rR   r@   rL   r.   rS   rT   rU   z&Discovered peer reflexive candidate %srL  T)rY   r@   r   rS   rT   r
   r   rm   r<   r  r  rr   r   r   r   r   r  r   check_start_taskr-   r   r   r   rQ  )r   r   r   r!   r@   ru   rD  rs   r   r   r   r&  ,  sF   
	


zConnection.check_incomingc                 C   sf   | j D ]}|jtjjkr| |  dS q| j D ]}|jtjjkr)| |  dS q| js1| j S dS )NTF)	r   r   rr   r   r   rT  r   r   r   r   rs   r   r   r   r'  ]  s   



zConnection.check_periodicc              
      s  |  |tjj | jo| j }| j||d}z|jj||j	| j
ddI dH \}}W nU tjy } zH|jri|jjddd dkrid	|jv rP| jd
d nd|jv r[| jdd | |I dH W  Y d}~S |  |tjj | | W Y d}~dS d}~ww ||j	kr| d| |  |tjj | | dS |s|jrd|_nR| jr|j| jvr| d| | j|j | j|dd}z|jj||j	| j
ddI dH  W n tjy   | d| |  |tjj | | Y dS w d|_|  |tjj | | dS )z!
        Starts a check.
        rF  utf8r   N
ERROR-CODEr   r     rK  Frv   rM  Tz)Check %s failed : source address mismatchzCheck %s nominating pairz)Check %s failed : could not nominate pair)rP  rr   r   r   r-   r   rO  r!   rl   r   r   encoder   TransactionErrorro   rm   r)  switch_rolecheck_startr   rQ  r  r   r   r@   r   r%   r   )r   rs   rF  rl   ro   r   r   r   r   r   r^  p  sd   








zConnection.check_startc                 C   s$   |j du rt| ||_ dS dS )zC
        Starts a check in a task, unless already started.
        N)r   r   r-  r^  rU  r   r   r   rT    s   
zConnection.check_start_taskr   c                 C   s   |  d||j| ||_dS )z/
        Updates the state of a check.
        zCheck %s %s -> %sN)r  r   )r   rs   r   r   r   r   rP    s   
zConnection.check_stateeventc                 C   s(   | j d ur| j }d | _ || d S d S rt   )r   r   )r   r_  waiterr   r   r   r6    s
   
zConnection._emit_eventc                 C   s,   | j D ]}|j|kr|j|kr|  S qdS )z:
        Find a candidate pair in the check list.
        N)r   r!   ru   )r   r!   ru   rs   r   r   r   r    s
   
zConnection._find_pairr   r=   timeoutc                    s  g }t  }g }|D ]s}z'|j fdd|dfdI d H \}}	|d}
|
d ur3|
tjtjtj	 W n t
yM } z d|| W Y d }~qd }~ww ||	 |	jd}ttdd	|d |d	t|d|d |d
 dd|	_ jtjkr~||	j q  j|7  _g } jr|D ]}	t|	jjjdkr|t t|	 j q jr|t t| fdd j j j  j! j"d t#|rt j$||dI d H \}}|D ]}|% d u r|& \}}	|| |	d ur j|	 q|D ]}|'  q|S )Nc                         t  S rt   rB   r   r   r   r   r         z5Connection.get_component_candidates.<locals>.<lambda>r   )r   re   zCould not bind to %s - %srM   rS   rP   r   rS  r   c                      rb  rt   rc  r   r   r   r   r     rd  )r@   rA   rC   rD   rE   rF   rG   )ra  )(r   rc   create_datagram_endpointrX   
setsockoptre   
SOL_SOCKET	SO_RCVBUFr	   UDP_SOCKET_BUFFER_SIZEOSErrorr  r<   rL   r
   r   r   rY   r  r   r   r   r]   r   r   rS   versionr-  rp   rC   r\   rD   rE   rF   rG   r=  wait	exceptionr>  r+  )r   r@   r=   ra  r  rn   host_protocolsaddressrL   r!   sockr   r[   tasksr   pendingr   r   r   r   r   r    s   

	



z#Connection.get_component_candidatesc                 C   s>   t tdd | j}| j| }|r| d|  || _dS dS )z
        Remove components for which the remote party did not provide any candidates.

        This can only be determined after end-of-candidates.
        c                 S   r  rt   )r@   r  r   r   r   r   #  r!  z.Connection._prune_components.<locals>.<lambda>z%Components %s have no candidate pairsN)r"   mapr   r   r  )r   seen_componentsmissing_componentsr   r   r   r
    s   

zConnection._prune_componentsc              	      s   d}	 t tddt    I dH  | j D ]C}| j|dd}z|jj||j	| j
ddd	I dH  d}W n tjyF   |d
7 }Y nw |tkr\| d d| _|  I dH   S qq)z8
        Periodically check consent (RFC 7675).
        r   Tg?g?NFrV  rW  )r   r   r   zConsent to send expired)r   r(  CONSENT_INTERVALrandomr   valuesrO  r!   rl   r   r   r[  r   r\  CONSENT_FAILURESr  r   r)   )r   failuresrs   rl   r   r   r   r.  +  s.    

zConnection.query_consentc                 C   s   | j ||f d S rt   )r   r4  r;  r   r   r   r   E  s   zConnection.data_receivedraw_datac              	   C   s  |j tjjkr| |||d d S z&tj|| jdd | jd ur6d| j	| jf }|j
d|kr6tdW n tyI   | |||d Y d S w | jrpd|j
v rp| d | j|j
d kri| |||d	 d S | jd
d n%| jsd|j
v r| d | j|j
d k r| |||d	 d S | jdd tjtjjtjj|jd}||j
d< || jd ||| | js| js| j|||f d S | ||| d S )N)i  zBad RequestrW  rX  rG  rH  zWrong usernamerK  z)Role conflict, expected to be controlling)rZ  zRole ConflictFrv   rM  z(Role conflict, expected to be controlledTr_   r`   r   rb   )r_   r   rh   ri   respond_errorr   r   r[  r   r   rm   r)  r   r-   r  r  r]  rg   rj   r   r   r   r   r   r   r   r<   r&  )r   r   r   r!   r{  rx_usernamero   r   r   r   r   H  sN   



zConnection.request_receivedrl   
error_codec                 C   sD   t j|jt jj|jd}||jd< || j	d |
|| d S )Nr|  rY  rW  )r   rg   r_   rj   r   r   rm   r   r   r[  r   )r   rl   r   r!   r  ro   r   r   r   r}  }  s   
zConnection.respond_errorc                 C   s   t | j| j d S rt   )r|   r   r-   r   r   r   r   r    s   zConnection.sort_check_listc                 C   s&   |  d|rdpd || _|   d S )NzSwitching to %s rolecontrolling
controlled)r  r-   r  )r   r-   r   r   r   r]    s
   zConnection.switch_rolec                 C   s   d }| j D ]}|jt| jkr|} nq|d u rd S |jtjjkr)| |tjj	 t
|jj}| j D ]$}|j|jkrV|jj|vrV|jtjjkrV| |tjj	 ||jj q2d S rt   )r   r@   r/   r   r   rr   r   r   rP  r   r"   rY   rR   r%   )r   
first_pairrs   seen_foundationsr   r   r   r%    s&   

zConnection._unfreeze_initialr   r   c                 G   s   t jd| | g|R   d S )Nz%s )r   infor   r   r   r   
__log_info  s   zConnection.__log_infoc                 C   r   )NzConnection(%s))r   r   r   r   r   r     r   zConnection.__repr__r   )r   ):r   r   r   __doc__r   r   boolrz   r   r   r;   r   r   listr
   r  r   r   r	  r  r  r#  r2  r)   r   r9  r   r<  r:  r?  r   rE  rr   r   rg   rO  rQ  rB   r&  r'  r^  rT  r   rP  r6  r  r  r
  r.  r   r   r}  r  r]  r%  r   r  r   r   r   r   r   r   X  s
   	

S
6

6

6

1=


Q


5




r   )Ar   r  r   r   	itertoolsloggingrw  r   r   re   	threadingcollections.abcr   typingr   r   r   r6    r   r   r	   r   r
   r   r   utilsr   	getLoggerr   r   r,  r*  ry  rv  countr   r   r+   r   r   r   r   MDnsProtocolr'   r*   r  rz   r3   r  r;   r?   r   r\   rp   r|   r   r   r   rr   DatagramProtocolrB   r   r   r   r   r   r   r   <module>   s    
	




'


!


$Z