PERFORCE change 166212 for review

Zachariah Riggle zjriggl at FreeBSD.org
Fri Jul 17 20:57:42 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=166212

Change 166212 by zjriggl at zjriggl_ebsp2 on 2009/07/17 20:57:02

	Checking in modifications from work.

Affected files ...

.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/segmentBuffer.py#2 edit
.. //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpstatemachine.py#7 edit

Differences ...

==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/segmentBuffer.py#2 (text+ko) ====

@@ -38,7 +38,20 @@
     __MAX = (2**31) - 1
     _base = 0
     _max = __MAX
-
+    
+    def __eq__(self, x):
+        if not isinstance(x,list) and not isinstance(x,tuple):
+            return False
+        
+        if len(self) != len(x):
+            return False
+        
+        for i in range(0,len(self)):
+            if self[i] != x[i]:
+                return False
+            
+        return True
+    
     def __init__(self, base=None, max=None):
         list.__init__(self)
         
@@ -54,134 +67,185 @@
             
     def __delitem__(self,i):
         # print "delitem(%s)" % (i)
-        list.__delitem__(self, self._getIndex(i))
+        
+        index = self._getIndex(i)
+        if index is None:
+            raise IndexError, "list index out of range"
+        
+        list.__delitem__(self, index)
     
     def __getslice__(self, i, j):
-        # print "getslice(%s,%s)" % (i,j)
-        return [list.__getitem__(self,item) for item in self._getIndices(i, j)]
+       # # print "getslice(%s,%s)" % (i,j)
+       # return [list.__getitem__(self,item) for item in self._getIndices(i, j)]
        #  return [self[item] for item in range(i,j) ]
-    
+       
+       retVal = []
+       for (a,b) in self._getIndices(i, j):
+           retVal += list.__getslice__(self, a, b)
+       return retVal
+       
     def __getitem__(self,i):
-        # print "getitem(%s)" % (i) 
-        return list.__getitem__(self,self._getIndex(i))
+        
+        index = self._getIndex(i)
+        if index is None: index = self.__MAX
+        return list.__getitem__(self,index)
     
     def __setslice__(self, i, j, k):
         # print "setslice(%s,%s,%s)" % (i,j,k)
-        for x,i in enumerate(self._getIndices(i, j)):
-            self.__setitem__(x,k[i])  
+        #for x,i in enumerate(self._getIndices(i, j)):
+        #    self.__setitem__(x,k[i])
+        
+        indices = self._getIndices(i, j)
+        
+        offset = 0
+        
+        print indices
+        
+        for (a,b) in indices:
+            num = b-a
+            list.__setslice__(self, a, b, k[offset:offset+num])
+            offset += num  
         
     def __setitem__(self, i, x):
-        # print "setitem(%s,%s)" % (i,x)
-        list.__setitem__(self, self._getIndex(i), x)
-    
-    def _getIndices(self, i, j):
-        '''
-        Returns a list of ranges that cover the specified range.
         
-        Example:
-        >>> from segmentBuffer import *
-        >>> x = segmentBuffer(5,10) # Middle 10, max 20.
-        >>> x += range(0,10)
-        >>> x
-        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-        >>> x[5] == list.__getitem__(x,0)
-        True
-        >>> x[4] == list.__getitem__(x,9)
-        True
-        >>> for i in range(0,10):
-        ...   print "%s -> %s" % (i, x[i])
-        ... 
-        0 -> 5
-        1 -> 6
-        2 -> 7
-        3 -> 8
-        4 -> 9
-        5 -> 0
-        6 -> 1
-        7 -> 2
-        8 -> 3
-        9 -> 4        
-        '''
-        print "getIndices(%s,%s)" % (i,j)
+        index = self._getIndex(i)
+        if index is None: index = self.__MAX
+        list.__setitem__(self, index, x)
         
-        # Range does not support negative numbers here, sorry folks!
-        # TODO: This should be added at a later point in time, just to have it done.
-        if i < 0 or j < 0:
-            print "bad"
-            return []
         
-        # Get the **actual** indices.
-        iReal = self._getIndex(i)
-        jReal = self._getIndex(j)
+    def _getIndices(self, i, j):
         
-        print "iReal: %i" % iReal
-        print "jReal: %i" % jReal
-    
-        # if iReal 
+        # If we're doing 'all-inclusive', return EVERYTHING.
+        if i == 0 and j == self.__MAX:
+            return ((i,j),)
         
