From owner-p4-projects@FreeBSD.ORG Mon Jul 21 03:48:09 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4611E1065670; Mon, 21 Jul 2008 03:48:09 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F0725106564A for ; Mon, 21 Jul 2008 03:48:08 +0000 (UTC) (envelope-from bilouro@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id D81178FC12 for ; Mon, 21 Jul 2008 03:48:08 +0000 (UTC) (envelope-from bilouro@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m6L3m8nR024390 for ; Mon, 21 Jul 2008 03:48:08 GMT (envelope-from bilouro@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6L3m8Q1024388 for perforce@freebsd.org; Mon, 21 Jul 2008 03:48:08 GMT (envelope-from bilouro@FreeBSD.org) Date: Mon, 21 Jul 2008 03:48:08 GMT Message-Id: <200807210348.m6L3m8Q1024388@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bilouro@FreeBSD.org using -f From: Victor Hugo Bilouro To: Perforce Change Reviews Cc: Subject: PERFORCE change 145531 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jul 2008 03:48:09 -0000 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 " + 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):