
    \eM                     `   d 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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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&m'Z'm(Z( ddl)m*Z*m+Z+m,Z, 	 ddl-m.Z/ e/Z0n# e1$ r dZ0Y nw xY weej2        eej3        iZ4 eeej5        ej6                   G d dej7        e(e#                      Z8e0 ee8ej9                    G d de$e%e8          Z: G d de8          Z; G d de"          Z! eej<                   G d de(e                      Z=dS )z
TCP support for IOCP reactor
    N)Optional)classImplementsimplementer)addressdefererror
interfacesmain)	_LogOwnerisIPv6Address)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)startTLSc                       e Zd ZdZdZddZd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd Zd ZeddZd Zd ZddZd Zd Zd Zd ZdS )
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                 z    t           j                            | |           || _        |j        | _        || _        d S N)r   
FileHandle__init__socketfilenogetFileHandleprotocol)selfsockprotoreactors       @lib/python3.11/site-packages/twisted/internet/iocpreactor/tcp.pyr&   zConnection.__init__?   s7    $$T7333![    c                     | j         S r$   )r'   r+   s    r/   	getHandlezConnection.getHandleE   s
    {r0   c                     t          |t                    rnDt          |t                    rt          |          }nt          dt	          |          z             | 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+   rbuffers     r/   r:   zConnection.dataReceivedH   sp    
 gu%% 	U++ 	UGnnGGCd7mmSTTT""7+++++r0   c                 R    t          j        |                                 ||          S r$   )_iocprecvr)   )r+   bufflistevts      r/   readFromHandlezConnection.readFromHandleW   s"    z$,,..#>>>r0   c                     t          |          }t          j        |                                 |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   )
memoryviewr=   sendr)   
SEND_LIMITtobytes)r+   buffr@   	writeViews       r/   writeToHandlezConnection.writeToHandleZ   sP    
 t$$	z  )A,?"@"H"H"J"JC
 
 	
r0   c                 \   	 | j                             d           n# t          $ r Y nw xY wt          j        | j        d           }|rc	 |                                 d S # t          $ r? t          j	                    }t          j                     |                     |           Y d S w xY wd S )N   )r'   shutdownOSErrorr	   IHalfCloseableProtocolr*   writeConnectionLostBaseExceptionr   Failurer   errconnectionLost)r+   pfs      r/   _closeWriteConnectionz Connection._closeWriteConnectiond   s    	K  #### 	 	 	D	-dmTBB 	''%%'''''  ' ' 'O%%			##A&&&&&&'	' 	's    
**
A   AB)(B)c                 *   t          j        | j        d           }|ra	 |                                 d S # t          $ r= t          j                     |                     t          j	                               Y d S w xY w|                     |           d S r$   )
r	   rN   r*   readConnectionLostrP   r   rR   rS   r   rQ   )r+   reasonrT   s      r/   rX   zConnection.readConnectionLostr   s    -dmTBB 	(7$$&&&&&  7 7 7			##GO$5$56666667 '''''s   4 AA;:A;c                    | j         rd S t          j                            | |           |d u p|                    t
          j                   }|                     |           | j        }| `| `	| `
