1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 Alexander Krotov <krotov@iitp.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 #include <iostream>
21 
22 #include "ns3/test.h"
23 #include "ns3/core-module.h"
24 #include "ns3/network-module.h"
25 #include "ns3/internet-module.h"
26 
27 using namespace ns3;
28 
29 /**
30  * \ingroup internet-test
31  * \ingroup tests
32  *
33  * \brief Test that connection failed callback is called when
34  * SYN retransmission number is exceeded.
35  */
36 class TcpSynConnectionFailedTest : public TestCase
37 {
38 public:
39   /**
40    * Constructor.
41    * \param desc Test description.
42    * \param useEcn Whether to enable ECN.
43    */
44   TcpSynConnectionFailedTest (std::string desc, bool useEcn);
45 
46   /**
47    * \brief Handle a connection failure.
48    * \param socket The receiving socket.
49    */
50   void HandleConnectionFailed (Ptr<Socket> socket);
51   virtual void DoRun ();
52 
53 private:
54   bool m_connectionFailed{false}; //!< Connection failure indicator
55   bool m_useEcn {false}; //!< Use ECN (true or false)
56 };
57 
TcpSynConnectionFailedTest(std::string desc,bool useEcn)58 TcpSynConnectionFailedTest::TcpSynConnectionFailedTest (std::string desc, bool useEcn) : TestCase (desc), m_useEcn (useEcn)
59 {
60 }
61 
62 void
HandleConnectionFailed(Ptr<Socket> socket)63 TcpSynConnectionFailedTest::HandleConnectionFailed (Ptr<Socket> socket)
64 {
65   m_connectionFailed = true;
66 }
67 
68 void
DoRun()69 TcpSynConnectionFailedTest::DoRun ()
70 {
71   Ptr<Node> node = CreateObject<Node> ();
72 
73   InternetStackHelper internet;
74   internet.Install (node);
75 
76   TypeId tid = TcpSocketFactory::GetTypeId ();
77 
78   Ptr<Socket> socket = Socket::CreateSocket (node, tid);
79   if (m_useEcn)
80     {
81       Ptr<TcpSocketBase> tcpSocket = DynamicCast<TcpSocketBase> (socket);
82       tcpSocket->SetUseEcn (TcpSocketState::On);
83     }
84   socket->Bind ();
85   socket->SetConnectCallback (MakeNullCallback <void, Ptr<Socket>>(),
86                               MakeCallback (&TcpSynConnectionFailedTest::HandleConnectionFailed, this));
87   socket->Connect (InetSocketAddress (Ipv4Address::GetLoopback (), 9));
88 
89   Simulator::Run ();
90   Simulator::Destroy ();
91 
92   NS_TEST_ASSERT_MSG_EQ (m_connectionFailed, true, "Connection failed callback was not called");
93 }
94 
95 /**
96  * \ingroup internet-test
97  * \ingroup tests
98  *
99  * \brief TestSuite
100  */
101 class TcpSynConnectionFailedTestSuite : public TestSuite
102 {
103 public:
TcpSynConnectionFailedTestSuite()104   TcpSynConnectionFailedTestSuite () : TestSuite ("tcp-syn-connection-failed-test", UNIT)
105   {
106     AddTestCase (new TcpSynConnectionFailedTest ("TCP SYN connection failed test no ECN", false), TestCase::QUICK);
107     AddTestCase (new TcpSynConnectionFailedTest ("TCP SYN connection failed test with ECN", true), TestCase::QUICK);
108   }
109 };
110 
111 static TcpSynConnectionFailedTestSuite g_TcpSynConnectionFailedTestSuite; //!< Static variable for test initialization
112