o
    Òó·ikO  ã                   @  sê  d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	 ddl
mZmZ ddlmZmZmZmZmZ ddlmZmZ ddlmZmZ dd	lmZ dd
lmZmZ ddlm Z m!Z!m"Z"m#Z#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5 zddl6m7Z8 W n e9y›   dZ:Y nw e8Z:er¦ddl;m<Z< e ej=e"ej>iZ?ee&ej@ejAƒG dd„ dejBe1e,ƒƒZCe:durËeeCejDƒ G dd„ de-e.eCƒZEG dd„ deCƒZFG dd„ de+ƒZ*eejGƒG dd„ de1eƒƒZHdS )z
TCP support for IOCP reactor
é    )ÚannotationsN)ÚTYPE_CHECKINGÚOptionalÚUnion)ÚclassImplementsÚimplementer)ÚaddressÚdeferÚerrorÚ
interfacesÚmain)Ú	_LogOwnerÚisIPv6Address)ÚIPv4AddressÚIPv6Address)Ú	IProtocol)ÚabstractÚiocpsupport)ÚERROR_CONNECTION_REFUSEDÚERROR_IO_PENDINGÚERROR_NETWORK_UNREACHABLEÚSO_UPDATE_ACCEPT_CONTEXTÚSO_UPDATE_CONNECT_CONTEXT)ÚIReadWriteHandle)ÚProtocol)Ú	ConnectorÚ_AbortingMixinÚ_BaseBaseClientÚ_BaseTCPClientÚ_getsocknameÚ_resolveIPv6Ú_SocketCloser)ÚfailureÚlogÚreflect)ÚstartTLS)ÚIOCPReactorc                   @  sÊ   e Zd ZdZdZd/dd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZedurFd0dd „Zd!d"„ Zd#d$„ Zd/d%d&„Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ ZdS )1Ú
ConnectionzÞ
    @ivar TLS: C{False} to indicate the connection is in normal TCP mode,
        C{True} to indicate that TLS has been started and that operations must
        be routed through the L{TLSMemoryBIOProtocol} instance.
    FNc                 C  s&   t j | |¡ || _|j| _|| _d S ©N)r   Ú
FileHandleÚ__init__ÚsocketÚfilenoÚgetFileHandleÚprotocol)ÚselfÚsockÚprotoÚreactor© r3   úfC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/internet/iocpreactor/tcp.pyr*   F   s   
zConnection.__init__c                 C  ó   | j S r(   )r+   ©r/   r3   r3   r4   Ú	getHandleL   s   zConnection.getHandlec                 C  s@   t |tƒrnt |tƒrt|ƒ}ntdt|ƒ ƒ‚| j |¡ dS )z`
        @param rbuffer: Data received.
        @type rbuffer: L{bytes} or L{bytearray}
        z%data must be bytes or bytearray, not N)Ú
isinstanceÚbytesÚ	bytearrayÚ	TypeErrorÚtyper.   ÚdataReceived)r/   Zrbufferr3   r3   r4   r=   O   s   


zConnection.dataReceivedc                 C  s   t  |  ¡ ||¡S r(   )Ú_iocpÚrecvr-   )r/   ZbufflistÚevtr3   r3   r4   ÚreadFromHandle^   s   zConnection.readFromHandlec                 C  s(   t |ƒ}t |  ¡ |d| j…  ¡ |¡S )zŽ
        Send C{buff} to current file handle using C{_iocp.send}. The buffer
        sent is limited to a size of C{self.SEND_LIMIT}.
        r   N)Ú
memoryviewr>   Úsendr-   Z
SEND_LIMITÚtobytes)r/   Úbuffr@   Z	writeViewr3   r3   r4   ÚwriteToHandlea   s   ÿzConnection.writeToHandlec                 C  sx   z| j  d¡ W n	 ty   Y nw t | jd ¡}|r:z| ¡  W d S  ty9   t 	¡ }t
 ¡  |  |¡ Y d S w d S )Né   )r+   ÚshutdownÚOSErrorr   ÚIHalfCloseableProtocolr.   ZwriteConnectionLostÚBaseExceptionr"   ÚFailurer#   ÚerrÚconnectionLost)r/   ÚpÚfr3   r3   r4   Ú_closeWriteConnectionk   s   ÿýýz Connection._closeWriteConnectionc                 C  sZ   t  | jd ¡}|r&z| ¡  W d S  ty%   t ¡  |  t 	¡ ¡ Y d S w |  |¡ d S r(   )
r   rJ   r.   ÚreadConnectionLostrK   r#   rM   rN   r"   rL   )r/   ÚreasonrO   r3   r3   r4   rR   y   s   þzConnection.readConnectionLostc                 C  sX   | j rd S tj | |¡ |d u p| tj¡ }|  |¡ | j}| `| `	| `
| |¡ d S r(   )Údisconnectedr   r)   rN   Úcheckr
   ZConnectionAbortedÚ_closeSocketr.   r+   r-   )r/   rS   ZisCleanr.   r3   r3   r4   rN   „   s   
