Date: Mon, 21 Jul 2008 03:48:08 GMT From: Victor Hugo Bilouro <bilouro@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 145531 for review Message-ID: <200807210348.m6L3m8Q1024388@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145531 Change 145531 by bilouro@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):
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807210348.m6L3m8Q1024388>