|                    |           d S r$   )disconnectedr   r%   rS   checkr   ConnectionAborted_closeSocketr*   r'   r)   )r+   rY   isCleanr*   s       r/   rS   zConnection.connectionLost}   s     	F**4888D.MU5L(M(M$M'"""=MK'''''r0   c                     | j         S )zN
        Return the prefix to log with when I own the logging thread.
        )logstrr2   s    r/   	logPrefixzConnection.logPrefix        {r0   c                 z    t          | j                            t          j        t          j                            S r$   )boolr'   
getsockoptIPPROTO_TCPTCP_NODELAYr2   s    r/   getTcpNoDelayzConnection.getTcpNoDelay   s(    DK**6+=v?QRRSSSr0   c                 f    | j                             t           j        t           j        |           d S r$   )r'   
setsockoptrg   rh   r+   enableds     r/   setTcpNoDelayzConnection.setTcpNoDelay   s(    v163EwOOOOOr0   c                 z    t          | j                            t          j        t          j                            S r$   )re   r'   rf   
SOL_SOCKETSO_KEEPALIVEr2   s    r/   getTcpKeepAlivezConnection.getTcpKeepAlive   s(    DK**6+<f>QRRSSSr0   c                 f    | j                             t           j        t           j        |           d S r$   )r'   rk   rp   rq   rl   s     r/   setTcpKeepAlivezConnection.setTcpKeepAlive   s(    v0&2EwOOOOOr0   Tc                 >    t          | ||t          j                   dS )z9
            @see: L{ITLSTransport.startTLS}
            N)	_startTLSr   r%   )r+   contextFactorynormals      r/   r    zConnection.startTLS   s!     dNFH4GHHHHHr0   c                     | 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)r[   TLSr*   writer   r%   )r+   datas     r/   r{   zConnection.write   sY      	F8 	2M%%%%%%%dD11111r0   c                     | 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.writeSequence}
        N)r[   rz   r*   writeSequencer   r%   )r+   iovecs     r/   r~   zConnection.writeSequence   sY      	F8 	;M''.....--dE:::::r0   c                     | 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)rz   	connecteddisconnectingr*   loseConnectionr   r%   )r+   rY   s     r/   r   zConnection.loseConnection   sq     8 	=~ /d&8 /,,...../ / / / ..tV<<<<<r0   c                     | j         r| j                            ||           dS t          j                            | ||           dS )zc
        Register a producer.

        If TLS is enabled, the TLS connection handles this.
        N)rz   r*   registerProducerr   r%   )r+   producer	streamings      r/   r   zConnection.registerProducer   sP     8 	L
 M**8Y?????00xKKKKKr0   c                     | j         r| j                                         dS t          j                            |            dS )ze
        Unregister a producer.

        If TLS is enabled, the TLS connection handles this.
        N)rz   r*   unregisterProducerr   r%   r2   s    r/   r   zConnection.unregisterProducer   sE     8 	9M,,.....22488888r0   c                     d S r$    r2   s    r/   getHostzConnection.getHost       r0   c                     d S r$   r   r2   s    r/   getPeerzConnection.getPeer   r   r0   r$   )T)__name__
__module____qualname____doc__rz   r&   r3   r:   rA   rI   rV   rX   rS   rb   ri   rn   rr   rt   rv   r    r{   r~   r   r   r   r   r   r   r0   r/   r"   r"   5   s         C     , , ,? ? ?
 
 
' ' '	( 	( 	(
( 
( 
(  T T TP P PT T TP P P 	I 	I 	I 	I2 2 2; ; ;= = = =L L L	9 	9 	9      r0   r"   c                   Z    e Zd ZdZej        Zej        ZdZ	e
Zd Zd Zd Zd Zd Z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                 N    |d}|| _         t          j        | |||||           d S )N) r   )r.   r   r&   )r+   hostportbindAddress	connectorr.   s         r/   r&   zClient.__init__  s5    !KdD+y'RRRRRr0   c                 L    | j                             | j        | j                  S )zd
        Create a socket registered with the IOCP reactor.

        @see: L{_BaseTCPClient}
        )r.   createSocketaddressFamily
socketTyper2   s    r/   createInternetSocketzClient.createInternetSocket	  s!     |(();T_MMMr0   c                     | ` | `dS )z
        Clean up potentially circular references to the socket and to its
        C{getFileHandle} method.

        @see: L{_BaseBaseClient}
        N)r'   r)   r2   s    r/   _collectSocketDetailszClient._collectSocketDetails  s     K+++r0   c                 :    | j                             |            dS )z^
        Remove the active handle from the reactor.

        @see: L{_BaseBaseClient}
        N)r.   removeActiveHandler2   s    r/   _stopReadingAndWritingzClient._stopReadingAndWriting  s      	''-----r0   c           	         |rdt                               ||          }|                     t          j        |t
          j                            |d          f                     d S | j                            t          j	        t          t          j        d| j                                                             | j                            |                                           | _        d| _        |                     | j                  }|dz   | _        | j        )t+                      | _        |                                  d S | j                            |            |                                  d S )NzUnknown errorPTz,client)connectExErrorsgetfailIfNotConnectedr   getConnectErrorerrno	errorcoder'   rk   rp   r   structpackr(   r   buildProtocolr   r*   r   _getLogPrefixra   r   r   makeConnectionstartReading)r+   rcr|   r@   rb   s        r/   	cbConnectzClient.cbConnect"  sL    	$ $$R,,B##%r5?+>+>r?+S+S&TUU     K""!)C!3!3!5!566  
 !N88HHDM!DN**4=99I#i/DK}$ !)

##%%%%%,,T222!!#####r0   c                 b   t          | d          sd S t          j        sJ | j                            |            t          j        | j        |           }t          j        | j        	                                | j
        |          }|r$|t          k    r|                     |d|           d S d S d S )Nr   r   )hasattrr=   have_connectexr.   addActiveHandleEventr   connectr'   r(   realAddressr   )r+   r@   r   s      r/   	doConnectzClient.doConnect@  s    t[)) 	 F####$$T***k$.$//]4;--//1A3GG 	'"(((NN2q#&&&&&	' 	'((r0   N)r   r   r   r   r'   AF_INETr   SOCK_STREAMr   _tlsClientDefaultr"   _commonConnectionr&   r   r   r   r   r   r   r0   r/   r   r      s          NM#J"S S SN N N, , ,. . .$ $ $<' ' ' ' 'r0   r   c                   4    e Zd ZdZdZd ZdefdZd Z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.
    Fc                 z   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&   
serverAddr
clientAddr	sessionnor   r*   r   ra   format	__class__r   r   repstrr   r   )r+   r,   r*   r   r   r   r.   rb   s           r/   r&   zServer.__init__\  s     	D$':::$$"&&t}55	"GGYGG1EGG+22M#,NO 
 

 r0   returnc                     | j         S )z=
        A string representation of this connection.
        )r   r2   s    r/   __repr__zServer.__repr__r  rc   r0   c                     | j         S )zW
        Returns an IPv4Address.

        This indicates the server's address.
        )r   r2   s    r/   r   zServer.getHostx       r0   c                     | j         S )zW
        Returns an IPv4Address.

        This indicates the client's address.
        )r   r2   s    r/   r   zServer.getPeer  r   r0   N)
r   r   r   r   r   r&   strr   r   r   r   r0   r/   r   r   N  sn        	 	   ,#          r0   r   c                       e Zd Zd ZdS )r   c                 P    t          | j        | j        | j        | | j                  S r$   )r   r   r   r   r.   r2   s    r/   _makeTransportzConnector._makeTransport  s!    diD,<dDLQQQr0   N)r   r   r   r   r   r0   r/   r   r     s(        R R R R Rr0   r   c                       e Zd ZU dZdZdZej        Zej	        Z
ej        ZdZdZee         ed<   dZddZd	efd
Zd Z ej        ej                  fdZeZd Zd Zd Z d Z!d Z"d Z#d Z$dS )PortFr   N_realPortNumberTCP2   r   c                     || _         || _        || _        || _        || _        t          |          r$t          j        | _        t          j
        | _        d S d S r$   )r   factorybacklog	interfacer.   r   r'   AF_INET6r   r   IPv6Address_addressType)r+   r   r   r   r   r.   s         r/   r&   zPort.__init__  sZ    	"## 	4!'D ' 3D	4 	4r0   r   c                     | j         +d                    | j        | j        j        | j                   S d                    | j        | j        j                  S )Nz<{} of {} on {}>z<{} of {} (not listening)>)r   r   r   r   r2   s    r/   r   zPort.__repr__  s]    +%,,&$   066&  r0   c                 l   	 | j                             | j        | j                  }| j        t          j        k    rt          | j        | j                  }n| j        | j        f}|	                    |           n2# t          $ r%}t          j        | j        | j        |          d }~ww xY wt          j        |                                          | _        |                                d         | _        t'          j        |                     | j                  d| j                   | j                                         |                    | j                   d| _        d| _        | j                             |            || _        | j        j        | _        |                                  d S )NrK   z starting on TF)r.   r   r   r   r'   r   r   r   r   bindrM   r   CannotListenErrorr=   
maxAddrLenr(   addrLengetsocknamer   r   msgr   r   doStartlistenr   r   r[   r   r)   doAccept)r+   sktaddrles       r/   startListeningzPort.startListening  s   		I,++D,>PPC!V_44#DNDI>>	2HHTNNNN 	I 	I 	I)$.$)RHHH	I '

55  #003!!$,////1E1EG	
 	
 	

 	

4<   !$$T***![/s   A8A; ;
B* B%%B*c                     d| _         | j        r@t          j                    | _        | 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)r   r   r   Deferreddeferredr.   	callLaterrS   )r+   connDones     r/   r   zPort.loseConnection  sT     "> 	!!N,,DML""1d&98DDD= 	! 	!r0   c                 P    t          j        d| j         d| j         d           dS )z.
        Log message for closing port
        (z Port z Closed)N)r   r   _typer   r2   s    r/   _logConnectionLostMsgzPort._logConnectionLostMsg  s3     	DDJDDd&:DDDEEEEEr0   c                    |                                   d| _        d}t          | d          r	| j        }| `d| _        | j                            |            d| _        |                     d           | `	| `
	 | j                                         d| _        ||                    d           dS dS # t          $ r4 d| _        |)|                    t#          j                               Y dS  w xY w)z'
        Cleans up the socket.
        Nr   TF)r   r   r   r   r[   r.   r   r   r^   r'   r)   r   doStopr   callbackrP   errbackr   rQ   )r+   rY   ds      r/   rS   zPort.connectionLost  s    	""$$$#4$$ 	A ''---$K	!L!!! "'D}

4      }  	 	 	!&D}		'/++,,,,,,	s   9B4 49C20C2c                 >    t          j        | j        j                  S )zK
        Returns the name of my class, to prefix log entries with.
        )r   qualr   r   r2   s    r/   rb   zPort.logPrefix  s     |DL2333r0   c                 B     | j         dgt          | j                  R  S )zf
        Returns an IPv4Address or IPv6Address.

        This indicates the server's address.
        r   )r   r   r'   r2   s    r/   r   zPort.getHost  s)     !t Cdk)B)BCCCCr0   c                 ~    |                      ||           | j        s| j        s|                                  d S d S d S r$   )handleAcceptr   r[   r   )r+   r   r|   r@   s       r/   cbAcceptzPort.cbAccept  sR    "c"""" 	d&7 	MMOOOOO	 	 	 	r0   c           	      2   | j         s| j        rdS |r;t          j        dt          j                            |d          d|d           dS |j                            t          j
        t          t          j        d| j	                                                             t          j        |j                                        |j                  \  }}}|| j        k    sJ d|d         v r@t'          |d                             d          d	                   }|d         |d	         d|f}d|d         v r@t'          |d                             d          d	                   }|d         |d	         d|f}| j                             | j        d
