PERFORCE change 145531 for review
Victor Hugo Bilouro
bilouro at FreeBSD.org
Mon Jul 21 03:48:09 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145531
Change 145531 by bilouro at bilouro_tcptest on 2008/07/21 03:47:47
Testing Reset Generation
added:
-assertions messages
-some refactoring
-assertReset almost done
-several RFC and personal comments
Help Needed:
(a)About Reset segment generation, RFC says: when no ack at incoming segment,
seq will be 0 and ack to sum of segment length and sequence(incoming segment).
My value is exactly 19 less then RESET I receive.
Any suggestions?
Affected files ...
.. //depot/projects/soc2008/bilouro_tcptest/src/scripts/tests/cresetfromclosedstate.py#3 edit
.. //depot/projects/soc2008/bilouro_tcptest/src/scripts/tests/tcptest.py#4 edit
Differences ...
==== //depot/projects/soc2008/bilouro_tcptest/src/scripts/tests/cresetfromclosedstate.py#3 (text+ko) ====
@@ -46,15 +46,17 @@
class TestResetFromClosedState(unittest.TestCase):
"""
- RFC 793 - Section 3.4 Establishing a Connection - Reset Generation
+ RFC 793 - Section 3.4 Establishing a Connection
+ Page 36 - Reset Generation
- 1) Sends a segment to a closed state with ACK bit set and check
- if the answer is conformant with protocol specification.
+ As a general rule, reset (RST) must be sent whenever a segment arrives
+ which apparently is not intended for the current connection. A reset
+ must not be sent if it is not clear that this is the case.
[PREPARATION]
- ==DEVICE UNDER TEST
+ ==at DEVICE UNDER TEST(DUT)
inetd with descard server running (port 9)
- possibility to kill -TERM inet process and /etc/rc.d/inetd stop
+ you must have access DUT's shell with kill -TERM inetd process and /etc/rc.d/inetd stop privileges
[TESTS]
(a)SYN with and without ACK [80%]
@@ -97,40 +99,75 @@
self.tcb.output = { self.thisside : pcs.PcapConnector("ed0") , \
self.thatside : pcs.PcapConnector("ed0") }
-
-
-
def testResetFromClosedStateWithACKSYN(self):
"""
- RFC 793 - Section 3.4 Establishing a Connection - Reset Generation
+ RFC 793 - Section 3.4 Establishing a Connection
+ Page 36
+
+ 1. If the connection does not exist (CLOSED) then a reset is sent
+ in response to any incoming segment except another reset. In
+ particular, SYNs addressed to a non-existent connection are rejected
+ by this means.
- 1) Sends a segment to a closed state with ACK bit set and check
- if the answer is conformant with protocol specification.
+ If the incoming segment has an ACK field, the reset takes its
+ sequence number from the ACK field of the segment, otherwise the
+ reset has sequence number zero and the ACK field is set to the sum
+ of the sequence number and segment length of the incoming segment.
+ The connection remains in the CLOSED state.
"""
tcptest.threewayhandshakenoopt(self, self.tcb, self.thisside, self.thatside)
- ################
- # IMPORTANT NOTE
- ################
- #
- # At this time you shoud (a)kill -TERM the inetd server of the
- # connection priviously set and stop inetd superserver at
- # Device Under Test(DUT), this will cause:
- # --> DUT to start active close
- # --> avoid new connection at new socket
- #
+
+ print "################"
+ print "# IMPORTANT NOTE"
+ print "################"
+ print "#"
+ print "# At this moment you shoud do the following in the device under test(DUT):"
+ print '# > socket -4 | grep "\:9"'
+ print "# > kill -TERM <PID_OF_INETD>"
+ print "# > /etc/rc.d/inetd stop"
+ print "# "
tcptest.passivecloseconnection(self, self.tcb, self.thisside, self.thatside)
+ print "# "
+ print "# Waiting for a couple of MSL(Maximun Segment Lifetime)"
time.sleep(60) #2MSL(freebsd7)
+
#
#--->Sending SYN
(ipsyn, tcpsyn) = tcptest.createsyn(self, self.tcb, self.thisside, self.thatside)
+ #createsyn set ack bit to 0
+ tcpsyn.ack = 1
tcptest.createwritepacket(self, self.tcb, ipsyn, tcpsyn, self.thisside, self.thatside)
- # write code here to receive the segment
- # and assert that it is with RST flag set
+ # assert RST flag is set
+ (ipfinack, tcpfinack) = tcptest.receive(self,self.tcb, self.thisside, self.thatside)
+ tcptest.assertReset(self, self.tcb, tcpfinack, self.thisside, self.thatside, tcpsyn)
+
+ def testResetFromNonExistentConnection(self):
+ """
+ RFC 793 - Section 3.4 Establishing a Connection
+ Page 36
+
+ 1. If the connection does not exist (CLOSED) then a reset is sent
+ in response to any incoming segment except another reset. In
+ particular, SYNs addressed to a non-existent connection are rejected
+ by this means.
- #.....code here
+ If the incoming segment has an ACK field, the reset takes its
+ sequence number from the ACK field of the segment, otherwise the
+ reset has sequence number zero and the ACK field is set to the sum
+ of the sequence number and segment length of the incoming segment.
+ The connection remains in the CLOSED state.
+ """
+ (ipsyn, tcpsyn) = tcptest.createsyn(self, self.tcb, self.thisside, self.thatside)
+ tcptest.createwritepacket(self, self.tcb, ipsyn, tcpsyn, self.thisside, self.thatside)
+ (ipfinack, tcpfinack) = tcptest.receive(self,self.tcb, self.thisside, self.thatside)
+ tcptest.assertReset(self, self.tcb, tcpfinack, self.thisside, self.thatside, tcpsyn)
+
+ #
+ # HELP NEEDED
+ # My calc of segment length + sequence number is less 19 of the incoming segment. Always 19. any idea?!
if __name__ == '__main__':
unittest.main()
==== //depot/projects/soc2008/bilouro_tcptest/src/scripts/tests/tcptest.py#4 (text+ko) ====
@@ -42,14 +42,14 @@
"""RFC??
...ack must be present in every packet since step #2 of 3wayhand
"""
- self.failIf(tcp.ack < 1)
- self.assertNotEqual(tcp.ack_number, 0)
- self.assertNotEqual(tcp.ack_number, None)
+ self.failUnless(tcp.ack_number != None and tcp.ack_number > 0, \
+ 'ack number must be present and greater then 0')
def assertSynPresent(self, tcp):
"""
"""
- self.failIf(tcp.syn < 1)
+ self.failIf(tcp.syn < 1, \
+ "we expect the segment must have SYN bit set")
assertSequencePresent(self, tcp)
def assertSequencePresent(self, tcp):
@@ -57,20 +57,22 @@
A fundamental notion in the design is that every octet of data sent
over a TCP connection has a sequence number.
"""
- self.assertNotEqual(tcp.sequence, 0)
- self.assertNotEqual(tcp.sequence, None)
+ self.failUnless(tcp.sequence != None and tcp.sequence > 0, \
+ 'sequence must be present and greater then 0')
def assertExpectedSequence(self, tcb, tcp, from_, to):
"""RFC??
"""
- self.assertEqual(tcp.sequence, tcb.tcpsequence[ to ])
+ self.assertEqual(tcp.sequence, tcb.tcpsequence[ to ], \
+ 'sequence: ' + str(tcp.sequence) + ' , but we expect: ' + str(tcb.tcpsequence[ to ]) )
def assertExpectedAcknowledgment(self, tcb, tcp, from_, to):
"""RFC793-P16-p2
Acknowledgment Number, value of the next sequence number the sender of
the segment is expecting to receive
"""
- self.assertEqual(tcp.ack_number, tcb.tcpsequence[ from_ ])
+ self.assertEqual(tcp.ack_number, tcb.tcpsequence[ from_ ], \
+ 'ack number: ' + str(tcp.ack_number) + ' , but we expect: ' + str(tcb.tcpsequence[ from_ ]) )
def assertSequenceAcknowledgmentOK(self, tcb, tcp, from_, to):
#RFC793-P24-p1
@@ -83,7 +85,7 @@
assertExpectedSequence(self, tcb, tcp, from_, to)
-def assertReset(self, tcb, tcp, from_, to):
+def assertReset(self, tcb, tcp, from_, to, tcp_sent):
"""
RFC 793 - Section 3.4 Establishing a Connection
Page 36
@@ -95,26 +97,29 @@
The connection remains in the CLOSED state.
"""
#it must be a reset
- self.failIf(tcp.rst <1, 'rst bit must be set')
+ self.failIf(tcp.reset <1, 'reset bit must be set')
- #"*If* the incoming segment has..."
- if (tcb.sequence[ to ] == Null or tcb.tcpsequence[ to ] <= 0):
- #the only moment a segment has no ack is at syn where
- #we don't know the receiver sequence, in other words, we only get the
- #receiver sequence number at the first segment received back(syn+ack of
- #3way handshake)
+ if (tcp_sent.ack_number == None or tcp_sent.ack_number == 0):
#Assuming that "incoming segment" has *NO* ACK Field we need assert that:
#(1)has sequence number zero
+ self.assertEqual(tcp.sequence, 0, \
+ 'The incoming segment has no ack, then the reset segment we expect must have sequence equal to zero')
+
#(2)ACK field set to the sum of the sequence number and segment length
+ expected_sum = len(tcp_sent.getbytes()) + tcp_sent.sequence
+ self.assertEqual(tcp.ack_number, expected_sum, \
+ "The incoming segment has no ack, then the reset segment we expect must have ack_number equal to sum of the sequence number and segment length of the incoming segment. Expected ack_number: " + str(tcp.ack_number) + " given: " + str(expected_sum) )
- else: #(tcb.sequence[ to ] > 0):
+ else: #(tcp.sent.ack_number > 0):
#Assuming that "incoming segment" has ACK Field we need assert that:
- #(1)sequence number set to the ACK sent
+ #(1)sequence number set to the ACK sent (Reset use sequence that receiver waits for)
+ assertExpectedSequence(self, tcb, tcp, from_, to)
def assertFin(self, tcp):
"""is fin flag on?
"""
- self.failIf(tcp.fin<1)
+ self.failIf(tcp.fin<1, \
+ "we expect the segment must have FIN bit set")
def createsyn(self, tcb, from_, to):
More information about the p4-projects
mailing list