Added slow start test
Two test added: one for the normal slow start behavior in presence of a normal socket (receive a packet, and ACKs the sequence number according to the RFC) and the other with a malicious socket which sends many small ACKs (on bad implementation this should artificially inflate the window).
This commit is contained in:
@@ -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 {
|
||||
|
||||
159
src/internet/test/tcp-slow-start-test.cc
Normal file
159
src/internet/test/tcp-slow-start-test.cc
Normal file
@@ -0,0 +1,159 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
|
||||
*
|
||||
* 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<TcpSocketMsgBase>
|
||||
TcpSlowStartAttackerTest::CreateReceiverSocket (Ptr<Node> node)
|
||||
{
|
||||
Ptr<TcpSocketSmallAcks> socket = DynamicCast<TcpSocketSmallAcks> (
|
||||
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<TypeId> types;
|
||||
types.insert (types.begin (), TcpNewReno::GetTypeId ());
|
||||
types.insert (types.begin (), TcpWestwood::GetTypeId ());
|
||||
|
||||
for (std::list<TypeId>::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
|
||||
80
src/internet/test/tcp-slow-start-test.h
Normal file
80
src/internet/test/tcp-slow-start-test.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
|
||||
*
|
||||
* 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<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
#endif // TCPSLOWSTARTTEST_H
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user