zConnection.connectionLostc                 C  r5   )zN
        Return the prefix to log with when I own the logging thread.
        N)Úlogstrr6   r3   r3   r4   Ú	logPrefix�   ó   zConnection.logPrefixc                 C  ó   t | j tjtj¡ƒS r(   )Úboolr+   Ú
getsockoptÚIPPROTO_TCPÚTCP_NODELAYr6   r3   r3   r4   ÚgetTcpNoDelay–   ó   zConnection.getTcpNoDelayc                 C  ó   | j  t jt j|¡ d S r(   )r+   Ú
setsockoptr]   r^   ©r/   Úenabledr3   r3   r4   ÚsetTcpNoDelay™   ó   zConnection.setTcpNoDelayc                 C  rZ   r(   )r[   r+   r\   Ú
SOL_SOCKETÚSO_KEEPALIVEr6   r3   r3   r4   ÚgetTcpKeepAliveœ   r`   zConnection.getTcpKeepAlivec                 C  ra   r(   )r+   rb   rg   rh   rc   r3   r3   r4   ÚsetTcpKeepAliveŸ   rf   zConnection.setTcpKeepAliveTc                 C  s   t | ||tjƒ dS )z9
            @see: L{ITLSTransport.startTLS}
            N)Ú	_startTLSr   r)   )r/   ZcontextFactoryÚnormalr3   r3   r4   r%   ¤   s   zConnection.startTLSc                 C  ó2   | j rdS | jr| j |¡ dS tj | |¡ dS )zò
        Write some data, either directly to the underlying handle or, if TLS
        has been started, to the L{TLSMemoryBIOProtocol} for it to encrypt and
        send.

        @see: L{twisted.internet.interfaces.ITransport.write}
        N)rT   ÚTLSr.   Úwriter   r)   )r/   Údatar3   r3   r4   ro   ª   ó
   zConnection.writec                 C  rm   )zú
        Write some data, either directly to the underlying handle or, if TLS
        has been started, to the L{TLSMemoryBIOProtocol} for it to encrypt and
        send.

        @see: L{twisted.internet.interfaces.ITransport.writeSequence}
        N)rT   rn   r.   ÚwriteSequencer   r)   )r/   Ziovecr3   r3   r4   rr   ¹   rq   zConnection.writeSequencec                 C  s:   | j r| jr| js| j ¡  dS dS dS tj | |¡ dS )z®
        Close the underlying handle or, if TLS has been started, first shut it
        down.

        @see: L{twisted.internet.interfaces.ITransport.loseConnection}
        N)rn   Ú	connectedÚdisconnectingr.   ÚloseConnectionr   r)   )r/   rS   r3   r3   r4   ru   È   s
   ÿzConnection.loseConnectionc                 C  s,   | j r| j ||¡ dS tj | ||¡ dS )zc
        Register a producer.

        If TLS is enabled, the TLS connection handles this.
        N)rn   r.   ÚregisterProducerr   r)   )r/   ZproducerZ	streamingr3   r3   r4   rv   Õ   s   zConnection.registerProducerc                 C  s$   | j r
| j ¡  dS tj | ¡ dS )ze
        Unregister a producer.

        If TLS is enabled, the TLS connection handles this.
        N)rn   r.   ÚunregisterProducerr   r)   r6   r3   r3   r4   rw   ä   s   zConnection.unregisterProducerc                 C  ó   d S r(   r3   r6   r3   r3   r4   ÚgetHostï   ó   zConnection.getHostc                 C  rx   r(   r3   r6   r3   r3   r4   ÚgetPeeró   rz   zConnection.getPeerr(   )T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rn   r*   r7   r=   rA   rF   rQ   rR   rN   rX   r_   re   ri   rj   rk   r%   ro   rr   ru   rv   rw   ry   r{   r3   r3   r3   r4   r'   <   s2    



r'   c                   @  sT   e Zd ZdZejZejZdZ	e
Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ ZdS )ÚClientzº
    @ivar _tlsClientDefault: Always C{True}, indicating that this is a client
        connection, and by default when TLS is negotiated this class will act as
        a TLS client.
    Tc                 C  s*   |d u rd}|| _ t | |||||¡ d S )N)Ú r   )r2   r   r*   )r/   ÚhostÚportÚbindAddressÚ	connectorr2   r3   r3   r4   r*   	  s   zClient.__init__c                 C  s   | j  | j| j¡S )zd
        Create a socket registered with the IOCP reactor.

        @see: L{_BaseTCPClient}
        N)r2   ÚcreateSocketÚaddressFamilyÚ
socketTyper6   r3   r3   r4   ÚcreateInternetSocket  s   zClient.createInternetSocketc                 C  s   | ` | `dS )z–
        Clean up potentially circular references to the socket and to its
        C{getFileHandle} method.

        @see: L{_BaseBaseClient}
        N)r+   r-   r6   r3   r3   r4   Ú_collectSocketDetails  s   zClient._collectSocketDetailsc                 C  s   | j  | ¡ dS )z^
        Remove the active handle from the reactor.

        @see: L{_BaseBaseClient}
        N)r2   ÚremoveActiveHandler6   r3   r3   r4   Ú_stopReadingAndWriting!  s   zClient._stopReadingAndWritingc              	   C  s¶   |rt  ||¡}|  t |tj |d¡f¡¡ d S | j tj	t
t d| j ¡ ¡¡ | j |  ¡ ¡| _d| _|  | j¡}|d | _| jd u rOtƒ | _|  ¡  d S | j | ¡ |  ¡  d S )NzUnknown errorÚPTz,client)ÚconnectExErrorsÚgetZfailIfNotConnectedr
   ZgetConnectErrorÚerrnoÚ	errorcoder+   rb   rg   r   ÚstructÚpackr,   r…   ÚbuildProtocolr{   r.   rs   Ú_getLogPrefixrW   r   ru   ÚmakeConnectionÚstartReading)r/   Úrcrp   r@   rX   r3   r3   r4   Ú	cbConnect)  s&   ÿý

zClient.cbConnectc                 C  sn   t | dƒsd S tjsJ ‚| j | ¡ t | j| ¡}t | j 	¡ | j
|¡}|r3|tkr5|  |d|¡ d S d S d S )Nr…   r   )Úhasattrr>   Zhave_connectexr2   ÚaddActiveHandleÚEventr™   Úconnectr+   r,   ZrealAddressr   )r/   r@   r˜   r3   r3   r4   Ú	doConnectG  s   

ÿzClient.doConnectN)r|   r}   r~   r   r+   ÚAF_INETr‡   ÚSOCK_STREAMrˆ   Ú_tlsClientDefaultr'   Z_commonConnectionr*   r‰   rŠ   rŒ   r™   rž   r3   r3   r3   r4   r€   ü   s    	r€   c                   @  s8   e Zd ZdZdZddd„Zddd„Zdd„ Zdd„ ZdS )ÚServeraV  
    Serverside socket-stream connection class.

    I am a serverside network connection transport; a socket which came from an
    accept() on a server.

    @ivar _tlsClientDefault: Always C{False}, indicating that this is a server
        connection, and by default when TLS is negotiated this class will act as
        a TLS server.
    Fr0   úsocket.socketr.   r   Ú
clientAddrúUnion[IPv4Address, IPv6Address]Ú
serverAddrÚ	sessionnoÚintr2   r&   c                 C  sv   t  | |||¡ || _|| _|| _|  | j¡}|› d|› d| jj› �| _d 	| jj
j| j| jj¡| _d| _|  ¡  dS )a  
        Server(sock, protocol, client, server, sessionno)

        Initialize me with a socket, a protocol, a descriptor for my peer (a
        tuple of host, port describing the other end of the connection), an
        instance of Port, and a session number.
        ú,z<{} #{} on {}>TN)r'   r*   r¦   r¤   r§   r•   r.   r‚   rW   ÚformatÚ	__class__r|   rƒ   Úrepstrrs   r—   )r/   r0   r.   r¤   r¦   r§   r2   rX   r3   r3   r4   r*   c  s   ýzServer.__init__ÚreturnÚstrc                 C  r5   )z=
        A string representation of this connection.
        N)r¬   r6   r3   r3   r4   Ú__repr__�  rY   zServer.__repr__c                 C  r5   )zW
        Returns an IPv4Address.

        This indicates the server's address.
        N)r¦   r6   r3   r3   r4   ry   ‡  ó   zServer.getHostc                 C  r5   )zW
        Returns an IPv4Address.

        This indicates the client's address.
        N)r¤   r6   r3   r3   r4   r{   �  r°   zServer.getPeerN)r0   r£   r.   r   r¤   r¥   r¦   r¥   r§   r¨   r2   r&   ©r­   r®   )	r|   r}   r~   r   r¡   r*   r¯   ry   r{   r3   r3   r3   r4   r¢   U  s    

r¢   c                   @  s   e Zd Zdd„ ZdS )r   c                 C  s   t | j| j| j| | jƒS r(   )r€   r‚   rƒ   r„   r2   r6   r3   r3   r4   Ú_makeTransport™  rf   zConnector._makeTransportN)r|   r}   r~   r²   r3   r3   r3   r4   r   ˜  s    r   c                   @  s¬   e Zd ZU dZdZdZejZej	Z
ejZdZdZded< dZd!d	d
„Zd"dd„Zdd„ Ze ej¡fdd„ZeZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z dd „ Z!dS )#ÚPortFr   NzOptional[int]Ú_realPortNumberÚTCPé2   r�   c                 C  s>   || _ || _|| _|| _|| _t|ƒrtj| _t	j
| _d S d S r(   )rƒ   ÚfactoryÚbacklogÚ	interfacer2   r   r+   ÚAF_INET6r‡   r   r   Ú_addressType)r/   rƒ   r·   r¸   r¹   r2   r3   r3   r4   r*   ±  s   þzPort.__init__r­   r®   c                 C  s2   | j d urd | j| jj| j ¡S d | j| jj¡S )Nz<{} of {} on {}>z<{} of {} (not listening)>)r´   rª   r«   r·   r6   r3   r3   r4   r¯   »  s   
ýþzPort.__repr__c              
   C  sø   z$| j  | j| j¡}| jtjkrt| j| jƒ}n| j| jf}| 	|¡ W n t
y9 } z	t | j| j|¡‚d }~ww t | ¡ ¡| _| ¡ d | _t d|  | j¡| jf ¡ | j ¡  | | j¡ d| _d| _| j  | ¡ || _| jj| _|  ¡  d S )NrG   z%s starting on %sTF)r2   r†   r‡   rˆ   r+   rº   r    r¹   rƒ   ÚbindrI   r
   ZCannotListenErrorr>   Z
maxAddrLenr,   ÚaddrLenÚgetsocknamer´   r#   Úmsgr•   r·   ZdoStartÚlistenr¸   rs   rT   r›   r-   ÚdoAccept)r/   ZsktÚaddrÚler3   r3   r4   ÚstartListeningÈ  s2   €ÿÿÿ

zPort.startListeningc                 C  s2   d| _ | jrt ¡ | _| j d| j|¡ | jS dS )zæ
        Stop accepting connections on this port.

        This will shut down my socket and call self.connectionLost().
        It returns a deferred which will fire successfully when the
        port is actually closed.
        Tr   N)rt   rs   r	   ZDeferredÚdeferredr2   Z	callLaterrN   )r/   ZconnDoner3   r3   r4   ru   è  s   
ýzPort.loseConnectionc                 C  s    t  d| j› d| j› d�¡ dS )z.
        Log message for closing port
        ú(z Port z Closed)N)r#   r¿   Ú_typer´   r6   r3   r3   r4   Ú_logConnectionLostMsgø  s    zPort._logConnectionLostMsgc                 C  s²   |   ¡  d| _d}t| dƒr| j}| `d| _| j | ¡ d| _|  d¡ | `	| `
z| j ¡  W n tyH   d| _|durG| t ¡ ¡ Y dS ‚ w d| _|durW| d¡ dS dS )z'
        Cleans up the socket.
        NrÅ   TF)rÈ   r´   rš   rÅ   rT   r2   r‹   rs   rV   r+   r-   r·   ZdoStoprK   rt   Zerrbackr"   rL   Úcallback)r/   rS   Údr3   r3   r4   rN   þ  s0   

