A Discrete-Event Network Simulator
API
tcp-timestamp-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 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 "ns3/test.h"
21 #include "ns3/socket-factory.h"
22 #include "ns3/tcp-socket-factory.h"
23 #include "ns3/simulator.h"
24 #include "ns3/simple-channel.h"
25 #include "ns3/simple-net-device.h"
26 #include "ns3/drop-tail-queue.h"
27 #include "ns3/config.h"
28 #include "ns3/ipv4-static-routing.h"
29 #include "ns3/ipv4-list-routing.h"
30 #include "ns3/ipv6-static-routing.h"
31 #include "ns3/ipv6-list-routing.h"
32 #include "ns3/node.h"
33 #include "ns3/inet-socket-address.h"
34 #include "ns3/inet6-socket-address.h"
35 #include "ns3/uinteger.h"
36 #include "ns3/log.h"
37 #include "ns3/tcp-socket-base.h"
38 
39 #include "ns3/arp-l3-protocol.h"
40 #include "ns3/ipv4-l3-protocol.h"
41 #include "ns3/ipv6-l3-protocol.h"
42 #include "ns3/icmpv4-l4-protocol.h"
43 #include "ns3/icmpv6-l4-protocol.h"
44 #include "ns3/udp-l4-protocol.h"
45 #include "ns3/tcp-l4-protocol.h"
46 
47 #include "ns3/private/tcp-option-ts.h"
48 
49 namespace ns3 {
50 
51 NS_LOG_COMPONENT_DEFINE ("TimestampTestSuite");
52 
54 {
55 public:
57  {
62  };
63 
65 
66 private:
67  virtual void DoRun (void);
68  virtual void DoTeardown (void);
69 
70  void SetupDefaultSim (void);
71  //void SetupDefaultSim6 (void);
72 
75  Ptr<SimpleNetDevice> AddSimpleNetDevice (Ptr<Node> node, const char* ipaddr, const char* netmask);
77  void ServerHandleConnectionCreated (Ptr<Socket> s, const Address & addr);
78  void ServerHandleRecv (Ptr<Socket> sock);
79  void ServerHandleSend (Ptr<Socket> sock, uint32_t sendB);
80  void SourceHandleSend (Ptr<Socket> sock, uint32_t available);
81  void SourceHandleRecv (Ptr<Socket> sock);
82 
84 
85  uint32_t m_totalBytes;
87  uint32_t m_sourceReadSize;
89  uint32_t m_serverReadSize;
94 };
95 
97  : TestCase ("Testing the TCP Timestamp option")
98 {
99  m_configuration = conf;
100  m_totalBytes = 2000;
101  m_sourceWriteSize = 500;
102  m_sourceReadSize = 500;
103  m_serverWriteSize = 500;
104  m_serverReadSize = 500;
105 }
106 
107 void
109 {
114 
115 
116 // if (m_useIpv6 == true)
117 // {
118 // SetupDefaultSim6 ();
119 // }
120 // else
121 // {
122  SetupDefaultSim ();
123 // }
124 
125  Simulator::Run ();
126 
127  NS_TEST_EXPECT_MSG_EQ (m_currentSourceTxBytes, m_totalBytes, "Source sent all bytes");
128  NS_TEST_EXPECT_MSG_EQ (m_currentServerRxBytes, m_totalBytes, "Server received all bytes");
129  NS_TEST_EXPECT_MSG_EQ (m_currentSourceRxBytes, m_totalBytes, "Source received all bytes");
130 }
131 
132 void
134 {
136 }
137 
138 void
140 {
143 }
144 
145 void
147 {
148  while (sock->GetRxAvailable () > 0)
149  {
150  uint32_t toRead = std::min (m_serverReadSize, sock->GetRxAvailable ());
151  Ptr<Packet> p = sock->Recv (toRead, 0);
152 
153  if (p == 0 && sock->GetErrno () != Socket::ERROR_NOTERROR)
154  {
155  NS_FATAL_ERROR ("Server could not read stream at byte " << m_currentServerRxBytes);
156  }
157 
158  m_currentServerRxBytes += p->GetSize ();
159 
160  ServerHandleSend (sock, sock->GetTxAvailable ());
161  }
162 }
163 
164 void
166 {
168  {
170  uint32_t toSend = std::min (left, sock->GetTxAvailable ());
171  toSend = std::min (toSend, m_serverWriteSize);
172 
173  Ptr<Packet> p = Create<Packet> (toSend);
174 
175  int sent = sock->Send (p);
176 
177  NS_TEST_EXPECT_MSG_EQ ((sent != -1), true, "Server error during send ?");
178 
179  m_currentServerTxBytes += sent;
180  }
181 
183  {
184  sock->Close ();
185  }
186 }
187 
188 void
190 {
191  while (sock->GetTxAvailable () > 0 && m_currentSourceTxBytes < m_totalBytes)
192  {
193  uint32_t left = m_totalBytes - m_currentSourceTxBytes;
194  uint32_t toSend = std::min (left, sock->GetTxAvailable ());
195  toSend = std::min (toSend, m_sourceWriteSize);
196 
197  Ptr<Packet> p = Create<Packet> (toSend);
198 
199  int sent = sock->Send (p);
200  NS_TEST_EXPECT_MSG_EQ ((sent != -1), true, "Error during send ?");
201  m_currentSourceTxBytes += sent;
202  }
203 }
204 
205 void
207 {
208  while (sock->GetRxAvailable () > 0 && m_currentSourceRxBytes < m_totalBytes)
209  {
210  uint32_t toRead = std::min (m_sourceReadSize, sock->GetRxAvailable ());
211  Ptr<Packet> p = sock->Recv (toRead, 0);
212 
213  if (p == 0 && sock->GetErrno () != Socket::ERROR_NOTERROR)
214  {
215  NS_FATAL_ERROR ("Source could not read stream at byte " << m_currentSourceRxBytes);
216  }
217 
218  m_currentSourceRxBytes += p->GetSize ();
219  }
220 
222  {
223  sock->Close ();
224  }
225 }
226 
227 Ptr<Node>
229 {
230  Ptr<Node> node = CreateObject<Node> ();
231  //ARP
232  Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
233  node->AggregateObject (arp);
234  //IPV4
235  Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
236  //Routing for Ipv4
237  Ptr<Ipv4ListRouting> ipv4Routing = CreateObject<Ipv4ListRouting> ();
238  ipv4->SetRoutingProtocol (ipv4Routing);
239  Ptr<Ipv4StaticRouting> ipv4staticRouting = CreateObject<Ipv4StaticRouting> ();
240  ipv4Routing->AddRoutingProtocol (ipv4staticRouting, 0);
241  node->AggregateObject (ipv4);
242  //ICMP
243  Ptr<Icmpv4L4Protocol> icmp = CreateObject<Icmpv4L4Protocol> ();
244  node->AggregateObject (icmp);
245  //UDP
246  Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
247  node->AggregateObject (udp);
248  //TCP
249  Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
250  node->AggregateObject (tcp);
251  return node;
252 }
253 
255 TimestampTestCase::AddSimpleNetDevice (Ptr<Node> node, const char* ipaddr, const char* netmask)
256 {
257  Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
258  dev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
259  node->AddDevice (dev);
260  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
261  uint32_t ndid = ipv4->AddInterface (dev);
262  Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address (ipaddr), Ipv4Mask (netmask));
263  ipv4->AddAddress (ndid, ipv4Addr);
264  ipv4->SetUp (ndid);
265  return dev;
266 }
267 
268 void
270 {
271  const char* netmask = "255.255.255.0";
272  const char* ipaddr0 = "192.168.1.1";
273  const char* ipaddr1 = "192.168.1.2";
274  Ptr<Node> node0 = CreateInternetNode ();
275  Ptr<Node> node1 = CreateInternetNode ();
276  Ptr<SimpleNetDevice> dev0 = AddSimpleNetDevice (node0, ipaddr0, netmask);
277  Ptr<SimpleNetDevice> dev1 = AddSimpleNetDevice (node1, ipaddr1, netmask);
278 
279  Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
280  dev0->SetChannel (channel);
281  dev1->SetChannel (channel);
282 
283  Ptr<SocketFactory> sockFactory0 = node0->GetObject<TcpSocketFactory> ();
284  Ptr<SocketFactory> sockFactory1 = node1->GetObject<TcpSocketFactory> ();
285 
286  Ptr<TcpSocketBase> server = DynamicCast<TcpSocketBase> (sockFactory0->CreateSocket ());
287  Ptr<TcpSocketBase> source = DynamicCast<TcpSocketBase> (sockFactory1->CreateSocket ());
288 
289  NS_ASSERT (server != 0);
290  NS_ASSERT (source != 0);
291 
292  switch (m_configuration)
293  {
294  case DISABLED:
295  server->SetAttribute ("Timestamp", BooleanValue (false));
296  source->SetAttribute ("Timestamp", BooleanValue (false));
297  break;
298 
299  case ENABLED_CLIENT:
300  server->SetAttribute ("Timestamp", BooleanValue (false));
301  source->SetAttribute ("Timestamp", BooleanValue (true));
302  break;
303 
304  case ENABLED_SERVER:
305  server->SetAttribute ("Timestamp", BooleanValue (true));
306  source->SetAttribute ("Timestamp", BooleanValue (false));
307  break;
308 
309  case ENABLED:
310  server->SetAttribute ("Timestamp", BooleanValue (true));
311  source->SetAttribute ("Timestamp", BooleanValue (true));
312  break;
313  }
314 
315  uint16_t port = 50000;
316  InetSocketAddress serverlocaladdr (Ipv4Address::GetAny (), port);
317  InetSocketAddress serverremoteaddr (Ipv4Address (ipaddr0), port);
318 
319  server->Bind (serverlocaladdr);
320  server->Listen ();
321  server->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
323 
324  source->SetRecvCallback (MakeCallback (&TimestampTestCase::SourceHandleRecv, this));
325  source->SetSendCallback (MakeCallback (&TimestampTestCase::SourceHandleSend, this));
326 
327  source->Connect (serverremoteaddr);
328 }
329 
331 {
332 public:
333  TimestampValueTestCase (double startTime, double timeToWait,
334  std::string name);
335 
336 private:
337  virtual void DoRun (void);
338  virtual void DoTeardown (void);
339 
340  void Check ();
341  void Init ();
342 
343  double m_startTime;
344  double m_timeToWait;
345  double m_initValue;
346 };
347 
349  double timeToWait,
350  std::string name)
351  : TestCase (name)
352 {
354  m_timeToWait = timeToWait;
355 }
356 
357 void
359 {
364 
365  Simulator::Run ();
366 }
367 
368 void
370 {
372 }
373 
374 void
376 {
378 }
379 
380 void
382 {
383  uint32_t lastValue = TcpOptionTS::NowToTsValue ();
384 
386  MilliSeconds (1), "Different TS values");
387 
389  MilliSeconds (1), "Estimating Wrong RTT");
390 }
391 
392 static class TcpTimestampTestSuite : public TestSuite
393 {
394 public:
396  : TestSuite ("tcp-timestamp", UNIT)
397  {
402  AddTestCase (new TimestampValueTestCase (0.0, 0.01, "Value Check"), TestCase::QUICK);
403  AddTestCase (new TimestampValueTestCase (3.0, 0.5, "Value Check"), TestCase::QUICK);
404  AddTestCase (new TimestampValueTestCase (5.5, 1.0, "Value Check"), TestCase::QUICK);
405  AddTestCase (new TimestampValueTestCase (6.0, 2.0, "Value Check"), TestCase::QUICK);
406  AddTestCase (new TimestampValueTestCase (2.4, 0.7, "Value Check"), TestCase::QUICK);
407 
408  }
409 
411 
412 } // namespace ns3
tuple channel
Definition: third.py:85
an Inet address class
static Ipv4Address GetAny(void)
AttributeValue implementation for Boolean.
Definition: boolean.h:34
void ServerHandleConnectionCreated(Ptr< Socket > s, const Address &addr)
static Time ElapsedTimeFromTsValue(uint32_t echoTime)
Estimate the Time elapsed from a TS echo value.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
API to create TCP socket instances.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:226
Fast test.
Definition: test.h:1152
A suite of tests to run.
Definition: test.h:1333
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:246
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
static void Run(void)
Run the simulation.
Definition: simulator.cc:200
#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
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:278
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:145
Callback< R > MakeNullCallback(void)
Definition: callback.h:1626
Definition: conf.py:1
encapsulates test code
Definition: test.h:1147
This test suite implements a Unit Test.
Definition: test.h:1343
Ptr< Node > CreateInternetNode6(void)
ns3::TcpTimestampTestSuite g_tcpTimestampTestSuite
virtual enum Socket::SocketErrno GetErrno(void) const =0
Get last error number.
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:90
TimestampTestCase(TimestampTestCase::Configuration conf)
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1216
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:297
double startTime
TimestampValueTestCase(double startTime, double timeToWait, std::string name)
Ptr< SimpleNetDevice > AddSimpleNetDevice(Ptr< Node > node, const char *ipaddr, const char *netmask)
void ServerHandleSend(Ptr< Socket > sock, uint32_t sendB)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1480
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:373
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:164
void SourceHandleRecv(Ptr< Socket > sock)
static Mac48Address ConvertFrom(const Address &address)
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
Ptr< Node > CreateInternetNode(void)
void SourceHandleSend(Ptr< Socket > sock, uint32_t available)
void ServerHandleRecv(Ptr< Socket > sock)
void SetSendCallback(Callback< void, Ptr< Socket >, uint32_t > sendCb)
Notify application when space in transmit buffer is added.
Definition: socket.cc:121
static uint32_t NowToTsValue()
Return an uint32_t value which represent "now".
Describes an IPv6 address.
Definition: ipv6-address.h:47
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:121
a class to store IPv4 address information on an interface
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
Ptr< SimpleNetDevice > AddSimpleNetDevice6(Ptr< Node > node, Ipv6Address ipaddr, Ipv6Prefix prefix)
Describes an IPv6 prefix.
Definition: ipv6-address.h:389
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual int Close(void)=0
Close a socket.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual uint32_t GetTxAvailable(void) const =0
Returns the number of bytes which can be sent in a single call to Send.
virtual uint32_t GetRxAvailable(void) const =0
Return number of bytes which can be returned from one or multiple calls to Recv.