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
26using namespace ns3;
27
28NS_LOG_COMPONENT_DEFINE ("TcpBytesInFlightTestSuite");
29
44{
45public:
51 TcpBytesInFlightTest (const std::string &desc, std::vector<uint32_t> &toDrop);
52
53protected:
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
92
99
105 void RTOExpired (Time oldVal, Time newVal);
106
110 void FinalChecks ();
111
112private:
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
131void
133{
134 TcpGeneralTest::ConfigureEnvironment ();
135 SetAppPktCount (30);
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
156void
158{
159 NS_LOG_DEBUG ("Before RTO for " << who);
160 GetSenderSocket ()->TraceConnectWithoutContext ("RTO", MakeCallback (&TcpBytesInFlightTest::RTOExpired, this));
161}
162
163void
165{
166 NS_LOG_DEBUG ("RTO expired at " << newVal.GetSeconds ());
168}
169
170void
173{
174 NS_LOG_DEBUG ("Drop seq= " << tcpH.GetSequenceNumber () << " size " << p->GetSize ());
175}
176
177void
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
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 }
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
239void
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
270void
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
279void
281{
283 "Still present bytes in flight at the end of the transmission");
284}
285
286
294{
295public:
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
Check the value of BytesInFlight against a home-made guess.
std::vector< uint32_t > m_toDrop
List of SequenceNumber to drop.
void ConfigureEnvironment()
Configure the test.
virtual Ptr< ErrorModel > CreateReceiverErrorModel()
Create a receiver error model.
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Transmit a packet.
SequenceNumber32 m_lastAckRecv
Last ACK received.
void FinalChecks()
Do the final checks.
uint32_t m_guessedBytesInFlight
Guessed bytes in flight.
void BeforeRTOExpired(const Ptr< const TcpSocketState > tcb, SocketWho who)
Do the checks before the RTO expires.
void PktDropped(const Ipv4Header &ipH, const TcpHeader &tcpH, Ptr< const Packet > p)
Called when a packet is dropped.
virtual void BytesInFlightTrace(uint32_t oldValue, uint32_t newValue)
Track the bytes in flight.
TcpBytesInFlightTest(const std::string &desc, std::vector< uint32_t > &toDrop)
Constructor.
void RTOExpired(Time oldVal, Time newVal)
Update when RTO expires.
uint32_t m_dupAckRecv
Number of DupACKs received.
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Receive a packet.
SequenceNumber32 m_greatestSeqSent
greatest sequence number sent.
TestSuite: Check the value of BytesInFlight against a home-made guess.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Packet header for IPv4.
Definition: ipv4-header.h:34
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
void SetDropCallback(Callback< void, const Ipv4Header &, const TcpHeader &, Ptr< const Packet > > cb)
Set the drop callback.
General infrastructure for TCP testing.
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
@ RECEIVER
Receiver node.
uint32_t GetSegSize(SocketWho who)
Get the segment size of the node specified.
Ptr< TcpSocketMsgBase > GetSenderSocket()
Get the pointer to a previously created sender socket.
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:45
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
void AddSeqToKill(const SequenceNumber32 &seq)
Add the sequence number to the list of segments to be killed.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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:141
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:1648
static TcpBytesInFlightTestSuite g_tcpBytesInFlightTestSuite
Static variable for test initialization.