-        retVal = []
+        # Get the index of the first item.  If the index is bad, use zero (the base).
+        ii = self._getIndex(i)
+        if ii is None:
+            ii = 0
+            
+        # Get the index of the last (excluded) item.
+        jj = self._getIndex(j)
+        if jj is None:
+            jj = len(self)
+#        if jj > len(self):
+#            jj = ii + (j-i)
+#        else:
+#            jj = self._getIndex(j)
+#            if jj is None:
+#                jj = self._max - self._base
         
+        retVal = ()
         
+        # [5,5]
         if i == j:
-            pass # return [] via retVal
+            retVal = ()
         
-        elif iReal < jReal:
-            print "ordered"
-            retVal = range(iReal,jReal)
+        # [1,4]
+        elif ii < jj:
+            if j == self.__MAX:
+                retVal = ((ii,len(self)),)
+            else:
+                retVal = ((ii,jj),)
         
+        # [4,1]
         else:
-            print "group"
-            # I.e. sb[4:6] when offset = 5
-            # sb[6:] + sb[:4]
+            retVal = ((ii,len(self)),(0,jj))
             
-            print "range(%s, %s) + range(%s, %s)" % (iReal, len(self), self._getIndex(0), jReal)
-            
-            # retVal = range(jReal,
-            retVal = range(iReal, len(self)) + range(self._getIndex(0), jReal)
-            
-        print "[%s:%s] -> %s" % (i,j,retVal)
         return retVal
 
+
     def _getIndex(self, i):
-        print "getIndex(%s)" % (i)
-
+        '''
+        Retrieves the actual index of an item.
+        '''
+        
+        # For this method, assume that base=5, max=10.
+        print "getIndex(%i)" % i
         retVal = None
-
-        if i == self.__MAX:
-            return self._getIndex(self._max - 1) + 1
+        
+        # Special cases defined for quickness.
+        # The base is always at ZERO offset.
+        if i == self._base:
+            return 0
+        # 'Max' is the "END" of the list, AND it is the 0th item.
+        # '__MAX' is the absolute maximum value, and is the value provided
+        # when we are given an empty-ended slice, i.e [3:]
+        elif i == self._max or i == self.__MAX:
+            return (self._max - self._base)
         
-        if i == self._max:
-            return self._max - self._base
+#        elif i == self.__MAX:
+#            return self._getIndex(self._max) 
         
-        # Negative indices count from the back.  These are
-        # fine and don't need to be changed at all. 
-        if i < 0:
-            retVal = i
+        # i.e. self[12], should refer to self[2].
+        # i.e. self[10], should refer to self[0]
+        elif self._max < i:
+            return self._getIndex(i - self._max)
+            # retVal = self._getIndex(i - self._max)
+            
+        # i.e. self[6] is stored at [1], or i-base.
+        elif self._base < i < self._max:
+            retVal = i - self._base
             
-        
-        # If it's less than the base, then the index 0 is the max'th item, and
-        # go from there.
-        elif i < self._base:
-            # Wrap...
+        # i.e. self[2] is stored at [10+2], or max+i 
+        elif 0 <= i < self._base:
             retVal = self._getIndex(self._max) + i
-    
-        # If it's over the max, decrement and re-do.
-        elif self._max <= i:
-            retVal = self._getIndex(i - self._max)
         
-        # The N'th item is offset from the base.
-        elif self._base <= i <= self._max:
-            retVal = i - self._base
+        # i.e. self[-1] is stored at the real self[-1].
+        elif i < 0:
+            retVal = self._getIndex(self._max + i) # Note we are adding a negative
             
-        else:
-            print 'error: could not calculate index for %s' % i        
-        print "%s -> %s" % (i,retVal)
-        
-        return retVal
+        return retVal 
+#
+#        if i == self.__MAX:
+#            # return self._getIndex(self._max - 1) + 1
+#            return len(self)
+#        
+#        if i == self._max:
+#            return self._max - self._base
+#        
+#        # Negative indices count from the back...
+#        if i < 0:
+#            # Make sure it's not TOO negative...
+#            if abs(i) > self._max:
+#                retVal = self._getIndex(i + self._max)
+#            else:
+#                retVal = len(self) + i # Note that we "add" a negative
+#            
+#        elif self._max <= i:
+#            # retVal = None # Still none...
+#            return 
+#            
+#        # If it's less than the base, then the index 0 is the max'th item, and
+#        # go from there.
+#        elif i < self._base:
+#            # Wrap...
+#            retVal = self._getIndex(self._max) + i
+#    
+#        # If it's over the max, decrement and re-do.
+#        # elif self._max <= i:
+#        #    retVal = self._getIndex(i - self._max)
+#        
+#        # The N'th item is offset from the base.
+#        elif self._base <= i < self._max:
+#            retVal = i - self._base
+#            
+#        else:
+#            print 'error: could not calculate index for %s' % i        
+#        # print "%s -> %s" % (i,retVal)
+#        
+#        # Don't return an out-of-bounds index...
+#        if retVal >= len(self):
+#            # print "OOB"
+#            return None
+#        
+#        return retVal
     