g|R            }||j                                         n\| j        }|d	z   | _        t5          |j        | | j        d
g|R   | j        d
g|R  || j                  }	|                    |	           dS )NFz#Could not accept new connection -- zunknown errorz ()r   %r   rK   r   T)r   r[   r   r   r   r   r   newsktrk   r'   rp   r   r   r   r(   r=   get_accept_addrsrG   r   intsplitr   r   r   closer   r   r.   r   )
r+   r   r@   familylAddrrAddrscoper*   s	transports
             r/   r  zPort.handleAccept!  s;    	!2 	5  +	GG?&&r?;;;;RRRA   5 J!!!(C!3!3!5!566  
 $)#9#*:K:K:M:Msx#X#X FE5T///// eAhE!HNN3//233q58Q6eAhE!HNN3//233q58Q6|112C$2CE2RE2R2R2RSSH
  """"N!"Q"J%D%e4e444%D%e4e444L 	 ''	2224r0   c                    t          j        | j        |           }t          d| j        dz   z            x|_        }| j                            | j        | j	                  x|_
        }t          j        | j                                        |                                ||          }|r#|t          k    r|                     ||           d S d S d S )N      )r=   r   r  r7   r   rG   r.   r   r   r   r  acceptr'   r(   r   r  )r+   r@   rG   r  r   s        r/   r   zPort.doAcceptT  s    k$-.. $A):$;<<<4"l77
 
 	

V \$+,,..sKK 	'"(((b#&&&&&	' 	'((r0   )r   r   N)%r   r   r   r   r[   r   r'   r   r   r   r   r   IPv4Addressr   r   r   r   r
  __annotations__r   r&   r   r   r   r   rQ   r
   CONNECTION_DONEr   stopListeningr   rS   rb   r   r  r  r   r   r0   r/   r   r     s<        ILMNM#J&LI &*OXc]))) E4 4 4 4#      @ '6god6J&K&K ! ! ! ! #MF F F! ! !>4 4 4D D D  
1 1 1f' ' ' ' 'r0   r   )>r   r   r'   r   typingr   zope.interfacer   r   twisted.internetr   r   r   r	   r
   twisted.internet.abstractr   r   twisted.internet.iocpreactorr   r   r=   "twisted.internet.iocpreactor.constr   r   r   r   r   'twisted.internet.iocpreactor.interfacesr   twisted.internet.protocolr   twisted.internet.tcpr   TCPConnectorr   r   r   r   r   r   twisted.pythonr   r   r   twisted.internet._newtlsr    
__startTLSrv   ImportErrorWSAECONNREFUSEDWSAENETUNREACHr   ITCPTransportISystemHandler%   r"   ITLSTransportr   r   IListeningPortr   r   r0   r/   <module>r/     s^             7 7 7 7 7 7 7 7 D D D D D D D D D D D D D D > > > > > > > > G G G G G G G G              E D D D D D . . . . . .                  1 0 0 0 0 0 0 0 0 0?????? II    III e3u3 z79QRRx x x x x$m^ x x SRxv OJ
 8999V' V' V' V' V'_nj V' V' V'r8 8 8 8 8Z 8 8 8vR R R R R R R R
 Z&''Q' Q' Q' Q' Q'=) Q' Q' ('Q' Q' Q's   2A; ;BB