<s> import struct <EOL> from binascii import crc32 <EOL> import itertools <EOL> from twisted . python . failure import Failure <EOL> from twisted . internet . defer import Deferred <EOL> from twisted . internet import protocol , error , reactor , defer <EOL> from twisted . internet . main import CONNECTION_DONE <EOL> from twisted . python import log , util <EOL> from vertex import tcpdfa <EOL> from vertex . statemachine import StateError <EOL> genConnID = itertools . count ( <NUM_LIT:8> ) . next <EOL> MAX_PSEUDO_PORT = ( <NUM_LIT:2> ** <NUM_LIT:16> ) <EOL> _packetFormat = ( '<STR_LIT:!>' <EOL> '<STR_LIT:H>' <EOL> '<STR_LIT:H>' <EOL> '<STR_LIT:L>' <EOL> '<STR_LIT:L>' <EOL> '<STR_LIT:L>' <EOL> '<STR_LIT:B>' <EOL> '<STR_LIT:l>' <EOL> '<STR_LIT:H>' <EOL> ) <EOL> _fixedSize = struct . calcsize ( _packetFormat ) <EOL> _SYN , _ACK , _FIN , _RST , _STB = [ <NUM_LIT:1> << n for n in range ( <NUM_LIT:5> ) ] <EOL> def _flagprop ( flag ) : <EOL> def setter ( self , value ) : <EOL> if value : <EOL> self . flags |= flag <EOL> else : <EOL> self . flags &= ~ flag <EOL> return property ( lambda self : bool ( self . flags & flag ) , setter ) <EOL> def relativeSequence ( wireSequence , initialSequence , lapNumber ) : <EOL> """<STR_LIT>""" <EOL> return ( wireSequence + ( lapNumber * ( <NUM_LIT:2> ** <NUM_LIT:32> ) ) ) - initialSequence <EOL> class PTCPPacket ( util . FancyStrMixin , object ) : <EOL> showAttributes = ( <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT:data>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:%s>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ) <EOL> syn = _flagprop ( _SYN ) <EOL> ack = _flagprop ( _ACK ) <EOL> fin = _flagprop ( _FIN ) <EOL> rst = _flagprop ( _RST ) <EOL> stb = _flagprop ( _STB ) <EOL> retransmitCount = <NUM_LIT:50> <EOL> def shortdata ( ) : <EOL> def get ( self ) : <EOL> if len ( self . data ) > <NUM_LIT> : <EOL> return self . data [ : <NUM_LIT:5> ] + '<STR_LIT>' + self . data [ - <NUM_LIT:5> : ] <EOL> else : <EOL> return self . data <EOL> return get , <EOL> shortdata = property ( * shortdata ( ) ) <EOL> def niceflags ( ) : <EOL> def get ( self ) : <EOL> res = [ ] <EOL> for ( f , v ) in [ <EOL> ( self . syn , '<STR_LIT:S>' ) , ( self . ack , '<STR_LIT:A>' ) , ( self . fin , '<STR_LIT:F>' ) , <EOL> ( self . rst , '<STR_LIT:R>' ) , ( self . stb , '<STR_LIT:T>' ) ] : <EOL> res . append ( f and v or '<STR_LIT:.>' ) <EOL> return '<STR_LIT>' . join ( res ) <EOL> return get , <EOL> niceflags = property ( * niceflags ( ) ) <EOL> def create ( cls , <EOL> sourcePseudoPort , destPseudoPort , <EOL> seqNum , ackNum , data , <EOL> window = ( <NUM_LIT:1> << <NUM_LIT:15> ) , <EOL> syn = False , ack = False , fin = False , <EOL> rst = False , stb = False , <EOL> destination = None ) : <EOL> i = cls ( sourcePseudoPort , destPseudoPort , <EOL> seqNum , ackNum , window , <EOL> <NUM_LIT:0> , <NUM_LIT:0> , len ( data ) , data ) <EOL> i . syn = syn <EOL> i . ack = ack <EOL> i . fin = fin <EOL> i . rst = rst <EOL> i . stb = stb <EOL> i . checksum = i . computeChecksum ( ) <EOL> i . destination = destination <EOL> return i <EOL> create = classmethod ( create ) <EOL> def __init__ ( self , <EOL> sourcePseudoPort , <EOL> destPseudoPort , <EOL> seqNum , ackNum , window , flags , <EOL> checksum , dlen , data , peerAddressTuple = None , <EOL> seqOffset = <NUM_LIT:0> , ackOffset = <NUM_LIT:0> , seqLaps = <NUM_LIT:0> , ackLaps = <NUM_LIT:0> ) : <EOL> self . sourcePseudoPort = sourcePseudoPort <EOL> self . destPseudoPort = destPseudoPort <EOL> self . seqNum = seqNum <EOL> self . ackNum = ackNum <EOL> self . window = window <EOL> self . flags = flags <EOL> self . checksum = checksum <EOL> self . dlen = dlen <EOL> self . data = data <EOL> self . peerAddressTuple = peerAddressTuple <EOL> self . seqOffset = seqOffset <EOL> self . ackOffset = ackOffset <EOL> self . seqLaps = seqLaps <EOL> self . ackLaps = ackLaps <EOL> def segmentLength ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . dlen + self . syn + self . fin <EOL> def relativeSeq ( self ) : <EOL> return relativeSequence ( self . seqNum , self . seqOffset , self . seqLaps ) <EOL> def relativeAck ( self ) : <EOL> return relativeSequence ( self . ackNum , self . ackOffset , self . ackLaps ) <EOL> def verifyChecksum ( self ) : <EOL> if len ( self . data ) != self . dlen : <EOL> if len ( self . data ) > self . dlen : <EOL> raise GarbageDataError ( self ) <EOL> else : <EOL> raise TruncatedDataError ( self ) <EOL> expected = self . computeChecksum ( ) <EOL> received = self . checksum <EOL> if expected != received : <EOL> raise ChecksumMismatchError ( expected , received ) <EOL> def computeChecksum ( self ) : <EOL> return crc32 ( self . data ) <EOL> def decode ( cls , bytes , hostPortPair ) : <EOL> fields = struct . unpack ( _packetFormat , bytes [ : _fixedSize ] ) <EOL> sourcePseudoPort , destPseudoPort , seq , ack , window , flags , checksum , dlen = fields <EOL> data = bytes [ _fixedSize : ] <EOL> pkt = cls ( sourcePseudoPort , destPseudoPort , seq , ack , window , flags , <EOL> checksum , dlen , data , hostPortPair ) <EOL> return pkt <EOL> decode = classmethod ( decode ) <EOL> def mustRetransmit ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . syn or self . fin or self . dlen : <EOL> return True <EOL> return False <EOL> def encode ( self ) : <EOL> dlen = len ( self . data ) <EOL> checksum = self . computeChecksum ( ) <EOL> return struct . pack ( <EOL> _packetFormat , <EOL> self . sourcePseudoPort , self . destPseudoPort , <EOL> self . seqNum , self . ackNum , self . window , <EOL> self . flags , checksum , dlen ) + self . data <EOL> def fragment ( self , mtu ) : <EOL> if self . dlen < mtu : <EOL> return [ self ] <EOL> assert not self . syn , "<STR_LIT>" <EOL> seqOfft = <NUM_LIT:0> <EOL> L = [ ] <EOL> for chunk in iterchunks ( self . data , mtu ) : <EOL> last = self . create ( self . sourcePseudoPort , <EOL> self . destPseudoPort , <EOL> self . seqNum + seqOfft , <EOL> self . ackNum , <EOL> chunk , <EOL> self . window , <EOL> destination = self . destination , <EOL> ack = self . ack ) <EOL> L . append ( last ) <EOL> seqOfft += len ( chunk ) <EOL> if self . fin : <EOL> last . fin = self . fin <EOL> last . checksum = last . computeChecksum ( ) <EOL> return L <EOL> def iterchunks ( data , chunksize ) : <EOL> """<STR_LIT>""" <EOL> offt = <NUM_LIT:0> <EOL> while offt < len ( data ) : <EOL> yield data [ offt : offt + chunksize ] <EOL> offt += chunksize <EOL> def ISN ( ) : <EOL> """<STR_LIT>""" <EOL> return <NUM_LIT:0> <EOL> def segmentAcceptable ( RCV_NXT , RCV_WND , SEG_SEQ , SEG_LEN ) : <EOL> if SEG_LEN == <NUM_LIT:0> and RCV_WND == <NUM_LIT:0> : <EOL> return SEG_SEQ == RCV_NXT <EOL> if SEG_LEN == <NUM_LIT:0> and RCV_WND > <NUM_LIT:0> : <EOL> return ( ( RCV_NXT <= SEG_SEQ ) and ( SEG_SEQ < RCV_NXT + RCV_WND ) ) <EOL> if SEG_LEN > <NUM_LIT:0> and RCV_WND == <NUM_LIT:0> : <EOL> return False <EOL> if SEG_LEN > <NUM_LIT:0> and RCV_WND > <NUM_LIT:0> : <EOL> return ( ( ( RCV_NXT <= SEG_SEQ ) and ( SEG_SEQ < RCV_NXT + RCV_WND ) ) <EOL> or ( ( RCV_NXT <= SEG_SEQ + SEG_LEN - <NUM_LIT:1> ) and <EOL> ( SEG_SEQ + SEG_LEN - <NUM_LIT:1> < RCV_NXT + RCV_WND ) ) ) <EOL> assert <NUM_LIT:0> , '<STR_LIT>' <EOL> return False <EOL> class BadPacketError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class ChecksumMismatchError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class TruncatedDataError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class GarbageDataError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class PTCPConnection ( tcpdfa . TCP ) : <EOL> """<STR_LIT>""" <EOL> mtu = <NUM_LIT> - _fixedSize <EOL> recvWindow = mtu <EOL> sendWindow = mtu <EOL> sendWindowRemaining = mtu * <NUM_LIT:2> <EOL> protocol = None <EOL> def __init__ ( self , <EOL> hostPseudoPort , peerPseudoPort , <EOL> ptcp , factory , peerAddressTuple ) : <EOL> tcpdfa . TCP . __init__ ( self ) <EOL> self . hostPseudoPort = hostPseudoPort <EOL> self . peerPseudoPort = peerPseudoPort <EOL> self . ptcp = ptcp <EOL> self . factory = factory <EOL> self . _receiveBuffer = [ ] <EOL> self . retransmissionQueue = [ ] <EOL> self . peerAddressTuple = peerAddressTuple <EOL> self . oldestUnackedSendSeqNum = <NUM_LIT:0> <EOL> self . nextSendSeqNum = <NUM_LIT:0> <EOL> self . hostSendISN = <NUM_LIT:0> <EOL> self . nextRecvSeqNum = <NUM_LIT:0> <EOL> self . peerSendISN = <NUM_LIT:0> <EOL> self . setPeerISN = False <EOL> peerSendISN = None <EOL> def packetReceived ( self , packet ) : <EOL> if packet . stb : <EOL> [ self . mtu ] = struct . unpack ( '<STR_LIT>' , packet . data ) <EOL> rq = [ ] <EOL> for pkt in self . retransmissionQueue : <EOL> rq . extend ( pkt . fragment ( self . mtu ) ) <EOL> self . retransmissionQueue = rq <EOL> return <EOL> if self . _paused : <EOL> return <EOL> generatedStateMachineInput = False <EOL> if packet . syn : <EOL> if packet . dlen : <EOL> raise BadPacketError ( <EOL> "<STR_LIT>" <EOL> % ( packet , ) ) <EOL> else : <EOL> assert packet . segmentLength ( ) == <NUM_LIT:1> <EOL> if self . peerAddressTuple is None : <EOL> assert self . wasEverListen , "<STR_LIT>" <EOL> self . peerAddressTuple = packet . peerAddressTuple <EOL> else : <EOL> assert self . peerAddressTuple == packet . peerAddressTuple <EOL> if self . setPeerISN : <EOL> if self . peerSendISN != packet . seqNum : <EOL> raise BadPacketError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( <EOL> self . peerSendISN , packet . seqNum ) ) <EOL> if not self . retransmissionQueue : <EOL> self . originate ( ack = True ) <EOL> return <EOL> self . setPeerISN = True <EOL> self . peerSendISN = packet . seqNum <EOL> self . nextRecvSeqNum += packet . segmentLength ( ) <EOL> if not packet . ack : <EOL> generatedStateMachineInput = True <EOL> self . input ( tcpdfa . SYN ) <EOL> SEG_ACK = packet . relativeAck ( ) <EOL> if packet . ack : <EOL> if ( self . oldestUnackedSendSeqNum < SEG_ACK and <EOL> SEG_ACK <= self . nextSendSeqNum ) : <EOL> rq = self . retransmissionQueue <EOL> while rq : <EOL> segmentOnQueue = rq [ <NUM_LIT:0> ] <EOL> qSegSeq = segmentOnQueue . relativeSeq ( ) <EOL> if qSegSeq + segmentOnQueue . segmentLength ( ) <= SEG_ACK : <EOL> rq . pop ( <NUM_LIT:0> ) <EOL> sminput = None <EOL> self . sendWindowRemaining += segmentOnQueue . segmentLength ( ) <EOL> if segmentOnQueue . syn : <EOL> if packet . syn : <EOL> sminput = tcpdfa . SYN_ACK <EOL> else : <EOL> sminput = tcpdfa . ACK <EOL> elif segmentOnQueue . fin : <EOL> sminput = tcpdfa . ACK <EOL> if sminput is not None : <EOL> generatedStateMachineInput = True <EOL> self . input ( sminput ) <EOL> else : <EOL> break <EOL> else : <EOL> self . _writeBufferEmpty ( ) <EOL> self . oldestUnackedSendSeqNum = SEG_ACK <EOL> if packet . syn : <EOL> assert generatedStateMachineInput <EOL> return <EOL> if not packet . segmentLength ( ) : <EOL> assert packet . ack , "<STR_LIT>" + str ( packet ) <EOL> return <EOL> if not segmentAcceptable ( self . nextRecvSeqNum , <EOL> self . recvWindow , <EOL> packet . relativeSeq ( ) , <EOL> packet . segmentLength ( ) ) : <EOL> if not self . retransmissionQueue : <EOL> self . originate ( ack = True ) <EOL> return <EOL> if packet . relativeSeq ( ) > self . nextRecvSeqNum : <EOL> return <EOL> if packet . dlen : <EOL> assert not packet . syn , '<STR_LIT>' <EOL> usefulData = packet . data [ self . nextRecvSeqNum - packet . relativeSeq ( ) : ] <EOL> if self . protocol is not None : <EOL> try : <EOL> self . protocol . dataReceived ( usefulData ) <EOL> except : <EOL> log . err ( ) <EOL> self . loseConnection ( ) <EOL> self . nextRecvSeqNum += packet . segmentLength ( ) <EOL> if self . state == tcpdfa . ESTABLISHED : <EOL> self . originate ( ack = True ) <EOL> if packet . fin : <EOL> self . input ( tcpdfa . FIN ) <EOL> def getHost ( self ) : <EOL> tupl = self . ptcp . transport . getHost ( ) <EOL> return PTCPAddress ( ( tupl . host , tupl . port ) , <EOL> self . pseudoPortPair ) <EOL> def getPeer ( self ) : <EOL> return PTCPAddress ( self . peerAddressTuple , <EOL> self . pseudoPortPair ) <EOL> _outgoingBytes = '<STR_LIT>' <EOL> _nagle = None <EOL> def write ( self , bytes ) : <EOL> assert not self . disconnected , '<STR_LIT>' <EOL> self . _outgoingBytes += bytes <EOL> self . _writeLater ( ) <EOL> def writeSequence ( self , seq ) : <EOL> self . write ( '<STR_LIT>' . join ( seq ) ) <EOL> def _writeLater ( self ) : <EOL> if self . _nagle is None : <EOL> self . _nagle = reactor . callLater ( <NUM_LIT> , self . _reallyWrite ) <EOL> def _originateOneData ( self ) : <EOL> amount = min ( self . sendWindowRemaining , self . mtu ) <EOL> sendOut = self . _outgoingBytes [ : amount ] <EOL> self . _outgoingBytes = self . _outgoingBytes [ amount : ] <EOL> self . sendWindowRemaining -= len ( sendOut ) <EOL> self . originate ( ack = True , data = sendOut ) <EOL> def _reallyWrite ( self ) : <EOL> self . _nagle = None <EOL> if self . _outgoingBytes : <EOL> while self . sendWindowRemaining and self . _outgoingBytes : <EOL> self . _originateOneData ( ) <EOL> _retransmitter = None <EOL> _retransmitTimeout = <NUM_LIT:0.5> <EOL> def _retransmitLater ( self ) : <EOL> assert self . state != tcpdfa . CLOSED <EOL> if self . _retransmitter is None : <EOL> self . _retransmitter = reactor . callLater ( self . _retransmitTimeout , self . _reallyRetransmit ) <EOL> def _stopRetransmitting ( self ) : <EOL> if self . _retransmitter is not None : <EOL> self . _retransmitter . cancel ( ) <EOL> self . _retransmitter = None <EOL> if self . _nagle is not None : <EOL> self . _nagle . cancel ( ) <EOL> self . _nagle = None <EOL> if self . _closeWaitLoseConnection is not None : <EOL> self . _closeWaitLoseConnection . cancel ( ) <EOL> self . _closeWaitLoseConnection = None <EOL> def _reallyRetransmit ( self ) : <EOL> self . _retransmitter = None <EOL> if self . retransmissionQueue : <EOL> for packet in self . retransmissionQueue : <EOL> packet . retransmitCount -= <NUM_LIT:1> <EOL> if packet . retransmitCount : <EOL> packet . ackNum = self . currentAckNum ( ) <EOL> self . ptcp . sendPacket ( packet ) <EOL> else : <EOL> self . input ( tcpdfa . TIMEOUT ) <EOL> return <EOL> self . _retransmitLater ( ) <EOL> disconnecting = False <EOL> def loseConnection ( self ) : <EOL> if not self . disconnecting : <EOL> self . disconnecting = True <EOL> if not self . _outgoingBytes : <EOL> self . _writeBufferEmpty ( ) <EOL> def _writeBufferEmpty ( self ) : <EOL> if self . _outgoingBytes : <EOL> self . _reallyWrite ( ) <EOL> elif self . producer is not None : <EOL> if ( not self . streamingProducer ) or self . producerPaused : <EOL> self . producerPaused = False <EOL> self . producer . resumeProducing ( ) <EOL> elif self . disconnecting and ( not self . disconnected <EOL> or self . state == tcpdfa . CLOSE_WAIT ) : <EOL> self . input ( tcpdfa . APP_CLOSE ) <EOL> def _writeBufferFull ( self ) : <EOL> if ( self . producer is not None <EOL> and not self . producerPaused ) : <EOL> self . producerPaused = True <EOL> self . producer . pauseProducing ( ) <EOL> else : <EOL> pass <EOL> disconnected = False <EOL> producer = None <EOL> producerPaused = False <EOL> streamingProducer = False <EOL> def registerProducer ( self , producer , streaming ) : <EOL> if self . producer is not None : <EOL> raise RuntimeError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % ( producer , self . producer ) ) <EOL> if self . disconnected : <EOL> producer . stopProducing ( ) <EOL> else : <EOL> self . producer = producer <EOL> self . streamingProducer = streaming <EOL> if not streaming and not self . _outgoingBytes : <EOL> producer . resumeProducing ( ) <EOL> def unregisterProducer ( self ) : <EOL> self . producer = None <EOL> if not self . _outgoingBytes : <EOL> self . _writeBufferEmpty ( ) <EOL> _paused = False <EOL> def pauseProducing ( self ) : <EOL> self . _paused = True <EOL> def resumeProducing ( self ) : <EOL> self . _paused = False <EOL> def currentAckNum ( self ) : <EOL> return ( self . nextRecvSeqNum + self . peerSendISN ) % ( <NUM_LIT:2> ** <NUM_LIT:32> ) <EOL> def originate ( self , data = '<STR_LIT>' , syn = False , ack = False , fin = False ) : <EOL> if syn : <EOL> assert self . nextSendSeqNum == <NUM_LIT:0> <EOL> assert self . hostSendISN == <NUM_LIT:0> <EOL> p = PTCPPacket . create ( self . hostPseudoPort , <EOL> self . peerPseudoPort , <EOL> seqNum = ( self . nextSendSeqNum + self . hostSendISN ) % ( <NUM_LIT:2> ** <NUM_LIT:32> ) , <EOL> ackNum = self . currentAckNum ( ) , <EOL> data = data , <EOL> window = self . recvWindow , <EOL> syn = syn , ack = ack , fin = fin , <EOL> destination = self . peerAddressTuple ) <EOL> sl = p . segmentLength ( ) <EOL> self . nextSendSeqNum += sl <EOL> if p . mustRetransmit ( ) : <EOL> if self . retransmissionQueue : <EOL> if self . retransmissionQueue [ - <NUM_LIT:1> ] . fin : <EOL> raise AssertionError ( "<STR_LIT>" % ( p , ) ) <EOL> self . retransmissionQueue . append ( p ) <EOL> self . _retransmitLater ( ) <EOL> if not self . sendWindowRemaining : <EOL> self . _writeBufferFull ( ) <EOL> else : <EOL> pass <EOL> self . ptcp . sendPacket ( p ) <EOL> def transition_SYN_SENT_to_CLOSED ( self ) : <EOL> """<STR_LIT>""" <EOL> self . factory . clientConnectionFailed ( None , error . TimeoutError ( ) ) <EOL> wasEverListen = False <EOL> def enter_LISTEN ( self ) : <EOL> self . wasEverListen = True <EOL> def enter_CLOSED ( self ) : <EOL> self . ptcp . connectionClosed ( self ) <EOL> self . _stopRetransmitting ( ) <EOL> if self . _timeWaitCall is not None : <EOL> self . _timeWaitCall . cancel ( ) <EOL> self . _timeWaitCall = None <EOL> _timeWaitCall = None <EOL> _timeWaitTimeout = <NUM_LIT> <EOL> def enter_TIME_WAIT ( self ) : <EOL> self . _stopRetransmitting ( ) <EOL> self . _timeWaitCall = reactor . callLater ( self . _timeWaitTimeout , self . _do2mslTimeout ) <EOL> def _do2mslTimeout ( self ) : <EOL> self . _timeWaitCall = None <EOL> self . input ( tcpdfa . TIMEOUT ) <EOL> peerAddressTuple = None <EOL> def transition_LISTEN_to_SYN_SENT ( self ) : <EOL> """<STR_LIT>""" <EOL> raise StateError ( "<STR_LIT>" ) <EOL> def pseudoPortPair ( ) : <EOL> def get ( self ) : <EOL> return ( self . hostPseudoPort , <EOL> self . peerPseudoPort ) <EOL> return get , <EOL> pseudoPortPair = property ( * pseudoPortPair ( ) ) <EOL> def enter_ESTABLISHED ( self ) : <EOL> """<STR_LIT>""" <EOL> assert not self . disconnecting <EOL> assert not self . disconnected <EOL> try : <EOL> p = self . factory . buildProtocol ( PTCPAddress ( <EOL> self . peerAddressTuple , self . pseudoPortPair ) ) <EOL> p . makeConnection ( self ) <EOL> except : <EOL> log . msg ( "<STR_LIT>" ) <EOL> log . err ( ) <EOL> self . loseConnection ( ) <EOL> else : <EOL> self . protocol = p <EOL> def exit_ESTABLISHED ( self ) : <EOL> assert not self . disconnected <EOL> self . disconnected = True <EOL> try : <EOL> self . protocol . connectionLost ( Failure ( CONNECTION_DONE ) ) <EOL> except : <EOL> log . err ( ) <EOL> self . protocol = None <EOL> if self . producer is not None : <EOL> try : <EOL> self . producer . stopProducing ( ) <EOL> except : <EOL> log . err ( ) <EOL> self . producer = None <EOL> _closeWaitLoseConnection = None <EOL> def enter_CLOSE_WAIT ( self ) : <EOL> self . _closeWaitLoseConnection = reactor . callLater ( <NUM_LIT> , self . _loseConnectionBecauseOfCloseWait ) <EOL> def _loseConnectionBecauseOfCloseWait ( self ) : <EOL> self . _closeWaitLoseConnection = None <EOL> self . loseConnection ( ) <EOL> def immediateShutdown ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _outgoingBytes = '<STR_LIT>' <EOL> if self . state == tcpdfa . ESTABLISHED : <EOL> self . input ( tcpdfa . APP_CLOSE ) <EOL> self . _stopRetransmitting ( ) <EOL> self . _reallyRetransmit ( ) <EOL> self . input ( tcpdfa . TIMEOUT ) <EOL> assert self . _retransmitter is None <EOL> assert self . _nagle is None <EOL> def output_ACK ( self ) : <EOL> self . originate ( ack = True ) <EOL> def output_FIN ( self ) : <EOL> self . originate ( fin = True ) <EOL> def output_SYN_ACK ( self ) : <EOL> self . originate ( syn = True , ack = True ) <EOL> def output_SYN ( self ) : <EOL> self . originate ( syn = True ) <EOL> class PTCPAddress ( object ) : <EOL> def __init__ ( self , ( host , port ) , ( pseudoHostPort , pseudoPeerPort ) ) : <EOL> self . host = host <EOL> self . port = port <EOL> self . pseudoHostPort = pseudoHostPort <EOL> self . pseudoPeerPort = pseudoPeerPort <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( <EOL> self . host , self . port , <EOL> self . pseudoHostPort , <EOL> self . pseudoPeerPort ) <EOL> class _PendingEvent ( object ) : <EOL> def __init__ ( self ) : <EOL> self . listeners = [ ] <EOL> def deferred ( self ) : <EOL> d = Deferred ( ) <EOL> self . listeners . append ( d ) <EOL> return d <EOL> def callback ( self , result ) : <EOL> l = self . listeners <EOL> self . listeners = [ ] <EOL> for d in l : <EOL> d . callback ( result ) <EOL> def errback ( self , result = None ) : <EOL> if result is None : <EOL> result = Failure ( ) <EOL> l = self . listeners <EOL> self . listeners = [ ] <EOL> for d in l : <EOL> d . errback ( result ) <EOL> class PTCP ( protocol . DatagramProtocol ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , factory ) : <EOL> self . factory = factory <EOL> self . _allConnectionsClosed = _PendingEvent ( ) <EOL> def connect ( self , factory , host , port , pseudoPort = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> sourcePseudoPort = genConnID ( ) % MAX_PSEUDO_PORT <EOL> conn = self . _connections [ ( pseudoPort , sourcePseudoPort , ( host , port ) ) <EOL> ] = PTCPConnection ( <EOL> sourcePseudoPort , pseudoPort , self , factory , ( host , port ) ) <EOL> conn . input ( tcpdfa . APP_ACTIVE_OPEN ) <EOL> return conn <EOL> def sendPacket ( self , packet ) : <EOL> if self . transportGoneAway : <EOL> return <EOL> self . transport . write ( packet . encode ( ) , packet . destination ) <EOL> def startProtocol ( self ) : <EOL> self . transportGoneAway = False <EOL> self . _lastConnID = <NUM_LIT:10> <EOL> self . _connections = { } <EOL> def _finalCleanup ( self ) : <EOL> """<STR_LIT>""" <EOL> for conn in self . _connections . values ( ) : <EOL> conn . immediateShutdown ( ) <EOL> assert not self . _connections <EOL> def stopProtocol ( self ) : <EOL> """<STR_LIT>""" <EOL> self . transportGoneAway = True <EOL> self . _finalCleanup ( ) <EOL> def cleanupAndClose ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _finalCleanup ( ) <EOL> return self . _stop ( ) <EOL> def datagramReceived ( self , bytes , addr ) : <EOL> if len ( bytes ) < _fixedSize : <EOL> return <EOL> pkt = PTCPPacket . decode ( bytes , addr ) <EOL> try : <EOL> pkt . verifyChecksum ( ) <EOL> except TruncatedDataError : <EOL> self . sendPacket ( <EOL> PTCPPacket . create ( <EOL> pkt . destPseudoPort , <EOL> pkt . sourcePseudoPort , <EOL> <NUM_LIT:0> , <EOL> <NUM_LIT:0> , <EOL> struct . pack ( '<STR_LIT>' , len ( pkt . data ) ) , <EOL> stb = True , <EOL> destination = addr ) ) <EOL> except GarbageDataError : <EOL> print "<STR_LIT>" , pkt <EOL> except ChecksumMismatchError , cme : <EOL> print "<STR_LIT>" , pkt , cme <EOL> print repr ( pkt . data ) <EOL> print hex ( pkt . checksum ) , hex ( pkt . computeChecksum ( ) ) <EOL> else : <EOL> self . packetReceived ( pkt ) <EOL> stopped = False <EOL> def _stop ( self , result = None ) : <EOL> if not self . stopped : <EOL> self . stopped = True <EOL> return self . transport . stopListening ( ) <EOL> else : <EOL> return defer . succeed ( None ) <EOL> def waitForAllConnectionsToClose ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _connections : <EOL> return self . _stop ( ) <EOL> return self . _allConnectionsClosed . deferred ( ) . addBoth ( self . _stop ) <EOL> def connectionClosed ( self , ptcpConn ) : <EOL> packey = ( ptcpConn . peerPseudoPort , ptcpConn . hostPseudoPort , <EOL> ptcpConn . peerAddressTuple ) <EOL> del self . _connections [ packey ] <EOL> if ( ( not self . transportGoneAway ) and <EOL> ( not self . _connections ) and <EOL> self . factory is None ) : <EOL> self . _stop ( ) <EOL> if not self . _connections : <EOL> self . _allConnectionsClosed . callback ( None ) <EOL> def packetReceived ( self , packet ) : <EOL> packey = ( packet . sourcePseudoPort , packet . destPseudoPort , packet . peerAddressTuple ) <EOL> if packey not in self . _connections : <EOL> if packet . flags == _SYN and packet . destPseudoPort == <NUM_LIT:1> : <EOL> conn = PTCPConnection ( packet . destPseudoPort , <EOL> packet . sourcePseudoPort , self , <EOL> self . factory , packet . peerAddressTuple ) <EOL> conn . input ( tcpdfa . APP_PASSIVE_OPEN ) <EOL> self . _connections [ packey ] = conn <EOL> else : <EOL> log . msg ( "<STR_LIT>" % ( packet , packey , self . _connections ) ) <EOL> return <EOL> try : <EOL> self . _connections [ packey ] . packetReceived ( packet ) <EOL> except : <EOL> log . msg ( "<STR_LIT>" % ( packet , ) ) <EOL> log . err ( ) <EOL> del self . _connections [ packey ] </s>
