o bM@sdZddlZddlZddlZddlmZddlmZmZddl m Z m Z m Z m Z mZddlmZmZddlmZmZddlmZmZmZmZmZdd lmZdd lmZdd l m!Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(dd l)m*Z*m+Z+m,Z,zdd l-m.Z/Wn e0ydZ1Ynwe/Z1eej2eej3iZ4eee j5e j6Gdddej7e(e#Z8e1duree8e j9Gddde$e%e8Z:Gddde8Z;Gddde"Z!ee j<Gddde(eZ=dS)z TCP support for IOCP reactor N)Optional)classImplements implementer)addressdefererror interfacesmain) _LogOwner isIPv6Address)abstract iocpsupport)ERROR_CONNECTION_REFUSEDERROR_IO_PENDINGERROR_NETWORK_UNREACHABLESO_UPDATE_ACCEPT_CONTEXTSO_UPDATE_CONNECT_CONTEXT)IReadWriteHandle)Protocol) Connector_AbortingMixin_BaseBaseClient_BaseTCPClient _getsockname _resolveIPv6 _SocketCloser)failurelogreflect)startTLSc@seZdZdZdZd/ddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZedurFd0dd Zd!d"Zd#d$Zd/d%d&Zd'd(Zd)d*Zd+d,Zd-d.ZdS)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. FNcCs&tj||||_|j|_||_dSN)r FileHandle__init__socketfileno getFileHandleprotocol)selfsockprotoreactorr,B/usr/lib/python3/dist-packages/twisted/internet/iocpreactor/tcp.pyr#?s zConnection.__init__cC|jSr!)r$r(r,r,r- getHandleEszConnection.getHandlecCs@t|trnt|trt|}ntdt||j|dS)z` @param rbuffer: Data received. @type rbuffer: L{bytes} or L{bytearray} z%data must be bytes or bytearray, not N) isinstancebytes bytearray TypeErrortyper' dataReceived)r(rbufferr,r,r-r6Hs   zConnection.dataReceivedcCst|||Sr!)_iocprecvr&)r(bufflistevtr,r,r-readFromHandleWszConnection.readFromHandlecCs(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) memoryviewr8sendr& SEND_LIMITtobytes)r(buffr; writeViewr,r,r- writeToHandleZszConnection.writeToHandlecCsxz|jdWn tyYnwt|jd}|r:z|WdSty9t }t | |YdSwdS)N) r$shutdownOSErrorrIHalfCloseableProtocolr'writeConnectionLost BaseExceptionrFailurererrconnectionLost)r(pfr,r,r-_closeWriteConnectionds  z Connection._closeWriteConnectioncCsZt|jd}|r&z|WdSty%t|t YdSw||dSr!) rrGr'readConnectionLostrIrrKrLrrJ)r(reasonrMr,r,r-rPrs zConnection.readConnectionLostcCsX|jrdStj|||dup|tj }|||j}|`|` |` ||dSr!) disconnectedr r"rLcheckrConnectionAborted _closeSocketr'r$r&)r(rQisCleanr'r,r,r-rL}s zConnection.connectionLostcCr.)zN Return the prefix to log with when I own the logging thread. )logstrr/r,r,r- logPrefixzConnection.logPrefixcCt|jtjtjSr!)boolr$ getsockopt IPPROTO_TCP TCP_NODELAYr/r,r,r- getTcpNoDelayzConnection.getTcpNoDelaycC|jtjtj|dSr!)r$ setsockoptr]r^r(enabledr,r,r- setTcpNoDelayzConnection.setTcpNoDelaycCrZr!)r[r$r\ SOL_SOCKET SO_KEEPALIVEr/r,r,r-getTcpKeepAliver`zConnection.getTcpKeepAlivecCrar!)r$rbrgrhrcr,r,r-setTcpKeepAliverfzConnection.setTcpKeepAliveTcCst|||tjdS)z9 @see: L{ITLSTransport.startTLS} N) _startTLSr r")r(contextFactorynormalr,r,r-rszConnection.startTLScC2|jrdS|jr|j|dStj||dS)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)rRTLSr'writer r")r(datar,r,r-rp zConnection.writecCrn)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)rRror' writeSequencer r")r(iovecr,r,r-rsrrzConnection.writeSequencecCs:|jr|jr|js|jdSdSdStj||dS)z Close the underlying handle or, if TLS has been started, first shut it down. @see: L{twisted.internet.interfaces.ITransport.loseConnection} N)ro connected disconnectingr'loseConnectionr r")r(rQr,r,r-rws  zConnection.loseConnectioncCs,|jr |j||dStj|||dS)zc Register a producer. If TLS is enabled, the TLS connection handles this. N)ror'registerProducerr r")r(producer streamingr,r,r-rxszConnection.registerProducercCs$|jr |jdStj|dS)ze Unregister a producer. If TLS is enabled, the TLS connection handles this. N)ror'unregisterProducerr r"r/r,r,r-r{szConnection.unregisterProducercCdSr!r,r/r,r,r-getHostzConnection.getHostcCr|r!r,r/r,r,r-getPeerr~zConnection.getPeerr!)T)__name__ __module__ __qualname____doc__ror#r0r6r<rCrOrPrLrXr_rerirjrkrrprsrwrxr{r}rr,r,r,r-r 5s2        r c@sTeZdZdZejZejZdZ e Z ddZ ddZ ddZd d Zd d Zd dZdS)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. TcCs*|durd}||_t||||||dS)N)r)r+rr#)r(hostport bindAddress connectorr+r,r,r-r#szClient.__init__cCs|j|j|jS)zd Create a socket registered with the IOCP reactor. @see: L{_BaseTCPClient} )r+ createSocket addressFamily socketTyper/r,r,r-createInternetSocket szClient.createInternetSocketcCs |`|`dS)z Clean up potentially circular references to the socket and to its C{getFileHandle} method. @see: L{_BaseBaseClient} N)r$r&r/r,r,r-_collectSocketDetailss zClient._collectSocketDetailscCs|j|dS)z^ Remove the active handle from the reactor. @see: L{_BaseBaseClient} N)r+removeActiveHandler/r,r,r-_stopReadingAndWritingszClient._stopReadingAndWritingc Cs|rt||}|t|tj|dfdS|jtj t t d|j |j||_d|_||j}|d|_|jdurOt|_|dS|j||dS)Nz Unknown errorPTz,client)connectExErrorsgetfailIfNotConnectedrgetConnectErrorerrno errorcoder$rbrgrstructpackr%r buildProtocolrr'ru _getLogPrefixrWrrwmakeConnection startReading)r(rcrqr;rXr,r,r- cbConnect"s&       zClient.cbConnectcCsnt|dsdStjs J|j|t|j|}t|j |j |}|r3|t kr5||d|dSdSdS)Nrr) hasattrr8have_connectexr+addActiveHandleEventrconnectr$r% realAddressr)r(r;rr,r,r- doConnect@s    zClient.doConnectN)rrrrr$AF_INETr SOCK_STREAMr_tlsClientDefaultr _commonConnectionr#rrrrrr,r,r,r-rs  rc@s:eZdZdZdZddZdefddZdd Zd 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. FcCsvt||||||_||_||_||j}|d|d|jj|_d |jj j |j|jj |_ d|_|dS)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 sessionnorr'rrWformat __class__rrrepstrrur)r(r)r'rrrr+rXr,r,r-r#\s  zServer.__init__returncCr.)z= A string representation of this connection. )rr/r,r,r-__repr__rrYzServer.__repr__cCr.)zW Returns an IPv4Address. This indicates the server's address. )rr/r,r,r-r}xzServer.getHostcCr.)zW Returns an IPv4Address. This indicates the client's address. )rr/r,r,r-rrzServer.getPeerN) rrrrrr#strrr}rr,r,r,r-rNs  rc@seZdZddZdS)rcCst|j|j|j||jSr!)rrrrr+r/r,r,r-_makeTransportrfzConnector._makeTransportN)rrrrr,r,r,r-rs rc@seZdZUdZdZdZejZej Z e j Z dZdZeeed<dZddd Zd efd d Zd dZeejfddZeZddZddZddZ ddZ!ddZ"ddZ#ddZ$dS) PortFrN_realPortNumberTCP2rcCs>||_||_||_||_||_t|rtj|_t j |_ dSdSr!) rfactorybacklog interfacer+r r$AF_INET6rr IPv6Address _addressType)r(rrrrr+r,r,r-r#s z Port.__init__rcCs2|jdurd|j|jj|jSd|j|jjS)Nz<{} of {} on {}>z<{} of {} (not listening)>)rrrrr/r,r,r-rs z Port.__repr__c Csz$|j|j|j}|jtjkrt|j|j}n|j|jf}| |Wnt y9}z t |j|j|d}~wwt ||_|d|_td||j|jf|j||jd|_d|_|j|||_|jj|_|dS)NrDz%s starting on %sTF)r+rrrr$rrrrbindrFrCannotListenErrorr8 maxAddrLenr%addrLen getsocknamerrmsgrrdoStartlistenrrurRrr&doAccept)r(sktaddrler,r,r-startListenings2       zPort.startListeningcCs2d|_|jrt|_|jd|j||jSdS)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. TrN)rvrurDeferreddeferredr+ callLaterrL)r(connDoner,r,r-rws  zPort.loseConnectioncCs td|jd|jddS)z. Log message for closing port (z Port z Closed)N)rr_typerr/r,r,r-_logConnectionLostMsgs zPort._logConnectionLostMsgcCs|d|_d}t|dr|j}|`d|_|j|d|_|d|` |` z|j Wnt yHd|_|durG|tYdSwd|_|durW|ddSdS)z' Cleans up the socket. NrTF)rrrrrRr+rrurUr$r&rdoStoprIrverrbackrrJcallback)r(rQdr,r,r-rLs0    zPort.connectionLostcCst|jjS)zK Returns the name of my class, to prefix log entries with. )rqualrrr/r,r,r-rXszPort.logPrefixcCs|jdgt|jRS)zf Returns an IPv4Address or IPv6Address. This indicates the server's address. r)rrr$r/r,r,r-r}sz Port.getHostcCs,||||js|js|dSdSdSr!) handleAcceptrvrRr)r(rrqr;r,r,r-cbAccepts   z Port.cbAcceptc Csh|js|jrdS|rtdtj|d|fdS|jt j t t d|j t|j|j\}}}||jks>Jd|dvrYt|ddd}|d|dd|f}d|dvrtt|ddd}|d|dd|f}|j|jdg|R}|dur|jd S|j}|d|_t|j||jdg|R|jdg|R||j} || d S) NFz*Could not accept new connection -- %s (%s)z unknown errorr%rrDrT)rvrRrrrrrnewsktrbr$rgrrrr%r8get_accept_addrsrArintsplitrrrcloserrr+r) r(rr;familylAddrrAddrscoper's transportr,r,r-r"sL       zPort.handleAcceptcCs|t|j|}td|jd|_}|j|j|j |_ }t |j | ||}|r:|tkr<|||dSdSdS)N)r8rrr3rrAr+rrrracceptr$r%rr)r(r;rArrr,r,r-rUs  z Port.doAccept)rrN)%rrrrurRrvr$rrrrr IPv4Addressrrrrr__annotations__rr#rrrrrJr CONNECTION_DONErw stopListeningrrLrXr}rrrr,r,r,r-rs,      3r)>rrr$rtypingrzope.interfacerrtwisted.internetrrrrr twisted.internet.abstractr r twisted.internet.iocpreactorr r r8"twisted.internet.iocpreactor.constrrrrr'twisted.internet.iocpreactor.interfacesrtwisted.internet.protocolrtwisted.internet.tcpr TCPConnectorrrrrrrtwisted.pythonrrrtwisted.internet._newtlsr __startTLS ImportErrorrkWSAECONNREFUSEDWSAENETUNREACHr ITCPTransport ISystemHandler"r ITLSTransportrrIListeningPortrr,r,r,r-sB   $  < Y;