-    def repr(self):
+    def __repr__(self):
+        print 'repr!!'
         # return str( [self[i] for i in self._getIndices(0,len(self))] )
-        return str( self[0:] )
+        return str( self[:] )
         
-    def str(self):
+    def __str__(self):
+        print 'str!!'
         return self.__repr__()
==== //depot/projects/soc2009/zjriggl_tcpregression/src/tcpregression/tcpstatemachine.py#7 (text+ko) ====

@@ -99,7 +99,9 @@
     '''
     syn = False
     fin = False
-    
+    def __init__(self, syn=False, fin=False):
+        self.syn = syn
+        self.fin = fin
     def __str__(self):
         if self.syn:
             return "SYN"
@@ -152,8 +154,11 @@
     __connector = tcpFilter( testconfig.interface )
     __recvThread = None
 
-    @uint32
-    def snd_nxt(): '''Next sequence to be sent (SND.NXT) '''
+    # @uint32
+    @prop
+    def snd_nxt(): 
+        '''Next sequence to be sent (SND.NXT) '''
+        return {'fget': lambda self: seg(self.iss + len(self.outboundSequences))}
     _snd_nxt = 0
     
     @uint32
@@ -531,6 +536,7 @@
             # Set SND.UNA to ISS, SND.NXT to ISS+1, enter SYN-SENT
             # state, and return."
             self.snd_una = self.iss
+            self.outboundData = [sequenced(syn=True)]
             self.snd_nxt = self.iss + 1
             
             self.state = SYN_SENT
@@ -680,20 +686,28 @@
 
         pass
     
-    def send(self, data):
+    def send(self, data, async=False):
         '''
         Sends the specified data.
         Returns -1 on errors, or else the number of bytes sent.
+        
+        @param data 
+            Data string to send.
+        @param async 
+            Optionally send asynchronously.  Do not wait for acknowledgement.
         '''
+        if not validateTypes({data:str}):
+            return 0
+        
         if self.state == CLOSED:
             self.log.error('connection does not exist')
-            return -1
+            return 0
         
         if self.state == LISTEN:
             self.open()
         
         if self.state in (SYN_RECEIVED, SYN_SENT):
-            self.outboundSequences += [x for x in data]
+            self.outboundData += [x for x in data]
             
         if self.state in (ESTABLISHED, CLOSE_WAIT):
             pkt = self.newPacket({tcp.f_data: payload(data)})
@@ -702,49 +716,20 @@
             firstOctetSequence = seq(pkt.sequence)
             lastOctetSequence = seq(self.snd_nxt - 1)
             
+            self.outboundData[firstOctetSequence : lastOctetSequence] = \
+                [byte for byte in bytes]
             
-            seq = pkt.sequence
-            end = seq + len(data)
-            
             self.sendPacket(pkt)
             
-            
-            self.retransmissionQ[seq:end] = [byte for byte in bytes]
-            
-            self.outboundData[firstOctetSequence : lastOctetSequence] =
-            
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-            # TODO
-                        
-            # This is a blocking call.  Sleep until all of the data has
+            # This is a blocking call, we must wait until all of the data has
             # been acknowledged.
-            while self.snd_una <= end:
-                time.sleep(0.05)
+            while not async and self.snd_una <= lastOctetSequence:
+                time.sleep("0.01")
             
-        if self.state in (FIN_WAIT_1, FIN_WAIT_2, CLOSING, LAST_ACK, TIME_WAIT):
-            self.log.error('connection closing')                      
+            return len(pkt.data)
+        elif self.state in (FIN_WAIT_1, FIN_WAIT_2, CLOSING, LAST_ACK, TIME_WAIT):
+            self.log.error('connection closing')
+            return 0                      
         
 
     def sendQueuedPackets( self ):


More information about the p4-projects mailing list