A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-advertised-window-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Christoph Doepmann <doepmanc@informatik.hu-berlin.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18#include "tcp-error-model.h"
19#include "tcp-general-test.h"
20
21#include "ns3/log.h"
22#include "ns3/node.h"
23#include "ns3/random-variable-stream.h"
24#include "ns3/tcp-rx-buffer.h"
25
26using namespace ns3;
27
28NS_LOG_COMPONENT_DEFINE("TcpAdvertisedWindowTestSuite");
29
37{
38 public:
43 static TypeId GetTypeId();
44
47
54 {
55 }
56
63 : TcpSocketMsgBase(other)
64 {
67 }
68
75
81 void SetExpectedSegmentSize(uint16_t seg)
82 {
83 m_segmentSize = seg;
84 }
85
86 protected:
87 Ptr<TcpSocketBase> Fork() override;
88 uint16_t AdvertisedWindowSize(bool scale = true) const override;
89
90 private:
91 uint16_t OldAdvertisedWindowSize(bool scale = true) const;
93
101};
102
103void
105{
106 NS_ASSERT(!cb.IsNull());
107 m_inwalidAwndCb = cb;
108}
109
110TypeId
112{
113 static TypeId tid = TypeId("ns3::TcpSocketAdvertisedWindowProxy")
115 .SetGroupName("Internet")
116 .AddConstructor<TcpSocketAdvertisedWindowProxy>();
117 return tid;
118}
119
122{
123 return CopyObject<TcpSocketAdvertisedWindowProxy>(this);
124}
125
126uint16_t
128{
129 NS_LOG_FUNCTION(this << scale);
130
131 uint16_t newAwnd = TcpSocketMsgBase::AdvertisedWindowSize(scale);
132 uint16_t oldAwnd = OldAdvertisedWindowSize(scale);
133
134 if (!m_tcb->m_rxBuffer->Finished())
135 {
136 // The calculated windows will only be exactly equal if there is no data
137 // in the receive buffer yet.
138 if (newAwnd != oldAwnd)
139 {
140 uint32_t available = m_tcb->m_rxBuffer->Available();
141 // If the values differ, make sure this is only due to the single segment
142 // the socket just got, which has not yet been read by the application.
143 // Therefore, the difference should be exactly the size of one segment
144 // (but taking scale and m_maxWinSize into account).
145 uint32_t newAwndKnownDifference = newAwnd;
146 if (scale)
147 {
148 newAwndKnownDifference += (available >> m_rcvWindShift);
149 }
150 else
151 {
152 newAwndKnownDifference += available;
153 }
154
155 if (newAwndKnownDifference > m_maxWinSize)
156 {
157 newAwndKnownDifference = m_maxWinSize;
158 }
159
160 if (static_cast<uint16_t>(newAwndKnownDifference) != oldAwnd)
161 {
162 if (!m_inwalidAwndCb.IsNull())
163 {
164 m_inwalidAwndCb(oldAwnd, newAwnd);
165 }
166 }
167 }
168 }
169
170 return newAwnd;
171}
172
180uint16_t
182{
183 NS_LOG_FUNCTION(this << scale);
184 // NS_LOG_DEBUG ("MaxRxSequence () = " << m_tcb->m_rxBuffer->MaxRxSequence ());
185 // NS_LOG_DEBUG ("NextRxSequence () = " << m_tcb->m_rxBuffer->NextRxSequence ());
186 // NS_LOG_DEBUG ("MaxBufferSize () = " << m_tcb->m_rxBuffer->MaxBufferSize ());
187 // NS_LOG_DEBUG ("m_rcvWindShift = " << static_cast<uint16_t> (m_rcvWindShift));
188 // NS_LOG_DEBUG ("m_maxWinSize = " << m_maxWinSize);
189 // NS_LOG_DEBUG ("Available () = " << m_tcb->m_rxBuffer->Available ());
190 uint32_t w = m_tcb->m_rxBuffer->MaxBufferSize();
191
192 if (scale)
193 {
194 w >>= m_rcvWindShift;
195 }
196 if (w > m_maxWinSize)
197 {
198 w = m_maxWinSize;
199 NS_LOG_WARN("Adv window size truncated to "
200 << m_maxWinSize << "; possibly to avoid overflow of the 16-bit integer");
201 }
202 NS_LOG_DEBUG("Returning AdvertisedWindowSize of " << static_cast<uint16_t>(w));
203 return static_cast<uint16_t>(w);
204}
205
207
215{
216 public:
221 static TypeId GetTypeId();
222
227 TcpDropRatioErrorModel(double dropRatio)
229 m_dropRatio(dropRatio)
230 {
231 m_prng = CreateObject<UniformRandomVariable>();
232 }
233
234 protected:
235 bool ShouldDrop(const Ipv4Header& ipHeader,
236 const TcpHeader& tcpHeader,
237 uint32_t packetSize) override;
238
239 private:
240 void DoReset() override{};
241 double m_dropRatio;
243};
244
246
247TypeId
249{
250 static TypeId tid = TypeId("ns3::TcpDropRatioErrorModel").SetParent<TcpGeneralErrorModel>();
251 return tid;
252}
253
254bool
256 const TcpHeader& tcpHeader,
258{
259 return m_prng->GetValue() < m_dropRatio;
260}
261
286{
287 public:
295 TcpAdvertisedWindowTest(const std::string& desc,
296 uint32_t size,
297 uint32_t packets,
298 double lossRatio);
299
300 protected:
301 void ConfigureEnvironment() override;
304
305 private:
310 void InvalidAwndCb(uint16_t oldAwnd, uint16_t newAwnd);
313 double m_lossRatio;
314};
315
317 uint32_t size,
318 uint32_t packets,
319 double lossRatio)
320 : TcpGeneralTest(desc),
321 m_pktSize(size),
322 m_pktCount(packets),
323 m_lossRatio(lossRatio)
324{
325}
326
327void
329{
335}
336
339{
340 NS_LOG_FUNCTION(this);
341
344 DynamicCast<TcpSocketAdvertisedWindowProxy>(sock)->SetExpectedSegmentSize(500);
345 DynamicCast<TcpSocketAdvertisedWindowProxy>(sock)->SetInvalidAwndCb(
347
348 return sock;
349}
350
353{
354 return CreateObject<TcpDropRatioErrorModel>(m_lossRatio);
355}
356
357void
358TcpAdvertisedWindowTest::InvalidAwndCb(uint16_t oldAwnd, uint16_t newAwnd)
359{
360 NS_TEST_ASSERT_MSG_EQ(oldAwnd, newAwnd, "Old and new AWND calculations do not match.");
361}
362
363//-----------------------------------------------------------------------------
364
371{
372 public:
380 TcpAdvWindowOnLossTest(const std::string& desc,
381 uint32_t size,
382 uint32_t packets,
383 std::vector<uint32_t>& toDrop);
384
385 protected:
386 void ConfigureEnvironment() override;
390
391 private:
396 void InvalidAwndCb(uint16_t oldAwnd, uint16_t newAwnd);
399 std::vector<uint32_t> m_toDrop;
400};
401
403 uint32_t size,
404 uint32_t packets,
405 std::vector<uint32_t>& toDrop)
406 : TcpGeneralTest(desc),
407 m_pktSize(size),
408 m_pktCount(packets),
409 m_toDrop(toDrop)
410{
411}
412
413void
415{
421}
422
425{
426 NS_LOG_FUNCTION(this);
427
430 DynamicCast<TcpSocketAdvertisedWindowProxy>(sock)->SetExpectedSegmentSize(500);
431 DynamicCast<TcpSocketAdvertisedWindowProxy>(sock)->SetInvalidAwndCb(
433
434 return sock;
435}
436
439{
440 auto socket = TcpGeneralTest::CreateSenderSocket(node);
441 socket->SetAttribute("InitialCwnd", UintegerValue(10 * m_pktSize));
442
443 return socket;
444}
445
448{
449 Ptr<TcpSeqErrorModel> m_errorModel = CreateObject<TcpSeqErrorModel>();
450 for (auto it = m_toDrop.begin(); it != m_toDrop.end(); ++it)
451 {
452 m_errorModel->AddSeqToKill(SequenceNumber32(*it));
453 }
454
455 return m_errorModel;
456}
457
458void
459TcpAdvWindowOnLossTest::InvalidAwndCb(uint16_t oldAwnd, uint16_t newAwnd)
460{
461 NS_TEST_ASSERT_MSG_EQ(oldAwnd, newAwnd, "Old and new AWND calculations do not match.");
462}
463
464//-----------------------------------------------------------------------------
465
473{
474 public:
476 : TestSuite("tcp-advertised-window-test", Type::UNIT)
477 {
478 AddTestCase(new TcpAdvertisedWindowTest("TCP advertised window size, small seg + no loss",
479 500,
480 100,
481 0.0),
482 TestCase::Duration::QUICK);
483 AddTestCase(new TcpAdvertisedWindowTest("TCP advertised window size, small seg + loss",
484 500,
485 100,
486 0.1),
487 TestCase::Duration::QUICK);
488 AddTestCase(new TcpAdvertisedWindowTest("TCP advertised window size, large seg + no loss",
489 1000,
490 100,
491 0.0),
492 TestCase::Duration::QUICK);
494 new TcpAdvertisedWindowTest("TCP advertised window size, large seg + small loss",
495 1000,
496 100,
497 0.1),
498 TestCase::Duration::QUICK);
499 AddTestCase(new TcpAdvertisedWindowTest("TCP advertised window size, large seg + big loss",
500 1000,
501 100,
502 0.3),
503 TestCase::Duration::QUICK);
504 AddTestCase(new TcpAdvertisedWindowTest("TCP advertised window size, complete loss",
505 1000,
506 100,
507 1.0),
508 TestCase::Duration::QUICK);
509
510 std::vector<uint32_t> toDrop;
511 toDrop.push_back(8001);
512 toDrop.push_back(9001);
513 AddTestCase(new TcpAdvWindowOnLossTest("TCP advertised window size, after FIN loss",
514 1000,
515 10,
516 toDrop));
517 }
518};
519
521 g_tcpAdvertisedWindowTestSuite; //<! static obj for test initialization
Test the TCP's advertised window size when there is a loss of specific packets.
TcpAdvWindowOnLossTest(const std::string &desc, uint32_t size, uint32_t packets, std::vector< uint32_t > &toDrop)
Constructor.
std::vector< uint32_t > m_toDrop
Sequences to drop.
void InvalidAwndCb(uint16_t oldAwnd, uint16_t newAwnd)
Callback called for the update of the awnd.
Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node) override
Create and install the socket to install on the sender.
void ConfigureEnvironment() override
Change the configuration of the environment.
Ptr< ErrorModel > CreateReceiverErrorModel() override
Create and return the error model to install in the receiver node.
Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node) override
Create and install the socket to install on the receiver.
Test the new formula for calculating TCP's advertised window size.
Ptr< ErrorModel > CreateReceiverErrorModel() override
Create and return the error model to install in the receiver node.
Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node) override
Create and install the socket to install on the receiver.
void ConfigureEnvironment() override
Change the configuration of the environment.
TcpAdvertisedWindowTest(const std::string &desc, uint32_t size, uint32_t packets, double lossRatio)
Constructor.
void InvalidAwndCb(uint16_t oldAwnd, uint16_t newAwnd)
Callback called for the update of the awnd.
Test Suite for TCP adv window.
An error model that randomly drops a given rĂ¡tio of TCP segments.
static TypeId GetTypeId()
Get the type ID.
Ptr< UniformRandomVariable > m_prng
Random variable.
void DoReset() override
Re-initialize any state.
TcpDropRatioErrorModel(double dropRatio)
Constructor.
bool ShouldDrop(const Ipv4Header &ipHeader, const TcpHeader &tcpHeader, uint32_t packetSize) override
Check if the packet should be dropped.
Socket that wraps every call to AdvertisedWindowSize ().
Ptr< TcpSocketBase > Fork() override
Call CopyObject<> to clone me.
void SetInvalidAwndCb(InvalidAwndCallback cb)
Set the invalid AdvWnd callback.
void SetExpectedSegmentSize(uint16_t seg)
Set the expected segment size.
uint16_t m_segmentSize
Test meta-information: size of the segments that are received.
Callback< void, uint16_t, uint16_t > InvalidAwndCallback
typedef for a cb
TcpSocketAdvertisedWindowProxy(const TcpSocketAdvertisedWindowProxy &other)
Copy-constructor.
InvalidAwndCallback m_inwalidAwndCb
Callback.
uint16_t AdvertisedWindowSize(bool scale=true) const override
The amount of Rx window announced to the peer.
static TypeId GetTypeId()
Get the type ID.
uint16_t OldAdvertisedWindowSize(bool scale=true) const
The legacy code used for calculating the advertised window.
Callback template class.
Definition: callback.h:438
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
Packet header for IPv4.
Definition: ipv4-header.h:34
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
A general (TCP-aware) error model.
General infrastructure for TCP testing.
virtual Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node)
Create and install the socket to install on the sender.
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
void SetAppPktSize(uint32_t pktSize)
Set app packet size.
virtual Ptr< TcpSocketMsgBase > CreateSocket(Ptr< Node > node, TypeId socketType, TypeId congControl)
Create a socket.
TypeId m_congControlTypeId
Congestion control.
virtual void ConfigureEnvironment()
Change the configuration of the environment.
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:47
uint16_t m_maxWinSize
Maximum window size to advertise.
uint8_t m_rcvWindShift
Window shift to apply to outgoing segments.
Ptr< TcpSocketState > m_tcb
Congestion control information.
Class for inserting callbacks special points of the flow of TCP sockets.
Ptr< TcpRxBuffer > m_rxBuffer
Rx buffer (reordering buffer)
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
static constexpr auto UNIT
Definition: test.h:1286
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
#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:145
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
static TcpAdvertisedWindowTestSuite g_tcpAdvertisedWindowTestSuite
static const uint32_t packetSize
Packet size generated at the AP.