ûÿzPort.connectionLostc                 C  s   t  | jj¡S )zK
        Returns the name of my class, to prefix log entries with.
        N)r$   Zqualr·   r«   r6   r3   r3   r4   rX     s   zPort.logPrefixc                 C  s   | j dgt| jƒ¢R Ž S )zf
        Returns an IPv4Address or IPv6Address.

        This indicates the server's address.
        rµ   N)r»   r   r+   r6   r3   r3   r4   ry   #  s   zPort.getHostc                 C  s,   |   ||¡ | js| js|  ¡  d S d S d S r(   )ÚhandleAcceptrt   rT   rÁ   )r/   r˜   rp   r@   r3   r3   r4   ÚcbAccept+  s   ÿzPort.cbAcceptc           
   	   C  sh  | j s| jrdS |rt dtj |d¡|f ¡ dS |j t	j
tt d| j	 ¡ ¡¡ t |j ¡ |j¡\}}}|| jks>J ‚d|d v rYt|d  d¡d ƒ}|d |d d|f}d|d v rtt|d  d¡d ƒ}|d |d d|f}| j | jdg|¢R Ž ¡}|d u rŒ|j ¡  d	S | j}|d | _t|j|| jdg|¢R Ž | jdg|¢R Ž || jƒ}	| |	¡ d	S )
NFz*Could not accept new connection -- %s (%s)zunknown errorr�   ú%r   rG   rµ   T)rt   rT   r#   r¿   r�   r‘   r�   Únewsktrb   r+   rg   r   r’   r“   r,   r>   Zget_accept_addrsrE   r‡   r¨   Úsplitr·   r”   r»   Úcloser§   r¢   r2   r–   )
r/   r˜   r@   ÚfamilyZlAddrZrAddrZscoper.   ÚsÚ	transportr3   r3   r4   rË   0  sL   ÿÿý
õ
ú
zPort.handleAcceptc                 C  s|   t  | j| ¡}td| jd  ƒ |_}| j | j| j	¡ |_
}t  | j ¡ | ¡ ||¡}|r:|tkr<|  ||¡ d S d S d S )Né   é   )r>   rœ   rÌ   r:   r½   rE   r2   r†   r‡   rˆ   rÎ   Úacceptr+   r,   r   rË   )r/   r@   rE   rÎ   r˜   r3   r3   r4   rÁ   c  s   
ÿÿzPort.doAccept)r¶   r�   Nr±   )"r|   r}   r~   rs   rT   rt   r+   rŸ   r‡   r    rˆ   r   r   r»   r§   r´   Ú__annotations__rÇ   r*   r¯   rÄ   r"   rL   r   ZCONNECTION_DONEru   ÚstopListeningrÈ   rN   rX   ry   rÌ   rË   rÁ   r3   r3   r3   r4   r³   �  s,   
 


 3r³   )Ir   Ú
__future__r   r�   r+   r’   Útypingr   r   r   Zzope.interfacer   r   Ztwisted.internetr   r	   r
   r   r   Ztwisted.internet.abstractr   r   Ztwisted.internet.addressr   r   Ztwisted.internet.interfacesr   Ztwisted.internet.iocpreactorr   r   r>   Z"twisted.internet.iocpreactor.constr   r   r   r   r   Z'twisted.internet.iocpreactor.interfacesr   Ztwisted.internet.protocolr   Ztwisted.internet.tcpr   ZTCPConnectorr   r   r   r   r    r!   Ztwisted.pythonr"   r#   r$   Ztwisted.internet._newtlsr%   Z
__startTLSÚImportErrorrk   Z$twisted.internet.iocpreactor.reactorr&   ZWSAECONNREFUSEDZWSAENETUNREACHrŽ   ZITCPTransportZISystemHandler)   r'   ZITLSTransportr€   r¢   ZIListeningPortr³   r3   r3   r3   r4   Ú<module>   sL   $	ÿþ <YC