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Zd dlmZmZmZmZmZ ee dƒr†e jZne jZG dd„ deƒZG dd„ deƒZG dd	„ d	eƒZdS )
é    N)ÚQUIC_MAX_DATAGRAMÚBaseQuicConnectionÚBaseQuicManagerÚBaseQuicStreamÚUnexpectedEOFÚPollSelectorc                       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 )ÚSyncQuicStreamc                    s&   t ƒ  ||¡ t ¡ | _t ¡ | _d S ©N)ÚsuperÚ__init__Ú	threadingÚ	ConditionÚ_wake_upÚLockÚ_lock)ÚselfÚ
connectionÚ	stream_id©Ú	__class__© ú4./venv/lib/python3.8/site-packages/dns/quic/_sync.pyr       s    
zSyncQuicStream.__init__c              	   C   sn   |   |¡}| j& | j |¡r,W 5 Q R £ d S || _W 5 Q R X | j | j |¡sXtjj	‚W 5 Q R X d| _q d S )Nr   )
Z_timeout_from_expirationr   Ú_bufferZhaveZ
_expectingr   ÚwaitÚdnsÚ	exceptionÚTimeout)r   ÚamountÚ
expirationÚtimeoutr   r   r   Úwait_for%   s    
zSyncQuicStream.wait_forNc              
   C   st   |   |¡}|  d|¡ | j t d| j d¡¡\}W 5 Q R X |  ||¡ | j | j |¡W  5 Q R £ S Q R X d S )Né   z!H)Z_expiration_from_timeoutr    r   ÚstructÚunpackr   Úget)r   r   r   Úsizer   r   r   Úreceive1   s    
 zSyncQuicStream.receiveFc                 C   s    |   |¡}| j | j||¡ d S r	   )Z_encapsulateÚ_connectionÚwriteZ
_stream_id)r   ÚdatagramÚis_endÚdatar   r   r   Úsend:   s    
zSyncQuicStream.sendc              	   C   s,   |   ||¡r(| j | j ¡  W 5 Q R X d S r	   )Z_common_add_inputr   Únotify)r   r+   r*   r   r   r   Ú
_add_input>   s    zSyncQuicStream._add_inputc              	   C   s   | j  |  ¡  W 5 Q R X d S r	   )r   Z_close©r   r   r   r   ÚcloseC   s    zSyncQuicStream.closec                 C   s   | S r	   r   r/   r   r   r   Ú	__enter__G   s    zSyncQuicStream.__enter__c              	   C   s(   |   ¡  | j | j ¡  W 5 Q R X dS ©NF)r0   r   r-   )r   Úexc_typeÚexc_valÚexc_tbr   r   r   Ú__exit__J   s    zSyncQuicStream.__exit__)N)F)Ú__name__Ú
__module__Ú__qualname__r   r    r&   r,   r.   r0   r1   r6   Ú__classcell__r   r   r   r   r      s   
	
r   c                       sl   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zddd„Zdd„ Z	ddd„Z
‡ fdd„Zdd„ Z‡  ZS )ÚSyncQuicConnectionc                    sÈ   t ƒ  ||||||¡ t | jtjd¡| _| jd k	rtz| j tj	 
| j| j¡¡ W n  tk
rr   | j ¡  ‚ Y nX | j | j¡ t ¡ \| _| _| j d¡ | j d¡ t ¡ | _d | _t ¡ | _d S )Nr   F)r
   r   ÚsocketZ_afZ
SOCK_DGRAMÚ_socketZ_sourceZbindr   ZinetZlow_level_address_tupleÚ	Exceptionr0   ÚconnectÚ_peerZ
socketpairÚ_send_wakeupÚ_receive_wakeupZsetblockingr   ÚEventÚ_handshake_completeÚ_worker_threadr   r   )r   r   ÚaddressÚportÚsourceÚsource_portZmanagerr   r   r   r   R   s"    
ÿ

zSyncQuicConnection.__init__c              	   C   sj   d}|dk rf|d7 }z| j  t¡}W n tk
r:   Y d S X | j | j || jt ¡ ¡ W 5 Q R X qd S )Nr   é
   é   )	r=   Úrecvr   ÚBlockingIOErrorr   r'   Zreceive_datagramr@   Útime)r   Úcountr)   r   r   r   Ú_reade   s    zSyncQuicConnection._readc                 C   s.   z| j  d¡ W q  tk
r&   Y d S X q d S )Né    )rB   rL   rM   r/   r   r   r   Ú_drain_wakeupp   s    z SyncQuicConnection._drain_wakeupc           	      C   s  zâtƒ }| | jtj| j	¡ | | j
tj| j¡ | jsà|  d¡\}}| |¡}|D ]\}}| ¡  qR| j  |  |¡ W 5 Q R X |  ¡  | j  | j t ¡ ¡}W 5 Q R X |D ].\}}z| j |¡ W q® tk
rÚ   Y q®X q®q0W 5 | j  d| _W 5 Q R X | j ¡  X d S )NTF)r   Ú_donerD   ÚsetÚ_selector_classÚregisterr=   Ú	selectorsZ
EVENT_READrP   rB   rR   Z_get_timer_valuesZselectr+   Z_handle_timerÚ_handle_eventsr'   Zdatagrams_to_sendrN   r,   rM   )	r   Zselr   ÚintervalÚitemsÚkeyÚ_Z	datagramsr)   r   r   r   Ú_workerw   s,    

