diff --git a/src/internet/test/tcp-general-test.cc b/src/internet/test/tcp-general-test.cc index 58aaf9e9d..ffc0a2b01 100644 --- a/src/internet/test/tcp-general-test.cc +++ b/src/internet/test/tcp-general-test.cc @@ -23,6 +23,9 @@ #include "ns3/ipv4-address-helper.h" #include "ns3/internet-stack-helper.h" #include "ns3/log.h" +#include "ns3/tcp-l4-protocol.h" +#include "../model/ipv4-end-point.h" +#include "../model/ipv6-end-point.h" #include "tcp-general-test.h" namespace ns3 { diff --git a/src/internet/test/tcp-slow-start-test.cc b/src/internet/test/tcp-slow-start-test.cc new file mode 100644 index 000000000..45fbbaad2 --- /dev/null +++ b/src/internet/test/tcp-slow-start-test.cc @@ -0,0 +1,159 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015 Natale Patriciello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "tcp-slow-start-test.h" +#include "ns3/log.h" +#include "ns3/simple-channel.h" +#include "ns3/internet-module.h" +#include "ns3/config.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("TcpSlowStartTest"); + +// TcpSlowStartNormalTest + +TcpSlowStartNormalTest::TcpSlowStartNormalTest (uint32_t segmentSize, + uint32_t packetSize, + uint32_t initSsTh, + uint32_t packets, + TypeId &typeId, + const std::string &desc) + : TcpGeneralTest (desc, packetSize, packets, Seconds (0.01), Seconds (0.5), + Seconds (10), initSsTh, 1, segmentSize, typeId, 1500), + m_lastChange (Time (0.0)), + m_leftSegments (1), + m_ackedSegments (0), + m_initial (true) +{ +} + +/** + * \brief Trace the cWnd over the slow start + * + * This method is called each time the cWnd changes. It should be updated only + * by MSS bytes at time. Since the size doubles each RTT, a timing test is also + * performed: the doubling should be made in 0.5s from the first (0.5s is + * the delay of the SimpleChannel which connect the two socket). + * + * \param oldValue old value of cWnd + * \param newValue new value of cWnd + */ +void +TcpSlowStartNormalTest::CWndTrace (uint32_t oldValue, uint32_t newValue) +{ + uint32_t segSize = GetSegSize (TcpGeneralTest::SENDER); + + if (m_initial) + { + m_initial = false; + NS_LOG_INFO ("Ignored update to " << newValue << + " with a segsize of " << segSize); + return; + } + + uint32_t segsBefore = oldValue / segSize; + uint32_t segsAfter = newValue / segSize; + uint32_t segsCumAcked = segsAfter - segsBefore; + + NS_TEST_ASSERT_MSG_EQ (newValue % segSize, 0, "SSTh increased more than segsize"); + + oldValue += segSize; + + NS_TEST_ASSERT_MSG_LT_OR_EQ (newValue, GetInitialSsThresh (), "cWnd increased over ssth"); + NS_TEST_ASSERT_MSG_EQ (oldValue, newValue, "Incremented cWnd more than segsize"); + + if (m_ackedSegments == 0) + { + m_lastChange = Simulator::Now (); + } + + m_ackedSegments += segsCumAcked; + m_leftSegments -= segsCumAcked; + + NS_LOG_INFO ("Incremented cWnd by " << segSize << " byte in Slow Start " << + "achieving a value of " << newValue << ". Acked segments: " << + m_ackedSegments << " left to be acked: " << m_leftSegments); + + if (m_leftSegments == 0) + { + m_leftSegments = m_ackedSegments * 2; + m_ackedSegments = 0; + + NS_LOG_INFO ("Updated test value. Left to be acked: " << m_leftSegments); + } +} + +// TcpSlowStartAttackerTest +TcpSlowStartAttackerTest::TcpSlowStartAttackerTest (uint32_t segmentSize, + uint32_t packetSize, + uint32_t initSsTh, + uint32_t packets, + TypeId &typeId, const std::string &msg) + : TcpSlowStartNormalTest (segmentSize, packetSize, initSsTh, packets, typeId, msg) +{ + +} + +Ptr +TcpSlowStartAttackerTest::CreateReceiverSocket (Ptr node) +{ + Ptr socket = DynamicCast ( + CreateSocket (node, + TcpSocketSmallAcks::GetTypeId (), + m_congControlTypeId)); + socket->SetBytesToAck (125); + + return socket; +} + + +//----------------------------------------------------------------------------- + +static class TcpSlowStartTestSuite : public TestSuite +{ +public: + TcpSlowStartTestSuite () : TestSuite ("tcp-slow-start-test", UNIT) + { + // This test have less packets to transmit than SsTh + std::list types; + types.insert (types.begin (), TcpNewReno::GetTypeId ()); + types.insert (types.begin (), TcpWestwood::GetTypeId ()); + + for (std::list::iterator it = types.begin (); it != types.end (); ++it) + { + AddTestCase (new TcpSlowStartNormalTest (500, 500, 10000, 10, (*it), + "slow start 500 byte, " + (*it).GetName ()), + TestCase::QUICK); + AddTestCase (new TcpSlowStartNormalTest (1000, 1000, 10000, 9, (*it), + "slow start 1000 byte, " + (*it).GetName ()), + TestCase::QUICK); + AddTestCase (new TcpSlowStartNormalTest (500, 250, 10000, 10, (*it), + "slow start small packets, " + (*it).GetName ()), + TestCase::QUICK); + AddTestCase (new TcpSlowStartAttackerTest (500, 500, 10000, 10, (*it), + "slow start ack attacker, 500 byte, " + (*it).GetName ()), + TestCase::QUICK); + AddTestCase (new TcpSlowStartAttackerTest (1000, 1000, 10000, 9, (*it), + "slow start ack attacker, 1000 byte, " + (*it).GetName ()), + TestCase::QUICK); + } + } +} g_tcpSlowStartTestSuite; + +} // namespace ns3 diff --git a/src/internet/test/tcp-slow-start-test.h b/src/internet/test/tcp-slow-start-test.h new file mode 100644 index 000000000..81f909d1f --- /dev/null +++ b/src/internet/test/tcp-slow-start-test.h @@ -0,0 +1,80 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015 Natale Patriciello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef TCPSLOWSTARTTEST_H +#define TCPSLOWSTARTTEST_H + +#include "ns3/test.h" +#include "tcp-general-test.h" + +namespace ns3 { + +/** + * \brief Test the normal behavior for slow start + * + * As method for checking the slow start, a callback is attached to the + * congestion window. With the knowledge of the number of segments, we can calculate + * if the value of the cWnd is right. Also, with a fixed delay for each packet, + * we can know if the timing is correct. + * + * Check what is done inside CWndTrace. + * + * \see CWndTrace + */ +class + TcpSlowStartNormalTest : public TcpGeneralTest +{ +public: + TcpSlowStartNormalTest (uint32_t segmentSize, uint32_t packetSize, + uint32_t initSsTh, uint32_t packets, TypeId& congControl, + const std::string &desc); + +protected: + virtual void CWndTrace (uint32_t oldValue, uint32_t newValue); + + Time m_lastChange; + uint32_t m_leftSegments; + uint32_t m_ackedSegments; + + bool m_initial; + +}; + +/** + * \brief A slow start test using a socket which sends smaller ACKs + * + * The same test are performed over a connection where, on one side, there is + * a malicious socket which sends smaller ACKs than the segment received. + * + * Slow start behavior should not change. + */ +class + TcpSlowStartAttackerTest : public TcpSlowStartNormalTest +{ +public: + TcpSlowStartAttackerTest (uint32_t segmentSize, uint32_t packetSize, + uint32_t initSsTh, uint32_t packets, TypeId& congControl, + const std::string &desc); + +protected: + virtual Ptr CreateReceiverSocket (Ptr node); +}; + +} //namespace ns3 +#endif // TCPSLOWSTARTTEST_H + diff --git a/src/internet/wscript b/src/internet/wscript index cf5a6b975..6f2df5e9b 100644 --- a/src/internet/wscript +++ b/src/internet/wscript @@ -233,6 +233,7 @@ def build(bld): 'test/tcp-header-test.cc', 'test/tcp-general-test.cc', 'test/tcp-error-model.cc', + 'test/tcp-slow-start-test.cc', 'test/udp-test.cc', 'test/ipv6-address-generator-test-suite.cc', 'test/ipv6-dual-stack-test-suite.cc',