Date: Mon, 17 Aug 2009 06:58:05 GMT From: Zachariah Riggle <zjriggl@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 167425 for review Message-ID: <200908170658.n7H6w52D003538@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=167425 Change 167425 by zjriggl@zjriggl_tcpregression on 2009/08/17 06:57:12 *Sigh* Perforce fail. I think this should fix everything. *Crosses fingers* Affected files ... .. //depot/projects/soc2009/zjriggl_tcpregression/LICENSE#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/LOGGING#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/Makefile#3 edit .. //depot/projects/soc2009/zjriggl_tcpregression/README#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/pcssetup.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/setup.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/__init__.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/__init__.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/arp.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/dhcpv4.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/dns.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/ethernet.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/icmpv4.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/icmpv6.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/ipsec.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/ipv4.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/ipv6.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/localhost.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/nd6.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/payload.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/pseudoipv6.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/tcp.orig.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/tcp.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/tcpv6.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/udp.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/udpv4.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/pcs/packets/udpv6.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/__init__.py#1 add .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/loggable.py#7 edit .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/logging.conf#6 edit .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/StringField.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/__init__.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/checksum.py#3 edit .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/checksum.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/decorators.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/field.py#4 edit .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/field.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/hwAddress.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/ipAddress.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/networkPort.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/payload.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/pseudoipv4.pyc#2 delete .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcprecvdaemon.py#4 edit .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpsenddaemon.py#2 edit .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpstates.py#4 edit .. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/timer.py#1 add Differences ... ==== //depot/projects/soc2009/zjriggl_tcpregression/Makefile#3 (text+ko) ==== @@ -1,7 +1,7 @@ PYTHON=python -PCAP=src/tcpregression/pcs/pcap -PCS=src/tcpregression/pcs +PCAP=src/pcs/pcap +PCS=src/pcs SO=pcap.so all: pcap @@ -22,3 +22,4 @@ cd $(PCAP); make clean rm -f $(PCS)/$(SO) $(PCAP)/$(SO) rm -f `find * | grep "pyc$$"` + rm -f src/pcs/pcap.c ==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/loggable.py#7 (text+ko) ==== @@ -1,9 +1,19 @@ import logging import pcsextension import inspect +from os.path import join, dirname, exists, expanduser # -------- Configure logging -------- -logging.config.fileConfig( "logging.conf" ) +if not logging.getLogger( 'tcpregression' ).disabled: + logFiles = ['logging.conf', + join( expanduser( '~' ), 'logging.conf' ), + join( dirname( __file__ ), 'logging.conf' )] + + for logFile in logFiles: + if exists( logFile ): + logging.config.fileConfig( logFile ) + logging.getLogger( 'tcpregression' ).debug( "Using log cofiguration file %s" % logFile ) + break # -------- Set Up New Loglevel Names -------- ( logging.FIELD_CHANGE, @@ -12,8 +22,7 @@ ( logging.PACKET_TRANSMIT, logging.PACKET_RECEIVED, logging.PACKET_SENT, - logging.VALIDATE, - logging.STATE_CHANGE ) = range( logging.INFO - 5, logging.INFO ) + logging.STATE_CHANGE ) = range( logging.INFO - 4, logging.INFO ) # -------- ANSI/VT100 Colors -------- @@ -58,7 +67,6 @@ logging.addLevelName( logging.RESPONSE_GENERATION, colorText( "GENERATE", fgCyan ) ) logging.addLevelName( logging.PACKET_RECEIVED, colorText( "RECVD", fgYellow ) ) logging.addLevelName( logging.PACKET_SENT, colorText( "SENT", fgGreen ) ) -logging.addLevelName( logging.VALIDATE, "VALIDATE" ) logging.addLevelName( logging.STATE_CHANGE, colorText( "STATE", fgBlue ) ) class tcplog( object ): @@ -98,8 +106,7 @@ ''' def __init__( self, parent ): - # self.logger = logging.getLogger(parent.__class__.__module__ + '.' + parent.__class__.__name__) - self.logger = logging.getLogger( parent.__class__.__name__ ) + self.logger = logging.getLogger( parent.__class__.__module__ ) def caller( self ): return inspect.stack()[2][3] @@ -112,7 +119,6 @@ warning = lambda self, x: self.logger.warning( x ) warn = lambda self, x: self.logger.warn( x ) state = lambda self, x: self.logger.log( logging.STATE_CHANGE, x ) - validate = lambda self, x: self.logger.log( logging.VALIDATE, x ) pktsent = lambda self, x: self.logger.log( logging.PACKET_SENT, x ) pktrecv = lambda self, x: self.logger.log( logging.PACKET_RECEIVED, x ) generated = lambda self, x: self.logger.log( logging.RESPONSE_GENERATION, x ) ==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/logging.conf#6 (text+ko) ==== @@ -1,5 +1,5 @@ [loggers] -keys=root +keys=root,tcpregression [handlers] keys=consoleHandler @@ -11,6 +11,12 @@ level=DEBUG handlers=consoleHandler +[logger_tcpregression] +level=DEBUG +propagate=0 +qualname=tcpregression +handlers=consoleHandler + [handler_consoleHandler] class=StreamHandler level=DEBUG @@ -18,5 +24,5 @@ args=(sys.stdout,) [formatter_simpleFormatter] -format=%(asctime)s - %(name)s - %(levelname)s - %(message)s -datefmt=+format=%(name)s - %(levelname)s - %(message)s +datefmt= ==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/checksum.py#3 (text+ko) ==== @@ -5,7 +5,7 @@ ''' from decorators import validateTypes -from ipAddress import IpAddress +from ipaddress import IpAddress from pcs.packets.ipv4 import ipv4 from pcs.packets.tcp import tcp from struct import pack, unpack ==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/pcsextension/field.py#4 (text+ko) ==== @@ -20,13 +20,20 @@ def __init__( self, default = 0, width = 8, networkByteOrder = False ): self.width = width self.networkByteOrder = networkByteOrder + self.set( default ) - if isinstance( default, int ): - self.setInteger( default ) - if isinstance( default, str ): - self.setAscii( default ) - if isinstance( default, Field ): - self.setNetworkBytes( default.getNetworkBytes() ) + def set( self, x ): + ''' + Default 'set' tries to infer the correct type. + ''' + if isinstance( x, int ): + self.setInteger( x ) + elif isinstance( x, str ): + self.setAscii( x ) + elif isinstance( x, Field ): + self.setNetworkBytes( x.getNetworkBytes() ) + else: + raise ValueError, "Could not infer type. Please use a specific set* method." def setAscii( self, x ): ''' ==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcprecvdaemon.py#4 (text+ko) ==== @@ -39,7 +39,7 @@ def __init__( self, target ): self.log = loggable.tcplog( self ) threading.Thread.__init__( self, None, self.recvThread, None, ( target, ) ) - self.log.info('Starting receive thread for object %s' % repr(target)) + self.log.info( 'Starting receive thread for object %s' % repr( target ) ) self.daemon = True # # List of packets that have been pulled off the interface, but were received out- @@ -51,31 +51,28 @@ # # # List of in-order packets to be processed. # packetsToBeProcessed = [] - def kill(self): - self.__killed= True + def kill( self ): + self.__killed = True def recvThread( self, t ): ''' Takes a TCP State Machine object as an argument. Performs the collection and organization of packets. ''' - + # Only process packets as long as we are told to. while t.state != CLOSED: # If we are not supposed to be processing packets, DON'T PROCESS PACKETS. if not t.processPacketsOnArrival: - time.sleep( 0.05 ) + time.sleep( 0.01 ) continue - - print "##### %s" % t.state - # Get the next packet from PCAP - packet = t.recvRawTcp(block=False) - if packet is not None: + packet = t.recvRawTcp( block = False ) + if packet is not None: # 'Arrive' it - t.segmentArrives(packet) + t.segmentArrives( packet ) else: - time.sleep(0.05) + time.sleep( 0.01 ) # # Iterate over all of the packets in our list. If we find ONE packet # # that is the 'next' packet that the TCP State Machine is expecting, then @@ -107,4 +104,4 @@ # # Remove everything that needs to be removed # for packet in toRemove: # self.packets.remove( packet )) - self.log.debug('Quitting recv thread')+ self.log.debug( 'Quitting recv thread' ) ==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpsenddaemon.py#2 (text+ko) ==== @@ -10,89 +10,94 @@ from pcs.packets import payload import timer from tcpstates import CLOSED, TIME_WAIT -from sequence import sequenced +from sequence import Sequenced -class TcpSendDaemon(threading.Thread): +class TcpSendDaemon( threading.Thread ): ''' This class is responsible for automatically re-sending unacknowledged data after some configured delay. ''' - timeout = timer.timer(1) + timeout = None log = None __killed = False - - def __init__(self, target): + + def __init__( self, target ): ''' @param target TcpStateMachine that this daemon is sending for. ''' - self.log = loggable.tcplog(self) - threading.Thread.__init__(self, None, self.sendThread, None, (target,) ) - self.log.info('Starting send thread for object %s' % repr(target)) + self.log = loggable.tcplog( self ) + self.timeout = timer.timer( 1 ) + threading.Thread.__init__( self, None, self.sendThread, None, ( target, ) ) + self.log.info( 'Starting send thread for object %s' % repr( target ) ) self.daemon = True - - def kill(self): - self.__killed= True - - def sendThread(self, t): - - while t.state not in (CLOSED, TIME_WAIT): - + + def kill( self ): + self.__killed = True + + def sendThread( self, t ): + + while t.state not in ( CLOSED, TIME_WAIT ): + # Restart the timer self.timeout.reset() - + # Sleep as long as we're not supposed to be sending packets, # and as long as the timer hasn't expired. self.timeout.wait() - + # Are we supposed to be sending stuff? if not t.autoResendUnackedSequences: - self.log.debug("Auto-resend disabled") + self.log.debug( "Auto-resend disabled" ) continue - + # Is there anything to send? - if len(t.outboundSequences) == 0: + if len( t.outboundSequences ) == 0: # self.log.debug("Nothing to send") continue - + # Make sure the state didn't change while we were sleeping. if t.state == CLOSED: - self.log.debug("State is CLOSED, not sending anything") + self.log.debug( "State is CLOSED, not sending anything" ) continue - + # Grab all available data, up to MSS. Only send one MSS' worth of data. - sequencesToSend = t.outboundSequences[:t.snd_una+t.mss] - self.log.debug("Sending items %i to %i in %s" % (t.snd_una, t.snd_una+t.mss, sequencesToSend)) - self.log.debug("Sending sequences %i to %i: %s" % - (t.snd_una, t.snd_una + len(sequencesToSend),repr(sequencesToSend))) - + sequencesToSend = t.outboundSequences[:t.snd_una + t.mss] + self.log.debug( "Getting sequences %i to %i in %s" % ( t.snd_una, t.snd_una + t.mss, sequencesToSend ) ) + self.log.debug( "Got sequences %i to %i: %s" % + ( t.snd_una, t.snd_una + len( sequencesToSend ), repr( sequencesToSend ) ) ) + # Len... - if len(sequencesToSend) == 0: - self.log.warn("outboundSequences is not empty, but there is no data to send.") + if len( sequencesToSend ) == 0: + self.log.warn( "outboundSequences is not empty, but there is no data to send." ) continue - + # Check for a SYN or FIN - syn = 1 if (type(sequencesToSend[0]) == sequenced and sequencesToSend[0].syn) else 0 - fin = 1 if (type(sequencesToSend[0]) == sequenced and sequencesToSend[0].fin) else 0 - if syn: self.log.debug("Haz a SYN!") - if fin: self.log.debug("Haz an FIN!") - + syn = 1 if ( type( sequencesToSend[0] ) == Sequenced and sequencesToSend[0].syn ) else 0 + fin = 1 if ( type( sequencesToSend[0] ) == Sequenced and sequencesToSend[0].fin ) else 0 + if syn: self.log.debug( "Sending SYN!" ) + if fin: self.log.debug( "Sending FIN!" ) + bytes = '' if not fin and not syn: - bytes = ''.join(sequencesToSend) - + bytes = ''.join( sequencesToSend ) + + self.log.debug( "Sending %i bytes" % len( bytes ) ) + # TCP Fields - tcpFields = {tcp.f_data: payload.payload(bytes), + tcpFields = {tcp.f_data: payload.payload( bytes ), tcp.f_sequence: t.snd_una, tcp.f_syn: syn, tcp.f_fin: fin } if not syn: tcpFields[tcp.f_ack] = 1 - tcpFields[tcp.f_ack_number] = t.rcv_nxt - + tcpFields[tcp.f_ack_number] = t.rcv_nxt + self.log.debug( "Set outgoing packet ACK to %i" % t.rcv_nxt ) + # Create the packet - tcpPacket = t.newPacket(tcpFields) - + tcpPacket = t.newPacket( tcpFields ) + # Send the packet. Note that we use 'sendRaw' so that it is ALWAYS sent. - t.sendRawTcp(tcpPacket) - self.log.debug('Quitting send thread')+ self.log.debug( "Sending packet." ) + t.sendRawTcp( tcpPacket ) + self.log.debug( 'Quitting send thread' ) ==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpstates.py#4 (text+ko) ==== @@ -1,5 +1,28 @@ +# Copyright 1994-2009 The FreeBSD Project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. Redistributions in binary +# form must reproduce the above copyright notice, this list of conditions and +# the following disclaimer in the documentation and/or other materials provided +# with the distribution. THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS +# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of the FreeBSD Project. ''' -Created on May 24, 2009 +Created on May 24, 2009 @author: zach ''' @@ -16,11 +39,14 @@ name = 'Base TCP State class' next = [None] + def __init__( self ): + pass + def __str__( self ): return self.name - - def __repr__(self): - return str(self) + + def __repr__( self ): + return str( self ) class TcpStateClosed( TcpState ): ''' @@ -28,7 +54,7 @@ ''' def initialize( self ): self.name = 'Closed' - self.next = [LISTEN, SYN_SENT] + self.next = ( LISTEN, SYN_SENT ) class TcpStateListen( TcpState ): ''' @@ -36,8 +62,8 @@ TCP and port. ''' def initialize( self ): - self.name = 'Listen' - self.next = [CLOSED, SYN_SENT, SYN_RECEIVED] + self.name = 'Listen' + self.next = ( CLOSED, SYN_SENT, SYN_RECEIVED ) class TcpStateSynSent( TcpState ): ''' @@ -46,7 +72,7 @@ ''' def initialize( self ): self.name = 'Syn-Sent' - self.next = [SYN_RECEIVED, ESTABLISHED, CLOSED] + self.next = ( SYN_RECEIVED, ESTABLISHED, CLOSED ) class TcpStateSynRecvd( TcpState ): ''' @@ -56,7 +82,7 @@ ''' def initialize( self ): self.name = 'Syn-Recvd' - self.next = [ESTABLISHED, FIN_WAIT_1] + self.next = ( ESTABLISHED, FIN_WAIT_1 ) class TcpStateEstablished( TcpState ): ''' @@ -66,7 +92,7 @@ ''' def initialize( self ): self.name = 'Established' - self.next = [FIN_WAIT_1, CLOSE_WAIT] + self.next = ( FIN_WAIT_1, CLOSE_WAIT ) class TcpStateFinWait1( TcpState ): ''' @@ -76,7 +102,7 @@ ''' def initialize( self ): self.name = 'Fin-Wait-1' - self.next = [FIN_WAIT_2, CLOSING] + self.next = ( FIN_WAIT_2, CLOSING ) class TcpStateFinWait2( TcpState ): ''' @@ -85,7 +111,7 @@ ''' def initialize( self ): self.name = 'Fin-Wait-2' - self.next = [TIME_WAIT] + self.next = ( TIME_WAIT, ) class TcpStateClosing( TcpState ): ''' @@ -94,9 +120,8 @@ ''' def initialize( self ): self.name = 'Closing' - self.next = [TIME_WAIT] + self.next = ( TIME_WAIT, ) - class TcpStateCloseWait( TcpState ): ''' represents waiting for a connection termination request @@ -104,7 +129,7 @@ ''' def initialize( self ): self.name = 'Close-Wait' - self.next = [LAST_ACK] + self.next = ( LAST_ACK, ) class TcpStateLastAck( TcpState ): ''' @@ -115,7 +140,7 @@ ''' def initialize( self ): self.name = 'Last-Ack' - self.next = [CLOSED] + self.next = ( CLOSED, ) class TcpStateTimeWait( TcpState ): ''' @@ -125,7 +150,7 @@ ''' def initialize( self ): self.name = 'Time-Wait' - self.next = [CLOSED] + self.next = ( CLOSED, ) CLOSED = TcpStateClosed() TIME_WAIT = TcpStateTimeWait() @@ -151,14 +176,14 @@ SYN_SENT.initialize() LISTEN.initialize() -tcpStates = (CLOSED, TIME_WAIT, LAST_ACK, +tcpStates = ( CLOSED, TIME_WAIT, LAST_ACK, CLOSE_WAIT, CLOSING, FIN_WAIT_1, FIN_WAIT_2, ESTABLISHED, SYN_RECEIVED, SYN_SENT, - LISTEN) + LISTEN ) -synchronizedStates = (ESTABLISHED,FIN_WAIT_1, - FIN_WAIT_2, CLOSE_WAIT, - CLOSING, LAST_ACK, TIME_WAIT) +synchronizedStates = ( ESTABLISHED, FIN_WAIT_1, + FIN_WAIT_2, CLOSE_WAIT, + CLOSING, LAST_ACK, TIME_WAIT ) # #help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908170658.n7H6w52D003538>
