A Discrete-Event Network Simulator
API
tcp-endpoint-bug2211.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2015 Alexander Krotov <ilabdsf@yandex.ru>
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 /*
21  * Test for bug 2211
22  * https://www.nsnam.org/bugzilla/show_bug.cgi?id=2211
23  *
24  * NOTE: It is a valgrind testcase, it contains no ASSERTs.
25  *
26  * Test creates one node and sets up two TCP sockets on the loopback
27  * with default parameters: CWND = 1, MTU = 536.
28  * Sender socket sends 3 segments.
29  * When first segment is acknowledged, cwnd is raised to 2.
30  * Then, two segments are sent and arrive into receive buffer.
31  * Until bugfix, the following happened:
32  * Ipv4EndPoint::ForwardUp was called for both second and third segment.
33  * These calls scheduled two Ipv4EndPoint::DoForwardUp events.
34  * To demonstrate the bug, test case closes the receiver socket after
35  * receiving the second segment. As a result, Ipv4EndPoint is destroyed.
36  * However, Ipv4EndPoint::DoForwardUp is already scheduled for third segment.
37  * It is a use-after-free bug.
38  */
39 #include <iostream>
40 
41 #include "ns3/test.h"
42 #include "ns3/core-module.h"
43 #include "ns3/network-module.h"
44 #include "ns3/internet-module.h"
45 
46 namespace ns3 {
47 
49 {
50 public:
51  TcpEndPointBug2211Test (std::string desc, bool ipVersion);
52 
53  void Recv (Ptr<Socket> socket);
54  void HandleAccept (Ptr<Socket> s, const Address &from);
55  void HandleConnect (Ptr<Socket> socket);
56  virtual void DoRun ();
57 private:
58  bool m_v6;
59 };
60 
61 void
63 {
64  if (socket->GetRxAvailable() == 536 * 2)
65  {
66  socket->Close();
67  }
68 }
69 
70 void
72 {
74 }
75 
76 void
78 {
79  socket->Send (Create<Packet> (536));
80  socket->Send (Create<Packet> (536));
81  socket->Send (Create<Packet> (536));
82  socket->Close ();
83 }
84 
85 TcpEndPointBug2211Test::TcpEndPointBug2211Test (std::string desc, bool ipVersion) : TestCase (desc)
86 {
87  m_v6 = ipVersion;
88 }
89 
90 void
92 {
93  Ptr<Node> node = CreateObject<Node> ();
94 
95  InternetStackHelper internet;
96  internet.Install (node);
97 
100  if (m_v6 == false)
101  {
103  }
104  else
105  {
107  }
108  sink->Listen ();
109  sink->SetAcceptCallback (MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
111 
112  Ptr<Socket> source = Socket::CreateSocket (node, tid);
113  source->Bind ();
115  MakeNullCallback <void, Ptr<Socket> >());
116  if (m_v6 == false)
117  {
119  }
120  else
121  {
123  }
124 
125  Simulator::Run ();
127 }
128 
130 {
131 public:
132  TcpEndpointBug2211TestSuite () : TestSuite ("tcp-endpoint-bug2211-test", UNIT)
133  {
134  AddTestCase (new TcpEndPointBug2211Test ("Bug 2211 testcase IPv4", false), TestCase::QUICK);
135  AddTestCase (new TcpEndPointBug2211Test ("Bug 2211 testcase IPv6", true), TestCase::QUICK);
136  }
138 
139 } // namespace ns3
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:47
static Ipv6Address GetLoopback()
Get the loopback address.
void HandleAccept(Ptr< Socket > s, const Address &from)
an Inet address class
static Ipv4Address GetAny(void)
Fast test.
Definition: test.h:1152
A suite of tests to run.
Definition: test.h:1333
static void Run(void)
Run the simulation.
Definition: simulator.cc:201
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
aggregate IP/TCP/UDP functionality to existing Nodes.
Callback< R > MakeNullCallback(void)
Definition: callback.h:1635
encapsulates test code
Definition: test.h:1147
This test suite implements a Unit Test.
Definition: test.h:1343
a polymophic address class
Definition: address.h:90
virtual int Listen(void)=0
Listen for incoming connections.
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
An Inet6 address class.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:165
static TypeId GetTypeId(void)
Get the type ID.
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
void Recv(Ptr< Socket > socket)
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::TcpEndpointBug2211TestSuite g_TcpEndPoint2211TestSuite
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
static Ipv4Address GetLoopback(void)
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
Definition: socket.cc:104
void HandleConnect(Ptr< Socket > socket)
TcpEndPointBug2211Test(std::string desc, bool ipVersion)
virtual void DoRun()
Implementation to actually run this TestCase.
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition: socket.cc:84
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.
a unique identifier for an interface.
Definition: type-id.h:58
virtual uint32_t GetRxAvailable(void) const =0
Return number of bytes which can be returned from one or multiple calls to Recv.