zSyncQuicConnection._workerc              	   C   sú   | j  | j ¡ }W 5 Q R X |d kr(d S t|tjjjƒrn| j  | j 	|j
¡}W 5 Q R X |rô| |j|j¡ q t|tjjjƒrŠ| j ¡  q t|tjjjƒr´| j  d| _W 5 Q R X q t|tjjjƒr | j  | j 	|j
¡}W 5 Q R X |r | dd¡ q d S )NTó    )r   r'   Z
next_eventÚ
isinstanceÚaioquicZquicZeventsZStreamDataReceivedÚ_streamsr$   r   r.   r+   Z
end_streamZHandshakeCompletedrD   rT   ZConnectionTerminatedrS   ZStreamReset)r   ZeventÚstreamr   r   r   rX   ’   s&    z!SyncQuicConnection._handle_eventsFc              	   C   s2   | j  | j |||¡ W 5 Q R X | j d¡ d S )Nó   )r   r'   Zsend_stream_datarA   r,   )r   rb   r+   r*   r   r   r   r(   ¨   s    zSyncQuicConnection.writec                 C   s(   | j r
d S tj| jd| _| j ¡  d S )N)Útarget)Ú_closedr   ÚThreadr]   rE   Ústartr/   r   r   r   Úrun­   s    zSyncQuicConnection.runNc              	   C   sT   | j  |¡stjj‚| j0 | jr&t‚| j 	d¡}t
| |ƒ}|| j|< W 5 Q R X |S r2   )rD   r   r   r   r   r   rS   r   r'   Zget_next_available_stream_idr   ra   )r   r   r   rb   r   r   r   Úmake_stream³   s    
zSyncQuicConnection.make_streamc              	      s"   | j  tƒ  |¡ W 5 Q R X d S r	   )r   r
   Úclose_stream)r   r   r   r   r   rj   ¾   s    zSyncQuicConnection.close_streamc              	   C   sj   | j P | jrW 5 Q R £ d S | j | jd | jd ¡ d| _| j ¡  | j d¡ W 5 Q R X | j	 
¡  d S )Nr   rK   Trc   )r   re   Z_managerÚclosedr@   r'   r0   rA   r,   rE   Újoinr/   r   r   r   r0   Â   s    
zSyncQuicConnection.close)F)N)r7   r8   r9   r   rP   rR   r]   rX   r(   rh   ri   rj   r0   r:   r   r   r   r   r;   Q   s   

r;   c                       sX   e Zd Zdejdf‡ fdd„	Zddd„Z‡ fd	d
„Z‡ fdd„Zdd„ Z	dd„ Z
‡  ZS )ÚSyncQuicManagerNc                    s    t ƒ  ||t|¡ t ¡ | _d S r	   )r
   r   r;   r   r   r   )r   ÚconfZverify_modeZserver_namer   r   r   r   Î   s    zSyncQuicManager.__init__éU  r   Tc              
   C   sD   | j 4 |  |||||¡\}}|r*| ¡  |W  5 Q R £ S Q R X d S r	   )r   Z_connectrh   )r   rF   rG   rH   rI   Zwant_session_ticketr   rg   r   r   r   r?   Ò   s        ÿzSyncQuicManager.connectc              	      s$   | j  tƒ  ||¡ W 5 Q R X d S r	   )r   r
   rk   )r   rF   rG   r   r   r   rk   Ý   s    zSyncQuicManager.closedc              	      s&   | j  tƒ  |||¡ W 5 Q R X d S r	   )r   r
   Úsave_session_ticket)r   rF   rG   Zticketr   r   r   rp   á   s    z#SyncQuicManager.save_session_ticketc                 C   s   | S r	   r   r/   r   r   r   r1   å   s    zSyncQuicManager.__enter__c                 C   s$   t | j ¡ ƒ}|D ]}| ¡  qdS r2   )ÚlistZ_connectionsÚvaluesr0   )r   r3   r4   r5   Zconnectionsr   r   r   r   r6   è   s    
zSyncQuicManager.__exit__)ro   Nr   T)r7   r8   r9   ÚsslZCERT_REQUIREDr   r?   rk   rp   r1   r6   r:   r   r   r   r   rm   Í   s          ÿ
rm   )rW   r<   rs   r"   r   rN   Zaioquic.quic.configurationr`   Zaioquic.quic.connectionZaioquic.quic.eventsZdns.exceptionr   Zdns.inetZdns.quic._commonr   r   r   r   r   Úhasattrr   rU   ZSelectSelectorr   r;   rm   r   r   r   r   Ú<module>   s"   	
2|