U
    ©¹Öhö  ã                   @   s¬   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mZmZ G dd„ deƒZG dd„ deƒZG dd	„ d	eƒZdS )
é    N)ÚNullContext)ÚQUIC_MAX_DATAGRAMÚAsyncQuicConnectionÚAsyncQuicManagerÚBaseQuicStreamÚUnexpectedEOFc                       sX   e Zd Z‡ fdd„Zdd„ Zddd„Zdd	d
„Zdd„ Zdd„ Zdd„ Z	dd„ Z
‡  ZS )ÚTrioQuicStreamc                    s   t ƒ  ||¡ t ¡ | _d S ©N)ÚsuperÚ__init__ÚtrioÚ	ConditionÚ_wake_up)ÚselfÚ
connectionÚ	stream_id©Ú	__class__© ú4./venv/lib/python3.8/site-packages/dns/quic/_trio.pyr      s    zTrioQuicStream.__init__c              
   Ã   sR   | j  |¡rd S || _| j4 I d H š | j ¡ I d H  W 5 Q I d H R X d| _q d S )Nr   )Ú_bufferZhaveZ
_expectingr   Úwait)r   Úamountr   r   r   Úwait_for   s     zTrioQuicStream.wait_forNc              
   Ã   s‚   |d krt d ƒ}n
t |¡}|P |  d¡I d H  t d| j d¡¡\}|  |¡I d H  | j |¡W  5 Q R £ S Q R X tj	j
‚d S )Né   z!H)r   r   Úmove_on_afterr   ÚstructÚunpackr   ÚgetÚdnsÚ	exceptionÚTimeout)r   ÚtimeoutÚcontextÚsizer   r   r   Úreceive'   s    

zTrioQuicStream.receiveFc                 Ã   s&   |   |¡}| j | j||¡I d H  d S r	   )Z_encapsulateÚ_connectionÚwriteZ
_stream_id)r   ÚdatagramÚis_endÚdatar   r   r   Úsend3   s    
zTrioQuicStream.sendc              
   Ã   s:   |   ||¡r6| j4 I d H š | j ¡  W 5 Q I d H R X d S r	   )Z_common_add_inputr   Únotify)r   r*   r)   r   r   r   Ú
_add_input7   s    zTrioQuicStream._add_inputc                 Ã   s   |   ¡  d S r	   )Z_close©r   r   r   r   Úclose<   s    zTrioQuicStream.closec                 Ã   s   | S r	   r   r.   r   r   r   Ú
__aenter__A   s    zTrioQuicStream.__aenter__c              
   Ã   s<   |   ¡ I d H  | j4 I d H š | j ¡  W 5 Q I d H R X dS ©NF)r/   r   r,   )r   Úexc_typeÚexc_valÚexc_tbr   r   r   Ú	__aexit__D   s    zTrioQuicStream.__aexit__)N)F)Ú__name__Ú
__module__Ú__qualname__r   r   r%   r+   r-   r/   r0   r5   Ú__classcell__r   r   r   r   r      s   	

r   c                       sR   e Zd Zd‡ fdd„	Zdd„ Zdd„ Zdd	d
„Zdd„ Zddd„Zdd„ Z	‡  Z
S )ÚTrioQuicConnectionNc                    sP   t ƒ  ||||||¡ tj | jtjd¡| _t ¡ | _t ¡ | _	d | _
d| _d S )Nr   F)r
   r   r   ÚsocketÚ_afZ
SOCK_DGRAMÚ_socketÚEventÚ_handshake_completeÚ	_run_doneÚ_worker_scopeÚ_send_pending)r   r   ÚaddressÚportÚsourceÚsource_portZmanagerr   r   r   r   L   s    

