diff --git a/CHANGES.html b/CHANGES.html
index 02c50fed1..bee376e75 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -63,7 +63,9 @@ nodes to be placed outside of buildings defined in the scenario.
Changes to existing API:
TrafficControlHelper::Install now only includes root queue discs in the returned
- QueueDiscContainer.
+ QueueDiscContainer.
+
Recovery algorithms are now in a different class, instead of being tied to TcpSocketBase.
+ Take a look to TcpRecoveryOps for more information.
Changes to build system:
diff --git a/src/internet/doc/tcp.rst b/src/internet/doc/tcp.rst
index e8cafc2fa..93a2e0d2e 100644
--- a/src/internet/doc/tcp.rst
+++ b/src/internet/doc/tcp.rst
@@ -867,11 +867,63 @@ provided by TcpTxBuffer to query the scoreboard; please refer to the Doxygen
documentation (and to in-code comments) if you want to learn more about this
implementation.
+Loss Recovery Algorithms
+++++++++++++++++++++++++
+The following loss recovery algorithms are supported in ns-3 TCP:
+
+Classic Recovery
+^^^^^^^^^^^^^^^^
+Classic Recovery refers to the combination of NewReno algorithm described in
+RFC 6582 along with SACK based loss recovery algorithm mentioned in RFC 6675.
+SACK based loss recovery is used when sender and receiver support SACK options.
+In the case when SACK options are disabled, the NewReno modification handles
+the recovery.
+
+At the start of recovery phase the congestion window is reduced diffently for
+NewReno and SACK based recovery. For NewReno the reduction is done as given below:
+
+.. math:: cWnd = ssThresh
+
+For SACK based recovery, this is done as follows:
+
+.. math:: cWnd = ssThresh + (dupAckCount * segmentSize)
+
+While in the recovery phase, the congestion window is inflated by segmentSize
+on arrival of every ACK when NewReno is used. The congestion window is kept
+same when SACK based loss recovery is used.
+
+Adding a new loss recovery algorithm in ns-3
+++++++++++++++++++++++++++++++++++++++++++++
+
+Writing (or porting) a loss recovery algorithms from scratch (or from
+other systems) is a process completely separated from the internals of
+TcpSocketBase.
+
+All operations that are delegated to a loss recovery are contained in
+the class TcpRecoveryOps and are given below:
+
+.. code-block:: c++
+
+ virtual std::string GetName () const;
+ virtual void EnterRecovery (Ptr tcb, uint32_t unAckDataCount,
+ bool isSackEnabled, uint32_t dupAckCount,
+ uint32_t bytesInFlight, uint32_t lastDeliveredBytes);
+ virtual void DoRecovery (Ptr tcb, uint32_t unAckDataCount,
+ bool isSackEnabled, uint32_t dupAckCount,
+ uint32_t bytesInFlight, uint32_t lastDeliveredBytes);
+ virtual void ExitRecovery (Ptr tcb, uint32_t bytesInFlight);
+ virtual Ptr Fork ();
+
+EnterRecovery is called when packet loss is detected and recovery is triggered.
+While in recovery phase, each time when an ACK arrives, DoRecovery is called which
+performs the necessary congestion window changes as per the recovery algorithm.
+ExitRecovery is called just prior to exiting recovery phase in order to perform the
+required congestion window ajustments.
+
Current limitations
+++++++++++++++++++
* TcpCongestionOps interface does not contain every possible Linux operation
-* Fast retransmit / fast recovery are bound with TcpSocketBase, thereby preventing easy simulation of TCP Tahoe
.. _Writing-tcp-tests:
diff --git a/src/internet/model/tcp-bic.h b/src/internet/model/tcp-bic.h
index 4563cf82b..8428a77fd 100644
--- a/src/internet/model/tcp-bic.h
+++ b/src/internet/model/tcp-bic.h
@@ -21,6 +21,7 @@
#define TCPBIC_H
#include "ns3/tcp-congestion-ops.h"
+#include "ns3/tcp-recovery-ops.h"
class TcpBicIncrementTest;
class TcpBicDecrementTest;
diff --git a/src/internet/model/tcp-congestion-ops.h b/src/internet/model/tcp-congestion-ops.h
index 4e74d8c2b..10e251a59 100644
--- a/src/internet/model/tcp-congestion-ops.h
+++ b/src/internet/model/tcp-congestion-ops.h
@@ -20,6 +20,7 @@
#define TCPCONGESTIONOPS_H
#include "ns3/tcp-socket-base.h"
+#include "ns3/tcp-recovery-ops.h"
namespace ns3 {
diff --git a/src/internet/model/tcp-highspeed.h b/src/internet/model/tcp-highspeed.h
index 1afb42f89..c65ff3a80 100644
--- a/src/internet/model/tcp-highspeed.h
+++ b/src/internet/model/tcp-highspeed.h
@@ -21,6 +21,7 @@
#define TCPHIGHSPEED_H
#include "ns3/tcp-congestion-ops.h"
+#include "ns3/tcp-recovery-ops.h"
namespace ns3 {
diff --git a/src/internet/model/tcp-htcp.h b/src/internet/model/tcp-htcp.h
index 73388fab1..ea19c31c7 100644
--- a/src/internet/model/tcp-htcp.h
+++ b/src/internet/model/tcp-htcp.h
@@ -28,6 +28,7 @@
#define TCP_HTCP_H
#include "ns3/tcp-congestion-ops.h"
+#include "ns3/tcp-recovery-ops.h"
namespace ns3 {
diff --git a/src/internet/model/tcp-hybla.h b/src/internet/model/tcp-hybla.h
index 9bae424c7..68561679e 100644
--- a/src/internet/model/tcp-hybla.h
+++ b/src/internet/model/tcp-hybla.h
@@ -20,6 +20,7 @@
#define TCPHYBLA_H
#include "ns3/tcp-congestion-ops.h"
+#include "ns3/tcp-recovery-ops.h"
#include "ns3/traced-value.h"
namespace ns3 {
diff --git a/src/internet/model/tcp-illinois.h b/src/internet/model/tcp-illinois.h
index 64245a982..90ac5e573 100644
--- a/src/internet/model/tcp-illinois.h
+++ b/src/internet/model/tcp-illinois.h
@@ -29,6 +29,7 @@
#define TCPILLINOIS_H
#include "ns3/tcp-congestion-ops.h"
+#include "ns3/tcp-recovery-ops.h"
namespace ns3 {
diff --git a/src/internet/model/tcp-l4-protocol.cc b/src/internet/model/tcp-l4-protocol.cc
index c31821fb6..ef05a98dc 100644
--- a/src/internet/model/tcp-l4-protocol.cc
+++ b/src/internet/model/tcp-l4-protocol.cc
@@ -42,6 +42,7 @@
#include "tcp-socket-factory-impl.h"
#include "tcp-socket-base.h"
#include "tcp-congestion-ops.h"
+#include "tcp-recovery-ops.h"
#include "rtt-estimator.h"
#include
@@ -80,6 +81,11 @@ TcpL4Protocol::GetTypeId (void)
TypeIdValue (TcpNewReno::GetTypeId ()),
MakeTypeIdAccessor (&TcpL4Protocol::m_congestionTypeId),
MakeTypeIdChecker ())
+ .AddAttribute ("RecoveryType",
+ "Recovery type of TCP objects.",
+ TypeIdValue (ClassicRecovery::GetTypeId ()),
+ MakeTypeIdAccessor (&TcpL4Protocol::m_recoveryTypeId),
+ MakeTypeIdChecker ())
.AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
ObjectVectorValue (),
MakeObjectVectorAccessor (&TcpL4Protocol::m_sockets),
@@ -175,22 +181,26 @@ TcpL4Protocol::DoDispose (void)
}
Ptr
-TcpL4Protocol::CreateSocket (TypeId congestionTypeId)
+TcpL4Protocol::CreateSocket (TypeId congestionTypeId, TypeId recoveryTypeId)
{
NS_LOG_FUNCTION (this << congestionTypeId.GetName ());
ObjectFactory rttFactory;
ObjectFactory congestionAlgorithmFactory;
+ ObjectFactory recoveryAlgorithmFactory;
rttFactory.SetTypeId (m_rttTypeId);
congestionAlgorithmFactory.SetTypeId (congestionTypeId);
+ recoveryAlgorithmFactory.SetTypeId (recoveryTypeId);
Ptr rtt = rttFactory.Create ();
Ptr socket = CreateObject ();
Ptr algo = congestionAlgorithmFactory.Create ();
+ Ptr recovery = recoveryAlgorithmFactory.Create ();
socket->SetNode (m_node);
socket->SetTcp (this);
socket->SetRtt (rtt);
socket->SetCongestionControlAlgorithm (algo);
+ socket->SetRecoveryAlgorithm (recovery);
m_sockets.push_back (socket);
return socket;
@@ -199,7 +209,7 @@ TcpL4Protocol::CreateSocket (TypeId congestionTypeId)
Ptr
TcpL4Protocol::CreateSocket (void)
{
- return CreateSocket (m_congestionTypeId);
+ return CreateSocket (m_congestionTypeId, m_recoveryTypeId);
}
Ipv4EndPoint *
diff --git a/src/internet/model/tcp-l4-protocol.h b/src/internet/model/tcp-l4-protocol.h
index bbf87b5e9..ad089b107 100644
--- a/src/internet/model/tcp-l4-protocol.h
+++ b/src/internet/model/tcp-l4-protocol.h
@@ -113,7 +113,7 @@ public:
*
* \param congestionTypeId the congestion control algorithm TypeId
*/
- Ptr CreateSocket (TypeId congestionTypeId);
+ Ptr CreateSocket (TypeId congestionTypeId, TypeId recoveryTypeId);
/**
* \brief Allocate an IPv4 Endpoint
@@ -306,6 +306,7 @@ private:
Ipv6EndPointDemux *m_endPoints6; //!< A list of IPv6 end points.
TypeId m_rttTypeId; //!< The RTT Estimator TypeId
TypeId m_congestionTypeId; //!< The socket TypeId
+ TypeId m_recoveryTypeId; //!< The recovery TypeId
std::vector > m_sockets; //!< list of sockets
IpL4Protocol::DownTargetCallback m_downTarget; //!< Callback to send packets over IPv4
IpL4Protocol::DownTargetCallback6 m_downTarget6; //!< Callback to send packets over IPv6
diff --git a/src/internet/model/tcp-ledbat.h b/src/internet/model/tcp-ledbat.h
index 357026f83..a5458b7e1 100644
--- a/src/internet/model/tcp-ledbat.h
+++ b/src/internet/model/tcp-ledbat.h
@@ -24,6 +24,7 @@
#include
#include "ns3/tcp-congestion-ops.h"
+#include "ns3/tcp-recovery-ops.h"
namespace ns3 {
diff --git a/src/internet/model/tcp-lp.h b/src/internet/model/tcp-lp.h
index 8924af01f..d15ec17e7 100644
--- a/src/internet/model/tcp-lp.h
+++ b/src/internet/model/tcp-lp.h
@@ -25,6 +25,7 @@
#define TCPLP_H
#include "ns3/tcp-congestion-ops.h"
+#include "ns3/tcp-recovery-ops.h"
#include "ns3/traced-value.h"
namespace ns3 {
diff --git a/src/internet/model/tcp-recovery-ops.cc b/src/internet/model/tcp-recovery-ops.cc
new file mode 100644
index 000000000..d3ec83c2d
--- /dev/null
+++ b/src/internet/model/tcp-recovery-ops.cc
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2018 NITK Surathkal
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Viyom Mittal
+ * Vivek Jain
+ * Mohit P. Tahiliani
+ *
+ */
+#include "tcp-recovery-ops.h"
+#include "tcp-socket-base.h"
+#include "tcp-congestion-ops.h"
+#include "ns3/log.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("TcpRecoveryOps");
+
+NS_OBJECT_ENSURE_REGISTERED (TcpRecoveryOps);
+
+TypeId
+TcpRecoveryOps::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::TcpRecoveryOps")
+ .SetParent