tcp: Modularization of Fast Recovery - I
This commit is contained in:
@@ -63,7 +63,9 @@ nodes to be placed outside of buildings defined in the scenario.</li>
|
||||
<h2>Changes to existing API:</h2>
|
||||
<ul>
|
||||
<li>TrafficControlHelper::Install now only includes root queue discs in the returned
|
||||
QueueDiscContainer.</li>
|
||||
QueueDiscContainer.</li>
|
||||
<li>Recovery algorithms are now in a different class, instead of being tied to TcpSocketBase.
|
||||
Take a look to TcpRecoveryOps for more information.</li>
|
||||
</ul>
|
||||
<h2>Changes to build system:</h2>
|
||||
<ul>
|
||||
|
||||
@@ -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<const TcpSocketState> tcb, uint32_t unAckDataCount,
|
||||
bool isSackEnabled, uint32_t dupAckCount,
|
||||
uint32_t bytesInFlight, uint32_t lastDeliveredBytes);
|
||||
virtual void DoRecovery (Ptr<const TcpSocketState> tcb, uint32_t unAckDataCount,
|
||||
bool isSackEnabled, uint32_t dupAckCount,
|
||||
uint32_t bytesInFlight, uint32_t lastDeliveredBytes);
|
||||
virtual void ExitRecovery (Ptr<TcpSocketState> tcb, uint32_t bytesInFlight);
|
||||
virtual Ptr<TcpRecoveryOps> 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:
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define TCPBIC_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
class TcpBicIncrementTest;
|
||||
class TcpBicDecrementTest;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define TCPCONGESTIONOPS_H
|
||||
|
||||
#include "ns3/tcp-socket-base.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define TCPHIGHSPEED_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define TCP_HTCP_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define TCPILLINOIS_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -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 <vector>
|
||||
@@ -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<Socket>
|
||||
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<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();
|
||||
Ptr<TcpSocketBase> socket = CreateObject<TcpSocketBase> ();
|
||||
Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps> ();
|
||||
Ptr<TcpRecoveryOps> recovery = recoveryAlgorithmFactory.Create<TcpRecoveryOps> ();
|
||||
|
||||
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<Socket>
|
||||
TcpL4Protocol::CreateSocket (void)
|
||||
{
|
||||
return CreateSocket (m_congestionTypeId);
|
||||
return CreateSocket (m_congestionTypeId, m_recoveryTypeId);
|
||||
}
|
||||
|
||||
Ipv4EndPoint *
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
*
|
||||
* \param congestionTypeId the congestion control algorithm TypeId
|
||||
*/
|
||||
Ptr<Socket> CreateSocket (TypeId congestionTypeId);
|
||||
Ptr<Socket> 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<Ptr<TcpSocketBase> > 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
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
124
src/internet/model/tcp-recovery-ops.cc
Normal file
124
src/internet/model/tcp-recovery-ops.cc
Normal file
@@ -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 <viyommittal@gmail.com>
|
||||
* Vivek Jain <jain.vivek.anand@gmail.com>
|
||||
* Mohit P. Tahiliani <tahiliani@nitk.edu.in>
|
||||
*
|
||||
*/
|
||||
#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<Object> ()
|
||||
.SetGroupName ("Internet")
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TcpRecoveryOps::TcpRecoveryOps () : Object ()
|
||||
{
|
||||
}
|
||||
|
||||
TcpRecoveryOps::TcpRecoveryOps (const TcpRecoveryOps &other) : Object (other)
|
||||
{
|
||||
}
|
||||
|
||||
TcpRecoveryOps::~TcpRecoveryOps ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Classic recovery
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (ClassicRecovery);
|
||||
|
||||
TypeId
|
||||
ClassicRecovery::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::ClassicRecovery")
|
||||
.SetParent<TcpRecoveryOps> ()
|
||||
.SetGroupName ("Internet")
|
||||
.AddConstructor<ClassicRecovery> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
ClassicRecovery::ClassicRecovery (void) : TcpRecoveryOps ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
ClassicRecovery::ClassicRecovery (const ClassicRecovery& sock)
|
||||
: TcpRecoveryOps (sock)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
ClassicRecovery::~ClassicRecovery (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ClassicRecovery::EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount)
|
||||
{
|
||||
tcb->m_cWnd = tcb->m_ssThresh;
|
||||
tcb->m_cWndInfl = tcb->m_ssThresh + (dupAckCount * tcb->m_segmentSize);
|
||||
}
|
||||
|
||||
void
|
||||
ClassicRecovery::DoRecovery (Ptr<TcpSocketState> tcb)
|
||||
{
|
||||
tcb->m_cWndInfl += tcb->m_segmentSize;
|
||||
}
|
||||
|
||||
void
|
||||
ClassicRecovery::ExitRecovery (Ptr<TcpSocketState> tcb)
|
||||
{
|
||||
// Follow NewReno procedures to exit FR if SACK is disabled
|
||||
// (RFC2582 sec.3 bullet #5 paragraph 2, option 2)
|
||||
// For SACK connections, we maintain the cwnd = ssthresh. In fact,
|
||||
// this ACK was received in RECOVERY phase, not in OPEN. So we
|
||||
// are not allowed to increase the window
|
||||
tcb->m_cWndInfl = tcb->m_ssThresh.Get ();
|
||||
}
|
||||
|
||||
std::string
|
||||
ClassicRecovery::GetName () const
|
||||
{
|
||||
return "ClassicRecovery";
|
||||
}
|
||||
|
||||
Ptr<TcpRecoveryOps>
|
||||
ClassicRecovery::Fork ()
|
||||
{
|
||||
return CopyObject<ClassicRecovery> (this);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
183
src/internet/model/tcp-recovery-ops.h
Normal file
183
src/internet/model/tcp-recovery-ops.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/* -*- 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 <viyommittal@gmail.com>
|
||||
* Vivek Jain <jain.vivek.anand@gmail.com>
|
||||
* Mohit P. Tahiliani <tahiliani@nitk.edu.in>
|
||||
*
|
||||
*/
|
||||
#ifndef TCPRECOVERYOPS_H
|
||||
#define TCPRECOVERYOPS_H
|
||||
|
||||
#include "ns3/tcp-socket-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup tcp
|
||||
* \defgroup recoveryOps Recovery Algorithms.
|
||||
*
|
||||
* The various recovery algorithms used in recovery phase of TCP.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \ingroup recoveryOps
|
||||
*
|
||||
* \brief recovery abstract class
|
||||
*
|
||||
* The design is inspired by the TcpCongestionOps class in ns-3. The fast
|
||||
* recovery is splitted from the main socket code, and it is a pluggable
|
||||
* component. An interface has been defined; variables are maintained in the
|
||||
* TcpSocketState class, while subclasses of TcpRecoveryOps operate over an
|
||||
* instance of that class.
|
||||
*
|
||||
* \see DoRecovery
|
||||
*/
|
||||
class TcpRecoveryOps : public Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
*/
|
||||
TcpRecoveryOps ();
|
||||
|
||||
/**
|
||||
* \brief Copy constructor.
|
||||
* \param other object to copy.
|
||||
*/
|
||||
TcpRecoveryOps (const TcpRecoveryOps &other);
|
||||
|
||||
/**
|
||||
* \brief Deconstructor
|
||||
*/
|
||||
virtual ~TcpRecoveryOps ();
|
||||
|
||||
/**
|
||||
* \brief Get the name of the recovery algorithm
|
||||
*
|
||||
* \return A string identifying the name
|
||||
*/
|
||||
virtual std::string GetName () const = 0;
|
||||
|
||||
/**
|
||||
* \brief Performs variable initialization at the start of recovery
|
||||
*
|
||||
* The function is called when the TcpSocketState is changed to CA_RECOVERY.
|
||||
*
|
||||
* \param tcb internal congestion state
|
||||
* \param dupAckCount duplicate acknowldgement count
|
||||
*/
|
||||
virtual void EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount)
|
||||
{
|
||||
NS_UNUSED (tcb);
|
||||
NS_UNUSED (dupAckCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs recovery based on the recovery algorithm
|
||||
*
|
||||
* The function is called on arrival of every ack when TcpSocketState
|
||||
* is set to CA_RECOVERY. It performs the necessary cwnd changes
|
||||
* as per the recovery algorithm.
|
||||
*
|
||||
* \param tcb internal congestion state
|
||||
*/
|
||||
virtual void DoRecovery (Ptr<TcpSocketState> tcb)
|
||||
{
|
||||
NS_UNUSED (tcb);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs cwnd adjustments at the end of recovery
|
||||
*
|
||||
* The function is called when the TcpSocketState is changed from CA_RECOVERY.
|
||||
*
|
||||
* \param tcb internal congestion state
|
||||
* \param isSackEnabled
|
||||
*/
|
||||
virtual void ExitRecovery (Ptr<TcpSocketState> tcb)
|
||||
{
|
||||
NS_UNUSED (tcb);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Copy the recovery algorithm across socket
|
||||
*
|
||||
* \return a pointer of the copied object
|
||||
*/
|
||||
virtual Ptr<TcpRecoveryOps> Fork () = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The Classic recovery implementation
|
||||
*
|
||||
* Classic recovery refers to the two well-established recovery algorithms,
|
||||
* namely, NewReno (RFC 6582) and SACK based recovery (RFC 6675).
|
||||
*
|
||||
* The idea of the algorithm is that when we enter recovery, we set the
|
||||
* congestion window value to the slow start threshold and maintain it
|
||||
* at such value until we are fully recovered (in other words, until
|
||||
* the highest sequence transmitted at time of detecting the loss is
|
||||
* ACKed by the receiver).
|
||||
*
|
||||
* \see DoRecovery
|
||||
*/
|
||||
class ClassicRecovery : public TcpRecoveryOps
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
*/
|
||||
ClassicRecovery ();
|
||||
|
||||
/**
|
||||
* \brief Copy constructor.
|
||||
* \param recovery object to copy.
|
||||
*/
|
||||
ClassicRecovery (const ClassicRecovery& recovery);
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
*/
|
||||
~ClassicRecovery ();
|
||||
|
||||
virtual std::string GetName () const override;
|
||||
|
||||
virtual void EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount) override;
|
||||
|
||||
virtual void DoRecovery (Ptr<TcpSocketState> tcb) override;
|
||||
|
||||
virtual void ExitRecovery (Ptr<TcpSocketState> tcb) override;
|
||||
|
||||
virtual Ptr<TcpRecoveryOps> Fork () override;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif // TCPRECOVERYOPS_H
|
||||
@@ -31,6 +31,7 @@
|
||||
#define TCPSCALABLE_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "tcp-option-sack-permitted.h"
|
||||
#include "tcp-option-sack.h"
|
||||
#include "tcp-congestion-ops.h"
|
||||
#include "tcp-recovery-ops.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
@@ -187,7 +188,7 @@ TcpSocketBase::GetTypeId (void)
|
||||
"ns3::TracedValueCallback::Uint32")
|
||||
.AddTraceSource ("CongestionWindowInflated",
|
||||
"The TCP connection's congestion window inflates as in older RFC",
|
||||
MakeTraceSourceAccessor (&TcpSocketBase::m_cWndInfl),
|
||||
MakeTraceSourceAccessor (&TcpSocketBase::m_cWndInflTrace),
|
||||
"ns3::TracedValueCallback::Uint32")
|
||||
.AddTraceSource ("SlowStartThreshold",
|
||||
"TCP slow start threshold (bytes)",
|
||||
@@ -232,6 +233,10 @@ TcpSocketState::GetTypeId (void)
|
||||
"The TCP connection's congestion window",
|
||||
MakeTraceSourceAccessor (&TcpSocketState::m_cWnd),
|
||||
"ns3::TracedValue::Uint32Callback")
|
||||
.AddTraceSource ("CongestionWindowInflated",
|
||||
"The TCP connection's inflated congestion window",
|
||||
MakeTraceSourceAccessor (&TcpSocketState::m_cWndInfl),
|
||||
"ns3::TracedValue::Uint32Callback")
|
||||
.AddTraceSource ("SlowStartThreshold",
|
||||
"TCP slow start threshold (bytes)",
|
||||
MakeTraceSourceAccessor (&TcpSocketState::m_ssThresh),
|
||||
@@ -305,6 +310,10 @@ TcpSocketBase::TcpSocketBase (void)
|
||||
MakeCallback (&TcpSocketBase::UpdateCwnd, this));
|
||||
NS_ASSERT (ok == true);
|
||||
|
||||
ok = m_tcb->TraceConnectWithoutContext ("CongestionWindowInflated",
|
||||
MakeCallback (&TcpSocketBase::UpdateCwndInfl, this));
|
||||
NS_ASSERT (ok == true);
|
||||
|
||||
ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold",
|
||||
MakeCallback (&TcpSocketBase::UpdateSsThresh, this));
|
||||
NS_ASSERT (ok == true);
|
||||
@@ -405,12 +414,21 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
|
||||
m_congestionControl = sock.m_congestionControl->Fork ();
|
||||
}
|
||||
|
||||
if (sock.m_recoveryOps)
|
||||
{
|
||||
m_recoveryOps = sock.m_recoveryOps->Fork ();
|
||||
}
|
||||
|
||||
bool ok;
|
||||
|
||||
ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow",
|
||||
MakeCallback (&TcpSocketBase::UpdateCwnd, this));
|
||||
NS_ASSERT (ok == true);
|
||||
|
||||
ok = m_tcb->TraceConnectWithoutContext ("CongestionWindowInflated",
|
||||
MakeCallback (&TcpSocketBase::UpdateCwndInfl, this));
|
||||
NS_ASSERT (ok == true);
|
||||
|
||||
ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold",
|
||||
MakeCallback (&TcpSocketBase::UpdateSsThresh, this));
|
||||
NS_ASSERT (ok == true);
|
||||
@@ -1250,7 +1268,7 @@ TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress,
|
||||
|
||||
// Initialize cWnd and ssThresh
|
||||
m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize ();
|
||||
m_cWndInfl = m_tcb->m_cWnd;
|
||||
m_tcb->m_cWndInfl = m_tcb->m_cWnd;
|
||||
m_tcb->m_ssThresh = GetInitialSSThresh ();
|
||||
|
||||
if (tcpHeader.GetFlags () & TcpHeader::ACK)
|
||||
@@ -1489,7 +1507,7 @@ TcpSocketBase::EnterRecovery ()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! m_txBuffer->IsLost (m_txBuffer->HeadSequence ()))
|
||||
if (!m_txBuffer->IsLost (m_txBuffer->HeadSequence ()))
|
||||
{
|
||||
// We received 3 dupacks, but the head is not marked as lost
|
||||
// (received less than 3 SACK block ahead).
|
||||
@@ -1511,8 +1529,7 @@ TcpSocketBase::EnterRecovery ()
|
||||
// compatibility with old ns-3 versions
|
||||
uint32_t bytesInFlight = m_sackEnabled ? BytesInFlight () : BytesInFlight () + m_tcb->m_segmentSize;
|
||||
m_tcb->m_ssThresh = m_congestionControl->GetSsThresh (m_tcb, bytesInFlight);
|
||||
m_tcb->m_cWnd = m_tcb->m_ssThresh;
|
||||
m_cWndInfl = m_tcb->m_ssThresh + m_dupAckCount * m_tcb->m_segmentSize;
|
||||
m_recoveryOps->EnterRecovery (m_tcb, m_dupAckCount);
|
||||
|
||||
NS_LOG_INFO (m_dupAckCount << " dupack. Enter fast recovery mode." <<
|
||||
"Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " <<
|
||||
@@ -1550,15 +1567,6 @@ TcpSocketBase::DupAck ()
|
||||
++m_dupAckCount;
|
||||
}
|
||||
|
||||
if (!m_sackEnabled && m_tcb->m_congState == TcpSocketState::CA_RECOVERY)
|
||||
{
|
||||
// If we are in recovery and we receive a dupack, one segment
|
||||
// has left the network. This is equivalent to a SACK of one block.
|
||||
m_txBuffer->AddRenoSack ();
|
||||
|
||||
m_cWndInfl += m_tcb->m_segmentSize;
|
||||
}
|
||||
|
||||
if (m_tcb->m_congState == TcpSocketState::CA_OPEN)
|
||||
{
|
||||
// From Open we go Disorder
|
||||
@@ -1571,7 +1579,19 @@ TcpSocketBase::DupAck ()
|
||||
NS_LOG_DEBUG ("CA_OPEN -> CA_DISORDER");
|
||||
}
|
||||
|
||||
if (m_tcb->m_congState == TcpSocketState::CA_DISORDER)
|
||||
if (m_tcb->m_congState == TcpSocketState::CA_RECOVERY)
|
||||
{
|
||||
if (!m_sackEnabled)
|
||||
{
|
||||
// If we are in recovery and we receive a dupack, one segment
|
||||
// has left the network. This is equivalent to a SACK of one block.
|
||||
m_txBuffer->AddRenoSack ();
|
||||
}
|
||||
m_recoveryOps->DoRecovery (m_tcb);
|
||||
NS_LOG_INFO (m_dupAckCount << " Dupack received in fast recovery mode."
|
||||
"Increase cwnd to " << m_tcb->m_cWnd);
|
||||
}
|
||||
else if (m_tcb->m_congState == TcpSocketState::CA_DISORDER)
|
||||
{
|
||||
// RFC 6675, Section 5, continuing:
|
||||
// ... and take the following steps:
|
||||
@@ -1674,9 +1694,9 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
||||
*/
|
||||
|
||||
bool isDupack = m_sackEnabled ?
|
||||
scoreboardUpdated
|
||||
: ackNumber == oldHeadSequence &&
|
||||
ackNumber < m_tcb->m_highTxMark;
|
||||
scoreboardUpdated
|
||||
: ackNumber == oldHeadSequence &&
|
||||
ackNumber < m_tcb->m_highTxMark;
|
||||
|
||||
NS_LOG_DEBUG ("ACK of " << ackNumber <<
|
||||
" SND.UNA=" << oldHeadSequence <<
|
||||
@@ -1767,10 +1787,10 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
||||
m_txBuffer->DeleteRetransmittedFlagFromHead ();
|
||||
}
|
||||
DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet
|
||||
m_cWndInfl = SafeSubtraction (m_cWndInfl, bytesAcked);
|
||||
m_tcb->m_cWndInfl = SafeSubtraction (m_tcb->m_cWndInfl, bytesAcked);
|
||||
if (segsAcked >= 1)
|
||||
{
|
||||
m_cWndInfl += m_tcb->m_segmentSize;
|
||||
m_recoveryOps->DoRecovery (m_tcb);
|
||||
}
|
||||
|
||||
// This partial ACK acknowledge the fact that one segment has been
|
||||
@@ -1891,12 +1911,7 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
||||
if (exitedFastRecovery)
|
||||
{
|
||||
NewAck (ackNumber, true);
|
||||
// Follow NewReno procedures to exit FR if SACK is disabled
|
||||
// (RFC2582 sec.3 bullet #5 paragraph 2, option 2)
|
||||
m_cWndInfl = m_tcb->m_ssThresh.Get ();
|
||||
// For SACK connections, we maintain the cwnd = ssthresh. In fact,
|
||||
// this ACK was received in RECOVERY phase, not in OPEN. So we
|
||||
// are not allowed to increase the window
|
||||
m_recoveryOps->ExitRecovery (m_tcb);
|
||||
NS_LOG_DEBUG ("Leaving Fast Recovery; BytesInFlight() = " <<
|
||||
BytesInFlight () << "; cWnd = " << m_tcb->m_cWnd);
|
||||
}
|
||||
@@ -1904,7 +1919,7 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
||||
{
|
||||
m_congestionControl->IncreaseWindow (m_tcb, segsAcked);
|
||||
|
||||
m_cWndInfl = m_tcb->m_cWnd;
|
||||
m_tcb->m_cWndInfl = m_tcb->m_cWnd;
|
||||
|
||||
NS_LOG_LOGIC ("Congestion control called: " <<
|
||||
" cWnd: " << m_tcb->m_cWnd <<
|
||||
@@ -3306,7 +3321,7 @@ TcpSocketBase::ReTxTimeout ()
|
||||
|
||||
// Cwnd set to 1 MSS
|
||||
m_tcb->m_cWnd = m_tcb->m_segmentSize;
|
||||
m_cWndInfl = m_tcb->m_cWnd;
|
||||
m_tcb->m_cWndInfl = m_tcb->m_cWnd;
|
||||
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_LOSS);
|
||||
m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_LOSS);
|
||||
m_tcb->m_congState = TcpSocketState::CA_LOSS;
|
||||
@@ -3891,6 +3906,12 @@ TcpSocketBase::UpdateCwnd (uint32_t oldValue, uint32_t newValue)
|
||||
m_cWndTrace (oldValue, newValue);
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketBase::UpdateCwndInfl (uint32_t oldValue, uint32_t newValue)
|
||||
{
|
||||
m_cWndInflTrace (oldValue, newValue);
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketBase::UpdateSsThresh (uint32_t oldValue, uint32_t newValue)
|
||||
{
|
||||
@@ -3937,6 +3958,13 @@ TcpSocketBase::SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo)
|
||||
m_congestionControl = algo;
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketBase::SetRecoveryAlgorithm (Ptr<TcpRecoveryOps> recovery)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << recovery);
|
||||
m_recoveryOps = recovery;
|
||||
}
|
||||
|
||||
Ptr<TcpSocketBase>
|
||||
TcpSocketBase::Fork (void)
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@ class Packet;
|
||||
class TcpL4Protocol;
|
||||
class TcpHeader;
|
||||
class TcpCongestionOps;
|
||||
class TcpRecoveryOps;
|
||||
class RttEstimator;
|
||||
class TcpRxBuffer;
|
||||
class TcpTxBuffer;
|
||||
@@ -170,6 +171,7 @@ public:
|
||||
|
||||
// Congestion control
|
||||
TracedValue<uint32_t> m_cWnd {0}; //!< Congestion window
|
||||
TracedValue<uint32_t> m_cWndInfl {0}; //!< Inflated congestion window trace (used only for backward compatibility purpose)
|
||||
TracedValue<uint32_t> m_ssThresh {0}; //!< Slow start threshold
|
||||
uint32_t m_initialCWnd {0}; //!< Initial cWnd value
|
||||
uint32_t m_initialSsThresh {0}; //!< Initial Slow Start Threshold value
|
||||
@@ -459,6 +461,11 @@ public:
|
||||
*/
|
||||
TracedCallback<uint32_t, uint32_t> m_cWndTrace;
|
||||
|
||||
/**
|
||||
* \brief Callback pointer for cWndInfl trace chaining
|
||||
*/
|
||||
TracedCallback<uint32_t, uint32_t> m_cWndInflTrace;
|
||||
|
||||
/**
|
||||
* \brief Callback pointer for ssTh trace chaining
|
||||
*/
|
||||
@@ -496,6 +503,13 @@ public:
|
||||
*/
|
||||
void UpdateCwnd (uint32_t oldValue, uint32_t newValue);
|
||||
|
||||
/**
|
||||
* \brief Callback function to hook to TcpSocketState inflated congestion window
|
||||
* \param oldValue old cWndInfl value
|
||||
* \param newValue new cWndInfl value
|
||||
*/
|
||||
void UpdateCwndInfl (uint32_t oldValue, uint32_t newValue);
|
||||
|
||||
/**
|
||||
* \brief Callback function to hook to TcpSocketState slow start threshold
|
||||
* \param oldValue old ssTh value
|
||||
@@ -546,6 +560,13 @@ public:
|
||||
*/
|
||||
void SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo);
|
||||
|
||||
/**
|
||||
* \brief Install a recovery algorithm on this socket
|
||||
*
|
||||
* \param recovery Algorithm to be installed
|
||||
*/
|
||||
void SetRecoveryAlgorithm (Ptr<TcpRecoveryOps> recovery);
|
||||
|
||||
// Necessary implementations of null functions from ns3::Socket
|
||||
virtual enum SocketErrno GetErrno (void) const; // returns m_errno
|
||||
virtual enum SocketType GetSocketType (void) const; // returns socket type
|
||||
@@ -1046,7 +1067,7 @@ protected:
|
||||
void AddOptions (TcpHeader& tcpHeader);
|
||||
|
||||
/**
|
||||
* \brief Read TCP options begore Ack processing
|
||||
* \brief Read TCP options before Ack processing
|
||||
*
|
||||
* Timestamp and Window scale are managed in other pieces of code.
|
||||
*
|
||||
@@ -1252,6 +1273,7 @@ protected:
|
||||
// Transmission Control Block
|
||||
Ptr<TcpSocketState> m_tcb {nullptr}; //!< Congestion control informations
|
||||
Ptr<TcpCongestionOps> m_congestionControl {nullptr}; //!< Congestion control
|
||||
Ptr<TcpRecoveryOps> m_recoveryOps {nullptr}; //!< Recovery Algorithm
|
||||
|
||||
// Guesses over the other connection end
|
||||
bool m_isFirstPartialAck {true}; //!< First partial ACK during RECOVERY
|
||||
@@ -1265,11 +1287,6 @@ protected:
|
||||
|
||||
// Pacing related variable
|
||||
Timer m_pacingTimer {Timer::REMOVE_ON_DESTROY}; //!< Pacing Event
|
||||
|
||||
/**
|
||||
* \brief Inflated congestion window trace (not used in the real code, deprecated)
|
||||
*/
|
||||
TracedValue<uint32_t> m_cWndInfl {0};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define TCPVEGAS_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define TCPVENO_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define TCP_WESTWOOD_H
|
||||
|
||||
#include "tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
#include "ns3/sequence-number.h"
|
||||
#include "ns3/traced-value.h"
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define TCPYEAH_H
|
||||
|
||||
#include "ns3/tcp-scalable.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ NS_LOG_COMPONENT_DEFINE ("TcpGeneralTest");
|
||||
TcpGeneralTest::TcpGeneralTest (const std::string &desc)
|
||||
: TestCase (desc),
|
||||
m_congControlTypeId (TcpNewReno::GetTypeId ()),
|
||||
m_recoveryTypeId (ClassicRecovery::GetTypeId ()),
|
||||
m_remoteAddr (Ipv4Address::GetAny (), 4477)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << desc);
|
||||
@@ -96,6 +97,7 @@ TcpGeneralTest::ConfigureEnvironment ()
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
SetCongestionControl (m_congControlTypeId);
|
||||
SetRecoveryAlgorithm (m_recoveryTypeId);
|
||||
SetPropagationDelay (MilliSeconds (500));
|
||||
SetTransmitStart (Seconds (10));
|
||||
SetAppPktSize (500);
|
||||
@@ -197,6 +199,8 @@ TcpGeneralTest::DoRun (void)
|
||||
m_senderSocket->SetUpdateRttHistoryCb (MakeCallback (&TcpGeneralTest::UpdateRttHistoryCb, this));
|
||||
m_senderSocket->TraceConnectWithoutContext ("CongestionWindow",
|
||||
MakeCallback (&TcpGeneralTest::CWndTrace, this));
|
||||
m_senderSocket->TraceConnectWithoutContext ("CongestionWindowInflated",
|
||||
MakeCallback (&TcpGeneralTest::CWndInflTrace, this));
|
||||
m_senderSocket->TraceConnectWithoutContext ("SlowStartThreshold",
|
||||
MakeCallback (&TcpGeneralTest::SsThreshTrace, this));
|
||||
m_senderSocket->TraceConnectWithoutContext ("CongState",
|
||||
@@ -264,24 +268,34 @@ TcpGeneralTest::CreateChannel ()
|
||||
Ptr<TcpSocketMsgBase>
|
||||
TcpGeneralTest::CreateSocket (Ptr<Node> node, TypeId socketType,
|
||||
TypeId congControl)
|
||||
{
|
||||
return CreateSocket (node, socketType, congControl, m_recoveryTypeId);
|
||||
}
|
||||
|
||||
Ptr<TcpSocketMsgBase>
|
||||
TcpGeneralTest::CreateSocket (Ptr<Node> node, TypeId socketType,
|
||||
TypeId congControl, TypeId recoveryAlgorithm)
|
||||
{
|
||||
ObjectFactory rttFactory;
|
||||
ObjectFactory congestionAlgorithmFactory;
|
||||
ObjectFactory recoveryAlgorithmFactory;
|
||||
ObjectFactory socketFactory;
|
||||
|
||||
rttFactory.SetTypeId (RttMeanDeviation::GetTypeId ());
|
||||
congestionAlgorithmFactory.SetTypeId (congControl);
|
||||
recoveryAlgorithmFactory.SetTypeId (recoveryAlgorithm);
|
||||
socketFactory.SetTypeId (socketType);
|
||||
|
||||
Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();
|
||||
Ptr<TcpSocketMsgBase> socket = DynamicCast<TcpSocketMsgBase> (socketFactory.Create ());
|
||||
Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps> ();
|
||||
Ptr<TcpRecoveryOps> recovery = recoveryAlgorithmFactory.Create<TcpRecoveryOps> ();
|
||||
|
||||
socket->SetNode (node);
|
||||
socket->SetTcp (node->GetObject<TcpL4Protocol> ());
|
||||
socket->SetRtt (rtt);
|
||||
socket->SetCongestionControlAlgorithm (algo);
|
||||
|
||||
socket->SetRecoveryAlgorithm (recovery);
|
||||
return socket;
|
||||
}
|
||||
|
||||
@@ -300,13 +314,13 @@ TcpGeneralTest::CreateReceiverErrorModel ()
|
||||
Ptr<TcpSocketMsgBase>
|
||||
TcpGeneralTest::CreateSenderSocket (Ptr<Node> node)
|
||||
{
|
||||
return CreateSocket (node, TcpSocketMsgBase::GetTypeId (), m_congControlTypeId);
|
||||
return CreateSocket (node, TcpSocketMsgBase::GetTypeId (), m_congControlTypeId, m_recoveryTypeId);
|
||||
}
|
||||
|
||||
Ptr<TcpSocketMsgBase>
|
||||
TcpGeneralTest::CreateReceiverSocket (Ptr<Node> node)
|
||||
{
|
||||
return CreateSocket (node, TcpSocketMsgBase::GetTypeId (), m_congControlTypeId);
|
||||
return CreateSocket (node, TcpSocketMsgBase::GetTypeId (), m_congControlTypeId, m_recoveryTypeId);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "ns3/error-model.h"
|
||||
#include "ns3/tcp-socket-base.h"
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-recovery-ops.h"
|
||||
#include "ns3/test.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -322,6 +323,18 @@ protected:
|
||||
virtual Ptr<TcpSocketMsgBase> CreateSocket (Ptr<Node> node, TypeId socketType,
|
||||
TypeId congControl);
|
||||
|
||||
/**
|
||||
* \brief Create a socket
|
||||
*
|
||||
* \param node associated node
|
||||
* \param socketType Type of the TCP socket
|
||||
* \param congControl congestion control
|
||||
* \param recoveryAlgorithm recovery algorithm
|
||||
* \return a pointer to the newer created socket
|
||||
*/
|
||||
virtual Ptr<TcpSocketMsgBase> CreateSocket (Ptr<Node> node, TypeId socketType,
|
||||
TypeId congControl, TypeId recoveryAlgorithm);
|
||||
|
||||
/**
|
||||
* \brief Get the pointer to a previously created sender socket
|
||||
* \return ptr to sender socket or 0
|
||||
@@ -623,6 +636,13 @@ protected:
|
||||
*/
|
||||
void SetCongestionControl (TypeId congControl) { m_congControlTypeId = congControl; }
|
||||
|
||||
/**
|
||||
* \brief recovery algorithm of the sender socket
|
||||
*
|
||||
* \param recovery typeid of the recovery algorithm
|
||||
*/
|
||||
void SetRecoveryAlgorithm (TypeId reccovery) { m_recoveryTypeId = reccovery; }
|
||||
|
||||
/**
|
||||
* \brief MTU of the bottleneck link
|
||||
*
|
||||
@@ -654,6 +674,18 @@ protected:
|
||||
NS_UNUSED (newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Tracks the inflated congestion window changes
|
||||
*
|
||||
* \param oldValue old value
|
||||
* \param newValue new value
|
||||
*/
|
||||
virtual void CWndInflTrace (uint32_t oldValue, uint32_t newValue)
|
||||
{
|
||||
NS_UNUSED (oldValue);
|
||||
NS_UNUSED (newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Rtt changes
|
||||
*
|
||||
@@ -943,6 +975,7 @@ protected:
|
||||
}
|
||||
|
||||
TypeId m_congControlTypeId; //!< Congestion control
|
||||
TypeId m_recoveryTypeId; //!< Recovery
|
||||
|
||||
private:
|
||||
// Member variables, accessible through getters
|
||||
|
||||
@@ -179,6 +179,7 @@ def build(bld):
|
||||
'model/udp-socket-factory.cc',
|
||||
'model/tcp-socket.cc',
|
||||
'model/tcp-socket-factory.cc',
|
||||
'model/tcp-recovery-ops.cc',
|
||||
'model/ipv4.cc',
|
||||
'model/ipv4-raw-socket-factory.cc',
|
||||
'model/ipv6-header.cc',
|
||||
@@ -389,6 +390,7 @@ def build(bld):
|
||||
'model/tcp-socket-base.h',
|
||||
'model/tcp-tx-buffer.h',
|
||||
'model/tcp-rx-buffer.h',
|
||||
'model/tcp-recovery-ops.h',
|
||||
'model/rtt-estimator.h',
|
||||
'model/ipv4-packet-probe.h',
|
||||
'model/ipv6-packet-probe.h',
|
||||
|
||||
Reference in New Issue
Block a user