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 "tcp-error-model.h"
24 
25 namespace ns3 {
26 
27 NS_LOG_COMPONENT_DEFINE ("TcpBytesInFlightTestSuite");
28 
40 {
41 public:
42  TcpBytesInFlightTest (const std::string &desc, std::vector<uint32_t> &toDrop);
43 
44 protected:
46  virtual void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
47  virtual void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
48  virtual void BytesInFlightTrace (uint32_t oldValue, uint32_t newValue);
49 
50  void PktDropped (const Ipv4Header &ipH, const TcpHeader& tcpH, Ptr<const Packet> p);
51  void ConfigureEnvironment ();
52 
53  void FinalChecks ();
54 
55 private:
58  uint32_t m_dupAckRecv;
61  std::vector<uint32_t> m_toDrop; // List of SequenceNumber to drop
62 };
63 
65  std::vector<uint32_t> &toDrop)
66  : TcpGeneralTest (desc),
67  m_realBytesInFlight (0),
68  m_guessedBytesInFlight (0),
69  m_dupAckRecv (0),
70  m_lastAckRecv (1),
71  m_greatestSeqSent (0),
72  m_toDrop (toDrop)
73 {
74 }
75 
76 void
78 {
80  SetAppPktCount (30);
82  SetTransmitStart (Seconds (2.0));
83 
84 }
85 
88 {
89  Ptr<TcpSeqErrorModel> m_errorModel = CreateObject<TcpSeqErrorModel> ();
90  for (std::vector<uint32_t>::iterator it = m_toDrop.begin (); it != m_toDrop.end (); ++it)
91  {
92  m_errorModel->AddSeqToKill (SequenceNumber32 (*it));
93  }
94 
95  m_errorModel->SetDropCallback (MakeCallback (&TcpBytesInFlightTest::PktDropped, this));
96 
97  return m_errorModel;
98 }
99 
100 void
103 {
104  NS_LOG_DEBUG ("Drop seq= " << tcpH.GetSequenceNumber () << " size " << p->GetSize ());
105 
106  // These bytes leave the world, they were not loved by anyone
107  m_realBytesInFlight -= p->GetSize ();
108 }
109 
110 void
112 {
113  if (who == RECEIVER)
114  {
115  // Received has got data; bytes are not in flight anymore
116  m_realBytesInFlight -= p->GetSize ();
117  }
118  else if (who == SENDER)
119  {
120  if (h.GetAckNumber () > m_lastAckRecv)
121  { // New ack
122  uint32_t diff = h.GetAckNumber () - m_lastAckRecv;
123  NS_LOG_DEBUG ("Recv ACK=" << h.GetAckNumber ());
124 
125  if (m_dupAckRecv > 0)
126  { // Previously we got some ACKs
127  if (h.GetAckNumber () >= m_greatestSeqSent)
128  { // This an ACK which acknowledge all the window
129  diff -= (m_dupAckRecv * GetSegSize (SENDER));
130 
131  if (diff > m_guessedBytesInFlight)
132  {
133  // Our home-made guess is influenced also by retransmission
134  // so make sure that this does not overflow
135  diff = m_guessedBytesInFlight;
136  }
137 
138  m_dupAckRecv = 0;
139  }
140  else
141  {
142  // Partial ACK: Update the dupAck received count
143  m_dupAckRecv -= diff / GetSegSize (SENDER);
144  }
145  }
146 
147  if ((h.GetFlags () & TcpHeader::FIN) != 0
148  || m_guessedBytesInFlight + 1 == diff)
149  { // received the ACK for the FIN (which includes 1 spurious byte)
150  diff -= 1;
151  }
152  m_guessedBytesInFlight -= diff;
154  NS_LOG_DEBUG ("Update m_guessedBytesInFlight to " <<
156  }
157  else if (h.GetAckNumber () == m_lastAckRecv
159  && (h.GetFlags () & TcpHeader::FIN) == 0)
160  {
161  // For each dupack I should guess that a segment has been received
162  // Please do not count FIN and SYN/ACK as dupacks
164  m_dupAckRecv++;
165  NS_LOG_DEBUG ("Dupack received, Update m_guessedBytesInFlight to " <<
167  }
168 
169  }
170 }
171 
172 void
174 {
175  if (who == SENDER)
176  {
177  m_realBytesInFlight += p->GetSize ();
179  { // This is not a retransmission
182  }
183 
184  // TODO: Maybe we need to account retransmission in another variable,
185  // such as m_guessedRetransOut ?
186 
187  NS_LOG_DEBUG ("TX size=" << p->GetSize () << " seq=" << h.GetSequenceNumber () <<
188  " m_guessedBytesInFlight=" << m_guessedBytesInFlight);
189  }
190 }
191 
192 void
193 TcpBytesInFlightTest::BytesInFlightTrace (uint32_t oldValue, uint32_t newValue)
194 {
195  NS_LOG_DEBUG ("Socket BytesInFlight=" << newValue <<
196  " mine is=" << m_guessedBytesInFlight);
198  "Guessed and measured bytes in flight differs");
199 }
200 
201 void
203 {
205  "Still present bytes in flight at the end of the transmission");
206 }
207 
208 //-----------------------------------------------------------------------------
209 
211 {
212 public:
213  TcpBytesInFlightTestSuite () : TestSuite ("tcp-bytes-in-flight-test", UNIT)
214  {
215  std::vector<uint32_t> toDrop;
216  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, no drop", toDrop),
218  toDrop.push_back (4001);
219  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, one drop", toDrop),
221  toDrop.push_back (4001);
222  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, two drop of same segment", toDrop),
224  toDrop.pop_back ();
225  toDrop.push_back (4501);
226  AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, two drop of consecutive segments", toDrop),
228  }
230 
231 } // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
uint32_t GetSegSize(SocketWho who)
Get the segment size of the node specified.
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
Fast test.
Definition: test.h:1152
A suite of tests to run.
Definition: test.h:1333
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:903
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
TcpBytesInFlightTest(const std::string &desc, std::vector< uint32_t > &toDrop)
This test suite implements a Unit Test.
Definition: test.h:1343
Packet header for IPv4.
Definition: ipv4-header.h:33
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
#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:161
void FinalChecks()
Performs the (eventual) final checks through test asserts.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
Check the value of BytesInFlight against a home-made guess.
virtual void BytesInFlightTrace(uint32_t oldValue, uint32_t newValue)
Bytes in flight changes.
void PktDropped(const Ipv4Header &ipH, const TcpHeader &tcpH, Ptr< const Packet > p)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
ns3::TcpBytesInFlightTestSuite g_tcpBytesInFlightTestSuite
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
std::vector< uint32_t > m_toDrop
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
General infrastructure for TCP testing.
virtual void ConfigureEnvironment(void)
Change the configuration of the evironment.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
void ConfigureEnvironment()
Change the configuration of the evironment.
virtual Ptr< ErrorModel > CreateReceiverErrorModel()
Create and return the error model to install in the receiver node.
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.