o bF@s8dZddlZzddlmZWn eyYnwddlmZmZddl m Z m Z ddl m Z mZddlmZddlmZmZdd lmZdd lmZGd d d Zee jGd ddZee je jGdddZddZddZGdddZ  d#ddZ!eeddfddZ"ddZ#Gdd d Z$d$d!d"Z%dS)%z0 Utilities and helpers for simulating a network N)Error)directlyProvides implementer)error interfaces)TCP4ClientEndpointTCP4ServerEndpoint)ConnectionRefusedError)FactoryProtocol)MemoryReactorClock)Failurec@s*eZdZddZdefddZddZdS) TLSNegotiationcCs||_||_d|_||_dS)NF)obj connectStatesent readyToSend)selfrrr4/usr/lib/python3/dist-packages/twisted/test/iosim.py__init__s zTLSNegotiation.__init__returncCsd|jdS)NzTLSNegotiation())rrrrr__repr__"szTLSNegotiation.__repr__cCs&|j|jst|_|dSdSN)r iosimVerifyNativeOpenSSLErrordisconnectReasonloseConnection)rothertptrrrpretendToVerify%s zTLSNegotiation.pretendToVerifyN)__name__ __module__ __qualname__rstrrr"rrrrrs rc@seZdZdZdS) FakeAddressz] The default address type for the host and peer of L{FakeTransport} connections. N)r#r$r%__doc__rrrrr'.sr'c@seZdZdZeefddZdZdZ dZ e dZ dZdZdZd;ddZd efd d Zd d ZddZddZddZddZddZddZddZddZddZd d!Zd"d#Zd$d%Z d&d'Z!d(d)Z"d?s zFakeTransport.rzConnection doneNcCsH||_||_g|_||_|durt}||_|durt}||_dS)a @param protocol: This transport will deliver bytes to this protocol. @type protocol: L{IProtocol} provider @param isServer: C{True} if this is the accepting side of the connection, C{False} if it is the connecting side. @type isServer: L{bool} @param hostAddress: The value to return from C{getHost}. L{None} results in a new L{FakeAddress} being created to use as the value. @type hostAddress: L{IAddress} provider or L{None} @param peerAddress: The value to return from C{getPeer}. L{None} results in a new L{FakeAddress} being created to use as the value. @type peerAddress: L{IAddress} provider or L{None} N)protocolisServerstream _nextserialserialr' hostAddress peerAddress)rr.r/r3r4rrrrHs  zFakeTransport.__init__rcCs d|jrdpd|j|jjjS)NzFakeTransport<{},{},{}>SC)formatr/r2r. __class__r#rrrrrds  zFakeTransport.__repr__cCs4|jrdS|jdur|j|dS|j|dSr) disconnectingtlstlsbufappendr0)rdatarrrwriteks  zFakeTransport.writecCs"|jr |js|jdSdSdSrproducerstreamingProducerresumeProducingrrrr_checkProducerus zFakeTransport._checkProducercCs ||_||_|s|dSdS)z. From abstract.FileDescriptor Nr?)rr@ streamingrrrregisterProducer{s  zFakeTransport.registerProducercCs d|_dSr)r@rrrrunregisterProducer z FakeTransport.unregisterProducercCs||dSr)rFrrrrr stopConsumings zFakeTransport.stopConsumingcCs|d|dS)N)r>join)riovecrrr writeSequenceszFakeTransport.writeSequencecCs d|_dSNTr9rrrrrrGzFakeTransport.loseConnectioncCs d|_dS)zp For the time being, this is the same as loseConnection; no buffered data will be lost. TNrNrrrrabortConnections zFakeTransport.abortConnectioncCs,|jdur t}n|j}|jt|dSr)r:rrr.connectionLostr )rerrrrrreportDisconnects zFakeTransport.reportDisconnectcCsdS)zM Identify this transport/event source to the logging system. iosimrrrrr logPrefixszFakeTransport.logPrefixcC|jSr)r4rrrrgetPeerzFakeTransport.getPeercCrUr)r3rrrrgetHostrWzFakeTransport.getHostcCdSrrrrrrrBzFakeTransport.resumeProducingcCrYrrrrrrpauseProducingrZzFakeTransport.pauseProducingcCs |dSr)rrrrr stopProducings zFakeTransport.stopProducingTcCs |j|A}t|||_g|_dSr)r/rr:r;)rcontextFactorybeNormalrrrrstartTLSs   zFakeTransport.startTLScCsB|j}|r g|_d|S|jdur|jjrd|j_|jSdSdS)z Get the pending writes from this transport, clearing them from the pending buffer. @return: the bytes written with C{transport.write} @rtype: L{bytes} rINT)r0rJr:rr)rr5rrr getOutBuffers  zFakeTransport.getOutBuffercCsxt|tr4|jdus J|jjr.|j||d|_|jd}|_||t|tj dSd|j_ dS|j |dSrM) isinstancerr:rr"r;rLrr ISSLTransportrr. dataReceived)rbufbrrrbufferReceiveds   zFakeTransport.bufferReceivedcCrYrrrrrrgetTcpKeepAliverZzFakeTransport.getTcpKeepAlivecCrYrrrrrr getTcpNoDelayrZzFakeTransport.getTcpNoDelaycCrYrrrrrrloseWriteConnectionrZz!FakeTransport.loseWriteConnectioncCrYrrrenabledrrrsetTcpKeepAliverZzFakeTransport.setTcpKeepAlivecCrYrrrjrrr setTcpNoDelayrZzFakeTransport.setTcpNoDelay)NN)T)+r#r$r%r( staticmethod itertoolscountr1closedr9 disconnectedrConnectionDonerr@rAr:rr&rr>rCrErFrHrLrrOrRrTrVrXrBr[r\r_r`rfrgrhrirlrmrrrrr)6sF       r)cC t|ddS)z Create and return a new in-memory transport hooked up to the given protocol. @param clientProtocol: The client protocol to use. @type clientProtocol: L{IProtocol} provider @return: The transport. @rtype: L{FakeTransport} Fr/r))clientProtocolrrrmakeFakeClient rxcCrt)z Create and return a new in-memory transport hooked up to the given protocol. @param serverProtocol: The server protocol to use. @type serverProtocol: L{IProtocol} provider @return: The transport. @rtype: L{FakeTransport} Trurv)serverProtocolrrrmakeFakeServer ryr{c@s,eZdZdZddZd ddZd ddZd S) IOPumpz Utility to pump data between clients and servers for protocol testing. Perhaps this is a utility worthy of being in protocol.py? cCs"||_||_||_||_||_dSr)clientserverclientIOserverIOdebug)rr}r~rrrrrrrs  zIOPump.__init__FcCs.d}tdD] }||rd}q|SJd)zk Pump until there is no more input or output. Returns whether any data was moved. FiTrzToo long)rangepump)rrresultxrrrflush&s  z IOPump.flushcCs$|js|r td|j}|j}|j|j|js"|r:td|r0tdt||r:tdt||rB|j||rJ|j||sN|rPdS|jjrp|jj sp|js]|ratdd|j_ d|j_|j dS|jjr|jj s|js}|rtdd|j_ d|j_|j dSdS) zX Move data back and forth. Returns whether any data was moved. z -- GLUG --.zC: zS: Tz* Cz* SF) rprintrr`rrCreprrfr9rrrR)rrsDatacDatarrrr6sB            z IOPump.pumpNF)r#r$r%r(rrrrrrrr|s  r|FTcCs4||||t|||||}|r||S)aN Create a new L{IOPump} connecting two protocols. @param serverProtocol: The protocol to use on the accepting side of the connection. @type serverProtocol: L{IProtocol} provider @param serverTransport: The transport to associate with C{serverProtocol}. @type serverTransport: L{FakeTransport} @param clientProtocol: The protocol to use on the initiating side of the connection. @type clientProtocol: L{IProtocol} provider @param clientTransport: The transport to associate with C{clientProtocol}. @type clientTransport: L{FakeTransport} @param debug: A flag indicating whether to log information about what the L{IOPump} is doing. @type debug: L{bool} @param greet: Should the L{IOPump} be L{flushed } once before returning to put the protocols into their post-handshake or post-server-greeting state? @type greet: L{bool} @return: An L{IOPump} which connects C{serverProtocol} and C{clientProtocol} and delivers bytes between them when it is pumped. @rtype: L{IOPump} )makeConnectionr|r)rzserverTransportrwclientTransportrgreetrrrrconnect`s &  rc Cs4|}|}||}||} ||t|| ||||fS)a Connect a given server and client class to each other. @param ServerClass: a callable that produces the server-side protocol. @type ServerClass: 0-argument callable returning L{IProtocol} provider. @param ClientClass: like C{ServerClass} but for the other side of the connection. @type ClientClass: 0-argument callable returning L{IProtocol} provider. @param clientTransportFactory: a callable that produces the transport which will be attached to the protocol returned from C{ClientClass}. @type clientTransportFactory: callable taking (L{IProtocol}) and returning L{FakeTransport} @param serverTransportFactory: a callable that produces the transport which will be attached to the protocol returned from C{ServerClass}. @type serverTransportFactory: callable taking (L{IProtocol}) and returning L{FakeTransport} @param debug: Should this dump an escaped version of all traffic on this connection to stdout for inspection? @type debug: L{bool} @param greet: Should the L{IOPump} be L{flushed } once before returning to put the protocols into their post-handshake or post-server-greeting state? @type greet: L{bool} @return: the client protocol, the server protocol, and an L{IOPump} which, when its C{pump} and C{flush} methods are called, will move data between the created client and server protocol instances. @rtype: 3-L{tuple} of L{IProtocol}, L{IProtocol}, L{IOPump} )r) ServerClass ClientClassclientTransportFactoryserverTransportFactoryrrcsciosiorrrconnectedServerAndClients *rc Cs.|\}}}}}|\}}} } ||kr||fSdS)a' Should the client and server described by the arguments be connected to each other, i.e. do their port numbers match? @param clientInfo: the args for connectTCP @type clientInfo: L{tuple} @param serverInfo: the args for listenTCP @type serverInfo: L{tuple} @return: If they do match, return factories for the client and server that should connect; otherwise return L{None}, indicating they shouldn't be connected. @rtype: L{None} or 2-L{tuple} of (L{ClientFactory}, L{IProtocolFactory}) Nr) clientInfo serverInfo clientHost clientPort clientFactory clientTimeoutclientBindAddress serverPort serverFactory serverBacklogserverInterfacerrr_factoriesShouldConnects rc@s4eZdZdZddZd ddZeefddZd S) ConnectionCompleterz A L{ConnectionCompleter} can cause synthetic TCP connections established by L{MemoryReactor.connectTCP} and L{MemoryReactor.listenTCP} to succeed or fail. cCs ||_dS)z Create a L{ConnectionCompleter} from a L{MemoryReactor}. @param memoryReactor: The reactor to attach to. @type memoryReactor: L{MemoryReactor} N)_reactor)r memoryReactorrrrrs zConnectionCompleter.__init__Fc Cs|j}t|jD]?\}}|jD]7}t||}|rF|j||j||\}}|d} |d} t | } t | } t | | | | |SqqdS)a Complete a single TCP connection established on this L{ConnectionCompleter}'s L{MemoryReactor}. @param debug: A flag; whether to dump output from the established connection to stdout. @type debug: L{bool} @return: a pump for the connection, or L{None} if no connection could be established. @rtype: L{IOPump} or L{None} N) r enumerate tcpClients tcpServersrremove connectorspop buildProtocolr{rxr) rrr clientIdxrr factoriesrrrwrzrrrrr succeedOnces,        zConnectionCompleter.succeedOncecCs(|jjdd|jjd|dS)z Fail a single TCP connection established on this L{ConnectionCompleter}'s L{MemoryReactor}. @param reason: the reason to provide that the connection failed. @type reason: L{Failure} rN)rrrclientConnectionFailedr)rreasonrrrfailOnceszConnectionCompleter.failOnceNr) r#r$r%r(rrr r rrrrrrs  !rcCs8t}t|dd}t|d}|tt|t|fS)a Create an endpoint that can be fired on demand. @param debug: A flag; whether to dump output from the established connection to stdout. @type debug: L{bool} @return: A client endpoint, and an object that will cause one of the L{Deferred}s returned by that client endpoint. @rtype: 2-L{tuple} of (L{IStreamClientEndpoint}, L{ConnectionCompleter}) z0.0.0.0i)r rrlistenr forProtocolr r)rreactorclientEndpointserverEndpointrrrconnectableEndpoints    r)FTr)&r(ro OpenSSL.SSLrr ImportErrorzope.interfacerrtwisted.internetrrtwisted.internet.endpointsrrtwisted.internet.errorr twisted.internet.protocolr r twisted.internet.testingr twisted.python.failurer rIAddressr' ITransport ITLSTransportr)rxr{r|rrrrrrrrrsD     H  M 4 1>