A Discrete-Event Network Simulator
API
tcp-bytes-in-flight-test.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 Natale Patriciello <natale.patriciello@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  */
19 
20 #include "tcp-general-test.h"
21 #include "ns3/node.h"
22 #include "ns3/log.h"
23 #include "ns3/config.h"
24 #include "tcp-error-model.h"
25 
26 using namespace ns3;
27 
28 NS_LOG_COMPONENT_DEFINE ("TcpBytesInFlightTestSuite");
29 
44 {
45 public:
51  TcpBytesInFlightTest (const std::string &desc, std::vector<uint32_t> &toDrop);
52 
53 protected:
58  virtual Ptr<ErrorModel> CreateReceiverErrorModel ();
65  virtual void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
72  virtual void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
78  virtual void BytesInFlightTrace (uint32_t oldValue, uint32_t newValue);
79 
86  void PktDropped (const Ipv4Header &ipH, const TcpHeader& tcpH, Ptr<const Packet> p);
87 
91  void ConfigureEnvironment ();
92 
98  void BeforeRTOExpired (const Ptr<const TcpSocketState> tcb, SocketWho who);
99 
105  void RTOExpired (Time oldVal, Time newVal);
106 
110  void FinalChecks ();
111 
112 private:
114  uint32_t m_dupAckRecv;
117  std::vector<uint32_t> m_toDrop;
118 };
119 
121  std::vector<uint32_t> &toDrop)
122  : TcpGeneralTest (desc),
123  m_guessedBytesInFlight (0),
124  m_dupAckRecv (0),
125  m_lastAckRecv (1),
126  m_greatestSeqSent (0),
127  m_toDrop (toDrop)
128 {
129 }
130 
131 void
133 {
134  TcpGeneralTest::ConfigureEnvironment ();
135  SetAppPktCount (30);
137  SetTransmitStart (Seconds (2.0));
138 
139  Config::SetDefault ("ns3::TcpSocketBase::Sack", BooleanValue (false));
140 }
141 
144 {
145  Ptr<TcpSeqErrorModel> m_errorModel = CreateObject<TcpSeqErrorModel> ();
146  for (std::vector<uint32_t>::iterator it = m_toDrop.begin (); it != m_toDrop.end (); ++it)
147  {
148  m_errorModel->AddSeqToKill (SequenceNumber32 (*it));
149  }
150 
152 
153  return m_errorModel;
154 }
155 
156 void
158 {
159  NS_LOG_DEBUG ("Before RTO for " << who);
160  GetSenderSocket ()->TraceConnectWithoutContext ("RTO", MakeCallback (&TcpBytesInFlightTest::RTOExpired, this));
161 }
162 
163 void
165 {
166  NS_LOG_DEBUG ("RTO expired at " << newVal.GetSeconds ());
168 }
169 
170 void
173 {
174  NS_LOG_DEBUG ("Drop seq= " << tcpH.GetSequenceNumber () << " size " << p->GetSize ());
175 }
176 
177 void
179 {
180  if (who == RECEIVER)
181  {
182  }
183  else if (who == SENDER)
184  {
185  if (h.GetAckNumber () > m_lastAckRecv)
186  { // New ack
187  uint32_t diff = h.GetAckNumber () - m_lastAckRecv;
188  NS_LOG_DEBUG ("Recv ACK=" << h.GetAckNumber ());
189 
190  if (m_dupAckRecv > 0)
191  { // Previously we got some ACKs
192  if (h.GetAckNumber () >= m_greatestSeqSent)
193  { // This an ACK which acknowledge all the window
194  m_guessedBytesInFlight = 0; // All outstanding data acked
195  diff = 0;
196  m_dupAckRecv = 0;
197  }
198  else
199  {
200  // Partial ACK: Update the dupAck received count
201  m_dupAckRecv -= diff / GetSegSize (SENDER);
202  // During fast recovery the TCP data sender respond to a partial acknowledgment
203  // by inferring that the next in-sequence packet has been lost (RFC5681)
205  }
206  }
207 
208  if ((h.GetFlags () & TcpHeader::FIN) != 0
209  || m_guessedBytesInFlight + 1 == diff)
210  { // received the ACK for the FIN (which includes 1 spurious byte)
211  diff -= 1;
212  }
213  m_guessedBytesInFlight -= diff;
215  NS_LOG_DEBUG ("Update m_guessedBytesInFlight to " <<
217  }
218  else if (h.GetAckNumber () == m_lastAckRecv
220  && (h.GetFlags () & TcpHeader::FIN) == 0)
221  {
222  // For each dupack I should guess that a segment has been received
223  // Please do not count FIN and SYN/ACK as dupacks
225  m_dupAckRecv++;
226  // RFC 6675 says after two dupacks, the segment is considered lost
227  if (m_dupAckRecv == 3)
228  {
229  NS_LOG_DEBUG ("Loss of a segment detected");
231  }
232  NS_LOG_DEBUG ("Dupack received, Update m_guessedBytesInFlight to " <<
234  }
235 
236  }
237 }
238 
239 void
241 {
242  if (who == SENDER)
243  {
244  static SequenceNumber32 retr = SequenceNumber32 (0);
245  static uint32_t times = 0;
246 
248  { // This is not a retransmission
250  times = 0;
251  }
252 
253  if (retr == h.GetSequenceNumber ())
254  {
255  ++times;
256  }
257 
258  if (times < 2)
259  {
260  // count retransmission only one time
262  }
263  retr = h.GetSequenceNumber ();
264 
265  NS_LOG_DEBUG ("TX size=" << p->GetSize () << " seq=" << h.GetSequenceNumber () <<
266  " m_guessedBytesInFlight=" << m_guessedBytesInFlight);
267  }
268 }
269 
270 void
271 TcpBytesInFlightTest::BytesInFlightTrace (uint32_t oldValue, uint32_t newValue)
272 {
273  NS_LOG_DEBUG ("Socket BytesInFlight=" << newValue <<
274  " mine is=" << m_guessedBytesInFlight);
276  "At time " << Simulator::Now ().GetSeconds () << "; guessed and measured bytes in flight differs");
277 }
278 
279 void
281 {
283  "Still present bytes in flight at the end of the transmission");
284 }
285 
286 
294 {
295 public:
296  TcpBytesInFlightTestSuite () : TestSuite ("tcp-bytes-in-flight-test", UNIT)
297  {
298  std::vector<uint32_t> toDrop;
299  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, no drop", toDrop),
300  TestCase::QUICK);
301  toDrop.push_back (4001);
302  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, one drop", toDrop),
303  TestCase::QUICK);
304  toDrop.push_back (4001);
305  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, two drop of same segment", toDrop),
306  TestCase::QUICK);
307  toDrop.pop_back ();
308  toDrop.push_back (4501);
309  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, two drop of consecutive segments", toDrop),
310  TestCase::QUICK);
311  }
312 };
313 
315 
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::Ipv4Header
Packet header for IPv4.
Definition: ipv4-header.h:34
ns3::TcpGeneralTest::SocketWho
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
Definition: tcp-general-test.h:275
ns3::TestCase::AddTestCase
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
TcpBytesInFlightTest::BytesInFlightTrace
virtual void BytesInFlightTrace(uint32_t oldValue, uint32_t newValue)
Track the bytes in flight.
Definition: tcp-bytes-in-flight-test.cc:271
ns3::BooleanValue
AttributeValue implementation for Boolean.
Definition: boolean.h:37
ns3::Packet::GetSize
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
TcpBytesInFlightTest::m_lastAckRecv
SequenceNumber32 m_lastAckRecv
Last ACK received.
Definition: tcp-bytes-in-flight-test.cc:115
TcpBytesInFlightTestSuite
TestSuite: Check the value of BytesInFlight against a home-made guess.
Definition: tcp-bytes-in-flight-test.cc:294
TcpBytesInFlightTest::m_greatestSeqSent
SequenceNumber32 m_greatestSeqSent
greatest sequence number sent.
Definition: tcp-bytes-in-flight-test.cc:116
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::TcpGeneralTest::SENDER
@ SENDER
Sender node.
Definition: tcp-general-test.h:276
ns3::TcpGeneralTest::SetTransmitStart
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
Definition: tcp-general-test.h:671
ns3::TcpGeneralTest::SetAppPktCount
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
Definition: tcp-general-test.h:650
TcpBytesInFlightTest::Rx
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Receive a packet.
Definition: tcp-bytes-in-flight-test.cc:178
TcpBytesInFlightTest::TcpBytesInFlightTest
TcpBytesInFlightTest(const std::string &desc, std::vector< uint32_t > &toDrop)
Constructor.
Definition: tcp-bytes-in-flight-test.cc:120
TcpBytesInFlightTest::ConfigureEnvironment
void ConfigureEnvironment()
Configure the test.
Definition: tcp-bytes-in-flight-test.cc:132
ns3::TcpGeneralTest::GetSenderSocket
Ptr< TcpSocketMsgBase > GetSenderSocket()
Get the pointer to a previously created sender socket.
Definition: tcp-general-test.h:343
ns3::TcpGeneralTest::GetSegSize
uint32_t GetSegSize(SocketWho who)
Get the segment size of the node specified.
Definition: tcp-general-test.cc:637
ns3::SequenceNumber32
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
Definition: sequence-number.h:479
TcpBytesInFlightTestSuite::TcpBytesInFlightTestSuite
TcpBytesInFlightTestSuite()
Definition: tcp-bytes-in-flight-test.cc:296
TcpBytesInFlightTest::RTOExpired
void RTOExpired(Time oldVal, Time newVal)
Update when RTO expires.
Definition: tcp-bytes-in-flight-test.cc:164
ns3::TcpGeneralErrorModel::SetDropCallback
void SetDropCallback(Callback< void, const Ipv4Header &, const TcpHeader &, Ptr< const Packet > > cb)
Set the drop callback.
Definition: tcp-error-model.h:52
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
ns3::Now
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
TcpBytesInFlightTest::BeforeRTOExpired
void BeforeRTOExpired(const Ptr< const TcpSocketState > tcb, SocketWho who)
Do the checks before the RTO expires.
Definition: tcp-bytes-in-flight-test.cc:157
ns3::MilliSeconds
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
tcp-error-model.h
ns3::TcpGeneralTest::RECEIVER
@ RECEIVER
Receiver node.
Definition: tcp-general-test.h:277
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
ns3::TcpHeader
Header for the Transmission Control Protocol.
Definition: tcp-header.h:45
tcp-general-test.h
ns3::MakeCallback
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
ns3::TcpGeneralTest
General infrastructure for TCP testing.
Definition: tcp-general-test.h:257
TcpBytesInFlightTest::PktDropped
void PktDropped(const Ipv4Header &ipH, const TcpHeader &tcpH, Ptr< const Packet > p)
Called when a packet is dropped.
Definition: tcp-bytes-in-flight-test.cc:171
TcpBytesInFlightTest
Check the value of BytesInFlight against a home-made guess.
Definition: tcp-bytes-in-flight-test.cc:44
ns3::TestSuite
A suite of tests to run.
Definition: test.h:1344
TcpBytesInFlightTest::m_toDrop
std::vector< uint32_t > m_toDrop
List of SequenceNumber to drop.
Definition: tcp-bytes-in-flight-test.cc:117
NS_TEST_ASSERT_MSG_EQ
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::TestSuite::UNIT
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1353
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
g_tcpBytesInFlightTestSuite
static TcpBytesInFlightTestSuite g_tcpBytesInFlightTestSuite
Static variable for test initialization.
Definition: tcp-bytes-in-flight-test.cc:314
TcpBytesInFlightTest::m_guessedBytesInFlight
uint32_t m_guessedBytesInFlight
Guessed bytes in flight.
Definition: tcp-bytes-in-flight-test.cc:113
ns3::TcpHeader::GetFlags
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
ns3::TcpHeader::GetAckNumber
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
ns3::Config::SetDefault
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
TcpBytesInFlightTest::Tx
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Transmit a packet.
Definition: tcp-bytes-in-flight-test.cc:240
ns3::TcpSeqErrorModel::AddSeqToKill
void AddSeqToKill(const SequenceNumber32 &seq)
Add the sequence number to the list of segments to be killed.
Definition: tcp-error-model.h:100
ns3::SequenceNumber
Generic "sequence number" class.
Definition: sequence-number.h:60
TcpBytesInFlightTest::FinalChecks
void FinalChecks()
Do the final checks.
Definition: tcp-bytes-in-flight-test.cc:280
TcpBytesInFlightTest::CreateReceiverErrorModel
virtual Ptr< ErrorModel > CreateReceiverErrorModel()
Create a receiver error model.
Definition: tcp-bytes-in-flight-test.cc:143
ns3::Time::GetSeconds
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
ns3::TcpGeneralTest::SetPropagationDelay
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.
Definition: tcp-general-test.h:664
ns3::TcpHeader::GetSequenceNumber
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
TcpBytesInFlightTest::m_dupAckRecv
uint32_t m_dupAckRecv
Number of DupACKs received.
Definition: tcp-bytes-in-flight-test.cc:114