zTrioQuicConnection.__init__c              	   Ã   s  zü| jr(| j tj | j| j	¡¡I d H  | j 
| j¡I d H  | j sú|  d¡\}}| jrZd}tjt ¡ | d0| _| j t¡I d H }| j || jt ¡ ¡ W 5 Q R X d | _|  |¡ |  ¡ I d H  d| _| j t ¡ ¡}|D ]\}}| j |¡I d H  qÜq<W 5 d| _ | j ¡  X d S )NTFg        )Zdeadline)Ú_doner?   ÚsetZ_sourcer=   Zbindr   ZinetZlow_level_address_tupler<   ÚconnectÚ_peerZ_get_timer_valuesrB   r   ZCancelScopeZcurrent_timerA   Zrecvr   r&   Zreceive_datagramÚtimeZ_handle_timerÚ_handle_eventsZdatagrams_to_sendr+   )r   Z
expirationÚintervalr(   Z	datagramsÚ_r   r   r   Ú_workerT   s2    ÿ

ÿ 
zTrioQuicConnection._workerc                 Ã   sð   d}| j  ¡ }|d krd S t|tjjjƒrT| j |j	¡}|rÆ| 
|j|j¡I d H  nrt|tjjjƒrp| j ¡  nVt|tjjjƒr’d| _| j ¡  n4t|tjjjƒrÆ| j |j	¡}|rÆ| 
dd¡I d H  |d7 }|dkrd}t d¡I d H  qd S )Nr   Tó    é   é
   )r&   Z
next_eventÚ
isinstanceÚaioquicZquicZeventsZStreamDataReceivedÚ_streamsr   r   r-   r*   Z
end_streamZHandshakeCompletedr?   rH   ZConnectionTerminatedrG   r=   r/   ZStreamResetr   Úsleep)r   ÚcountZeventÚstreamr   r   r   rL   x   s*    
z!TrioQuicConnection._handle_eventsFc                 Ã   s.   | j  |||¡ d| _| jd k	r*| j ¡  d S )NT)r&   Zsend_stream_datarB   rA   Úcancel)r   rX   r*   r)   r   r   r   r'   ‘   s    
zTrioQuicConnection.writec              
   Ã   sF   | j r
d S t ¡ 4 I d H š}| | j¡ W 5 Q I d H R X | j ¡  d S r	   )Ú_closedr   Zopen_nurseryÚ
start_soonrO   r@   rH   )r   Únurseryr   r   r   Úrun—   s
    zTrioQuicConnection.runc              
   Ã   s~   |d krt d ƒ}n
t |¡}|L | j ¡ I d H  | jr<t‚| j d¡}t	| |ƒ}|| j
|< |W  5 Q R £ S Q R X tjj‚d S r1   )r   r   r   r?   r   rG   r   r&   Zget_next_available_stream_idr   rU   r   r    r!   )r   r"   r#   r   rX   r   r   r   Úmake_streamž   s    



zTrioQuicConnection.make_streamc                 Ã   s^   | j sZ| j | jd | jd ¡ d| _ | j ¡  d| _| jd k	rJ| j ¡  | j	 
¡ I d H  d S )Nr   rQ   T)rZ   Z_managerÚclosedrJ   r&   r/   rB   rA   rY   r@   r   r.   r   r   r   r/   ­   s    


zTrioQuicConnection.close)N)F)N)r6   r7   r8   r   rO   rL   r'   r]   r^   r/   r9   r   r   r   r   r:   K   s   $

r:   c                       s@   e Zd Zdejdf‡ fdd„	Zddd„Zd	d
„ Zdd„ Z‡  Z	S )ÚTrioQuicManagerNc                    s   t ƒ  ||t|¡ || _d S r	   )r
   r   r:   Ú_nursery)r   r\   ÚconfZverify_modeZserver_namer   r   r   r   ¹   s    zTrioQuicManager.__init__éU  r   Tc                 C   s,   |   |||||¡\}}|r(| j |j¡ |S r	   )Z_connectra   r[   r]   )r   rC   rD   rE   rF   Zwant_session_ticketr   Ústartr   r   r   rI   ¿   s        ÿzTrioQuicManager.connectc                 Ã   s   | S r	   r   r.   r   r   r   r0   É   s    zTrioQuicManager.__aenter__c                 Ã   s*   t | j ¡ ƒ}|D ]}| ¡ I d H  qdS r1   )ÚlistZ_connectionsÚvaluesr/   )r   r2   r3   r4   Zconnectionsr   r   r   r   r5   Ì   s    zTrioQuicManager.__aexit__)rc   Nr   T)
r6   r7   r8   ÚsslZCERT_REQUIREDr   rI   r0   r5   r9   r   r   r   r   r`   ¸   s     ÿ       ÿ

r`   )r;   rg   r   rK   Zaioquic.quic.configurationrT   Zaioquic.quic.connectionZaioquic.quic.eventsr   Zdns.exceptionr   Zdns.inetZdns._asyncbackendr   Zdns.quic._commonr   r   r   r   r   r   r:   r`   r   r   r   r   Ú<module>   s   	2m