tcp: added TCP YeAH
This commit is contained in:
@@ -33,6 +33,7 @@ New user-visible features
|
||||
- (internet) Added TCP Scalable congestion control algorithm
|
||||
- (internet) Added TCP Veno congestion control algorithm
|
||||
- (internet) Added TCP Bic congestion control algorithm
|
||||
- (internet) Added TCP YeAH congestion control algorithm
|
||||
- (network) SocketAddressTag has been removed from the codebase.
|
||||
Users can use RecvFrom (for UDP) or GetPeerName (for TCP) instead.
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ int main (int argc, char *argv[])
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("transport_prot", "Transport protocol to use: TcpNewReno, "
|
||||
"TcpHybla, TcpHighSpeed, TcpVegas, TcpScalable, TcpVeno, "
|
||||
"TcpBic, TcpWestwood, TcpWestwoodPlus ", transport_prot);
|
||||
"TcpBic, TcpYeah, TcpWestwood, TcpWestwoodPlus ", transport_prot);
|
||||
cmd.AddValue ("error_p", "Packet error rate", error_p);
|
||||
cmd.AddValue ("bandwidth", "Bottleneck bandwidth", bandwidth);
|
||||
cmd.AddValue ("delay", "Bottleneck delay", delay);
|
||||
@@ -254,6 +254,10 @@ int main (int argc, char *argv[])
|
||||
{
|
||||
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpBic::GetTypeId ()));
|
||||
}
|
||||
else if (transport_prot.compare ("TcpYeah") == 0)
|
||||
{
|
||||
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpYeah::GetTypeId ()));
|
||||
}
|
||||
else if (transport_prot.compare ("TcpWestwood") == 0)
|
||||
{ // the default protocol type in ns3::TcpWestwood is WESTWOOD
|
||||
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId ()));
|
||||
@@ -373,7 +377,8 @@ int main (int argc, char *argv[])
|
||||
|| transport_prot.compare ("TcpVegas") == 0
|
||||
|| transport_prot.compare ("TcpVeno") == 0
|
||||
|| transport_prot.compare ("TcpBic") == 0
|
||||
|| transport_prot.compare ("TcpScalable") == 0)
|
||||
|| transport_prot.compare ("TcpScalable") == 0
|
||||
|| transport_prot.compare ("TcpYeah") == 0)
|
||||
{
|
||||
Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (tcp_adu_size));
|
||||
BulkSendHelper ftp ("ns3::TcpSocketFactory", Address ());
|
||||
|
||||
@@ -329,6 +329,38 @@ decrease factor Beta) window size can be used as the new minimum.
|
||||
|
||||
More informations at: http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=1354672
|
||||
|
||||
YeAH
|
||||
^^^^
|
||||
|
||||
YeAH-TCP (Yet Another HighSpeed TCP) is a heuristic designed to balance various
|
||||
requirements of a state-of-the-art congestion control algorithm:
|
||||
1) fully exploit the link capacity of high BDP networks while inducing a small
|
||||
number of congestion events
|
||||
2) compete friendly with Reno flows
|
||||
3) achieve intra and RTT fairness
|
||||
4) robust to random losses
|
||||
5) achieve high performance regardless of buffer size
|
||||
|
||||
YeAH operates between 2 modes: Fast and Slow mode. In the Fast mode when the queue
|
||||
occupancy is small and the network congestion level is low, YeAH increments
|
||||
its congestion window according to the aggressive STCP rule. When the number of packets
|
||||
in the queue grows beyond a threshold and the network congestion level is high, YeAH enters
|
||||
its Slow mode, acting as Reno with a decongestion algorithm. YeAH employs Vegas' mechanism
|
||||
for calculating the backlog as in Equation (1). The estimation of the network congestion
|
||||
level is shown in Equation (2).
|
||||
|
||||
Q = (RTT - BaseRTT) (cwnd / RTT) (1)
|
||||
L = (RTT - BaseRTT) / BaseRTT (2)
|
||||
|
||||
To ensure TCP friendliness, YeAH also implements an algorithm to detect the presence of legacy
|
||||
Reno flows. Upon the receipt of 3 duplicate ACKs, YeAH decreases its slow start threshold
|
||||
according to Equation (3) if it's not competing with Reno flows. Otherwise, the ssthresh is
|
||||
halved as in Reno.
|
||||
|
||||
ssthresh = min{max{cwnd/8, Q}, cwnd/2}
|
||||
|
||||
More information: http://www.csc.lsu.edu/~sjpark/cs7601/4-YeAH_TCP.pdf
|
||||
|
||||
Validation
|
||||
++++++++++
|
||||
|
||||
@@ -350,7 +382,8 @@ section below on :ref:`Writing-tcp-tests`.
|
||||
* **tcp-vegas-test:** Unit tests on the Vegas congestion control
|
||||
* **tcp-veno-test:** Unit tests on the Veno congestion control
|
||||
* **tcp-scalable-test:** Unit tests on the Scalable congestion control
|
||||
* **tcp-bic-test:** Unit tests on the Vegas congestion control
|
||||
* **tcp-bic-test:** Unit tests on the BIC congestion control
|
||||
* **tcp-yeah-test:** Unit tests on the YeAH congestion control
|
||||
* **tcp-option:** Unit tests on TCP options
|
||||
* **tcp-pkts-acked-test:** Unit test the number of time that PktsAcked is called
|
||||
* **tcp-rto-test:** Unit test behavior after a RTO timeout occurs
|
||||
|
||||
345
src/internet/model/tcp-yeah.cc
Normal file
345
src/internet/model/tcp-yeah.cc
Normal file
@@ -0,0 +1,345 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* 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: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
|
||||
*
|
||||
* James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
|
||||
* ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
|
||||
* Information and Telecommunication Technology Center (ITTC)
|
||||
* and Department of Electrical Engineering and Computer Science
|
||||
* The University of Kansas Lawrence, KS USA.
|
||||
*/
|
||||
|
||||
#include "tcp-yeah.h"
|
||||
#include "ns3/tcp-socket-base.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("TcpYeah");
|
||||
NS_OBJECT_ENSURE_REGISTERED (TcpYeah);
|
||||
|
||||
|
||||
TypeId
|
||||
TcpYeah::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::TcpYeah")
|
||||
.SetParent<TcpNewReno> ()
|
||||
.AddConstructor<TcpYeah> ()
|
||||
.SetGroupName ("Internet")
|
||||
.AddAttribute ("Alpha", "Maximum backlog allowed at the bottleneck queue",
|
||||
UintegerValue (80),
|
||||
MakeUintegerAccessor (&TcpYeah::m_alpha),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("Gamma", "Fraction of queue to be removed per RTT",
|
||||
UintegerValue (1),
|
||||
MakeUintegerAccessor (&TcpYeah::m_gamma),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("Delta", "Log minimum fraction of cwnd to be removed on loss",
|
||||
UintegerValue (3),
|
||||
MakeUintegerAccessor (&TcpYeah::m_delta),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("Epsilon", "Log maximum fraction to be removed on early decongestion",
|
||||
UintegerValue (1),
|
||||
MakeUintegerAccessor (&TcpYeah::m_epsilon),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("Phy", "Maximum delta from base",
|
||||
UintegerValue (8),
|
||||
MakeUintegerAccessor (&TcpYeah::m_phy),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("Rho", "Minimum # of consecutive RTT to consider competition on loss",
|
||||
UintegerValue (16),
|
||||
MakeUintegerAccessor (&TcpYeah::m_rho),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("Zeta", "Minimum # of state switches to reset m_renoCount",
|
||||
UintegerValue (50),
|
||||
MakeUintegerAccessor (&TcpYeah::m_zeta),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("StcpAiFactor", "STCP additive increase factor",
|
||||
UintegerValue (100),
|
||||
MakeUintegerAccessor (&TcpYeah::m_stcpAiFactor),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TcpYeah::TcpYeah (void)
|
||||
: TcpNewReno (),
|
||||
m_alpha (80),
|
||||
m_gamma (1),
|
||||
m_delta (3),
|
||||
m_epsilon (1),
|
||||
m_phy (8),
|
||||
m_rho (16),
|
||||
m_zeta (50),
|
||||
m_stcpAiFactor (100),
|
||||
m_stcp (0),
|
||||
m_baseRtt (Time::Max ()),
|
||||
m_minRtt (Time::Max ()),
|
||||
m_cntRtt (0),
|
||||
m_doingYeahNow (true),
|
||||
m_begSndNxt (0),
|
||||
m_lastQ (0),
|
||||
m_doingRenoNow (0),
|
||||
m_renoCount (2),
|
||||
m_fastCount (0)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_stcp = CreateObject <TcpScalable> ();
|
||||
m_stcp->SetAttribute ("AIFactor", (UintegerValue) m_stcpAiFactor);
|
||||
}
|
||||
|
||||
TcpYeah::TcpYeah (const TcpYeah& sock)
|
||||
: TcpNewReno (sock),
|
||||
m_alpha (sock.m_alpha),
|
||||
m_gamma (sock.m_gamma),
|
||||
m_delta (sock.m_delta),
|
||||
m_epsilon (sock.m_epsilon),
|
||||
m_phy (sock.m_phy),
|
||||
m_rho (sock.m_rho),
|
||||
m_zeta (sock.m_zeta),
|
||||
m_stcpAiFactor (sock.m_stcpAiFactor),
|
||||
m_baseRtt (sock.m_baseRtt),
|
||||
m_minRtt (sock.m_minRtt),
|
||||
m_cntRtt (sock.m_cntRtt),
|
||||
m_doingYeahNow (sock.m_doingYeahNow),
|
||||
m_begSndNxt (sock.m_begSndNxt),
|
||||
m_lastQ (sock.m_lastQ),
|
||||
m_doingRenoNow (sock.m_doingRenoNow),
|
||||
m_renoCount (sock.m_renoCount),
|
||||
m_fastCount (sock.m_fastCount)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_stcp = CopyObject (sock.m_stcp);
|
||||
}
|
||||
|
||||
TcpYeah::~TcpYeah (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
Ptr<TcpCongestionOps>
|
||||
TcpYeah::Fork (void)
|
||||
{
|
||||
return CopyObject<TcpYeah> (this);
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeah::PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked,
|
||||
const Time& rtt)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << tcb << segmentsAcked << rtt);
|
||||
|
||||
if (rtt.IsZero ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_minRtt = std::min (m_minRtt, rtt);
|
||||
NS_LOG_DEBUG ("Updated m_minRtt = " << m_minRtt.GetMilliSeconds () << " ms");
|
||||
|
||||
m_baseRtt = std::min (m_baseRtt, rtt);
|
||||
NS_LOG_DEBUG ("Updated m_baseRtt = " << m_baseRtt.GetMilliSeconds () << " ms");
|
||||
|
||||
// Update RTT counter
|
||||
m_cntRtt++;
|
||||
NS_LOG_DEBUG ("Updated m_cntRtt = " << m_cntRtt);
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeah::EnableYeah (const SequenceNumber32 &nextTxSequence)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << nextTxSequence);
|
||||
|
||||
m_doingYeahNow = true;
|
||||
m_begSndNxt = nextTxSequence;
|
||||
m_cntRtt = 0;
|
||||
m_minRtt = Time::Max ();
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeah::DisableYeah ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
m_doingYeahNow = false;
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeah::CongestionStateSet (Ptr<TcpSocketState> tcb,
|
||||
const TcpSocketState::TcpCongState_t newState)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << tcb << newState);
|
||||
|
||||
if (newState == TcpSocketState::CA_OPEN)
|
||||
{
|
||||
EnableYeah (tcb->m_nextTxSequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableYeah ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeah::IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << tcb << segmentsAcked);
|
||||
|
||||
if (tcb->m_cWnd < tcb->m_ssThresh)
|
||||
{
|
||||
NS_LOG_LOGIC ("In slow start, invoke NewReno slow start.");
|
||||
segmentsAcked = TcpNewReno::SlowStart (tcb, segmentsAcked);
|
||||
}
|
||||
else if (!m_doingRenoNow)
|
||||
{ // Fast mode
|
||||
NS_LOG_LOGIC ("In Fast mode, increment cwnd according to STCP rule.");
|
||||
m_stcp->IncreaseWindow (tcb, segmentsAcked);
|
||||
NS_LOG_INFO ("In Fast mode, updated to cwnd " << tcb->m_cWnd <<
|
||||
" ssthresh " << tcb->m_ssThresh);
|
||||
}
|
||||
else
|
||||
{ // Behave like NewReno
|
||||
TcpNewReno::CongestionAvoidance (tcb, segmentsAcked);
|
||||
}
|
||||
|
||||
if (tcb->m_lastAckedSeq >= m_begSndNxt)
|
||||
{ // A YeAH cycle has finished, we do YeAH cwnd adjustment every RTT.
|
||||
|
||||
NS_LOG_LOGIC ("A YeAH cycle has finished, check if enough RTT samples.");
|
||||
/*
|
||||
* We perform YeAH calculations only if we got enough RTT samples to
|
||||
* insure that at least 1 of those samples wasn't from a delayed ACK.
|
||||
*/
|
||||
if (m_cntRtt > 2)
|
||||
{
|
||||
NS_LOG_LOGIC ("Enough RTT samples to perform YeAH calculations");
|
||||
/*
|
||||
* We have enough RTT samples to perform YeAH algorithm.
|
||||
* Now we need to determine if we should operate in Fast or Slow mode,
|
||||
* and if we should execute the precautionary decongestion algorithm.
|
||||
*/
|
||||
|
||||
uint32_t segCwnd = tcb->GetCwndInSegments ();
|
||||
|
||||
// Calculate the extra number of packets in queue
|
||||
// Naming convention: minRtt is the minimum RTT of this round,
|
||||
// baseRtt is the minimum RTT of the entire transmission.
|
||||
NS_ASSERT (m_minRtt >= m_baseRtt);
|
||||
Time rttQueue = m_minRtt - m_baseRtt;
|
||||
|
||||
// queue = rttQueue * bw = rttQueue * (cwnd/RTTmin)
|
||||
double bw = segCwnd / m_minRtt.GetSeconds ();
|
||||
uint32_t queue = bw * rttQueue.GetSeconds ();
|
||||
NS_LOG_DEBUG ("Queue backlog = " << queue <<
|
||||
" given by cwnd = " << segCwnd <<
|
||||
", minRtt = " << m_minRtt.GetMilliSeconds () <<
|
||||
" ms, baseRtt = " << m_baseRtt.GetMilliSeconds () <<
|
||||
" ms");
|
||||
|
||||
double L = rttQueue.GetSeconds () / m_baseRtt.GetSeconds ();
|
||||
NS_LOG_DEBUG ("Network congestion level = " << L);
|
||||
|
||||
if (queue > m_alpha || L > (1 / m_phy) )
|
||||
{ // Slow mode
|
||||
if (queue > m_alpha && segCwnd > m_renoCount)
|
||||
{ // Precautionary decongestion
|
||||
NS_LOG_LOGIC ("Execute the precautionary decongestion.");
|
||||
uint32_t reduction = std::min (queue / m_gamma, segCwnd >> m_epsilon);
|
||||
segCwnd -= reduction;
|
||||
segCwnd = std::max (segCwnd, m_renoCount);
|
||||
tcb->m_cWnd = segCwnd * tcb->m_segmentSize;
|
||||
tcb->m_ssThresh = tcb->m_cWnd;
|
||||
|
||||
NS_LOG_INFO ("In Slow mode, after precautionary decongestion, "
|
||||
"updated to cwnd " << tcb->m_cWnd <<
|
||||
" ssthresh " << tcb->m_ssThresh);
|
||||
}
|
||||
|
||||
if (m_renoCount <= 2)
|
||||
{
|
||||
m_renoCount = std::max (segCwnd >> 1, (uint32_t) 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_renoCount++;
|
||||
}
|
||||
|
||||
m_doingRenoNow = m_doingRenoNow + 1;
|
||||
NS_LOG_DEBUG ("In Slow mode, updated to m_renoCount = " <<
|
||||
m_renoCount << " m_doingRenoNow = " << m_doingRenoNow);
|
||||
}
|
||||
else
|
||||
{ // Fast mode
|
||||
m_fastCount++;
|
||||
if (m_fastCount > m_zeta)
|
||||
{ // Reset renoCount
|
||||
m_renoCount = 2;
|
||||
m_fastCount = 0;
|
||||
}
|
||||
m_doingRenoNow = 0;
|
||||
NS_LOG_DEBUG ("In Fast mode, updated to m_renoCount = " <<
|
||||
m_renoCount << " m_doingRenoNow = " << m_doingRenoNow);
|
||||
}
|
||||
m_lastQ = queue;
|
||||
}
|
||||
|
||||
// Save the current right edge for next Yeah cycle
|
||||
m_begSndNxt = tcb->m_nextTxSequence;
|
||||
|
||||
// Reset cntRtt & minRtt
|
||||
m_cntRtt = 0;
|
||||
m_minRtt = Time::Max ();
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
TcpYeah::GetName () const
|
||||
{
|
||||
return "TcpYeah";
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TcpYeah::GetSsThresh (Ptr<const TcpSocketState> tcb,
|
||||
uint32_t bytesInFlight)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << tcb << bytesInFlight);
|
||||
uint32_t reduction;
|
||||
uint32_t segBytesInFlight = bytesInFlight / tcb->m_segmentSize;
|
||||
|
||||
if (m_doingRenoNow < m_rho)
|
||||
{ // Not competing with Reno flows
|
||||
NS_LOG_LOGIC ("Not competing with Reno flows upon loss");
|
||||
reduction = m_lastQ;
|
||||
reduction = std::max (reduction, segBytesInFlight >> m_delta);
|
||||
reduction = std::min (reduction, std::max (segBytesInFlight >> 1, (uint32_t) 2));
|
||||
}
|
||||
else
|
||||
{ // Competing with Reno flows
|
||||
NS_LOG_LOGIC ("Competing with Reno flows upon loss");
|
||||
reduction = std::max (segBytesInFlight >> 1, (uint32_t) 2);
|
||||
}
|
||||
|
||||
NS_LOG_INFO ("Reduction amount upon loss = " << reduction);
|
||||
|
||||
m_fastCount = 0;
|
||||
m_renoCount = std::max (m_renoCount >> 1, (uint32_t) 2);
|
||||
|
||||
return (bytesInFlight - (reduction * tcb->m_segmentSize));
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
189
src/internet/model/tcp-yeah.h
Normal file
189
src/internet/model/tcp-yeah.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* 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: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
|
||||
*
|
||||
* James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
|
||||
* ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
|
||||
* Information and Telecommunication Technology Center (ITTC)
|
||||
* and Department of Electrical Engineering and Computer Science
|
||||
* The University of Kansas Lawrence, KS USA.
|
||||
*/
|
||||
|
||||
#ifndef TCPYEAH_H
|
||||
#define TCPYEAH_H
|
||||
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-scalable.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup tcp
|
||||
*
|
||||
* \brief An implementation of TCP YeAH
|
||||
*
|
||||
* YeAH-TCP (Yet Another HighSpeed TCP) is a heuristic designed to balance various
|
||||
* requirements of a state-of-the-art congestion control algorithm:
|
||||
* 1) fully exploit the link capacity of high BDP networks while inducing a small
|
||||
* number of congestion events
|
||||
* 2) compete friendly with Reno flows
|
||||
* 3) achieve intra and RTT fairness
|
||||
* 4) robust to random losses
|
||||
* 5) achieve high performance regardless of buffer size
|
||||
*
|
||||
* YeAH operates between 2 modes: Fast and Slow mode. In the Fast mode when the
|
||||
* queue occupancy is small and the network congestion level is low, YeAH
|
||||
* increments its congestion window according to the aggressive STCP rule.
|
||||
* When the number of packets in the queue grows beyond a threshold and the
|
||||
* network congestion level is high, YeAH enters its Slow mode, acting as Reno
|
||||
* with a decongestion algorithm. YeAH employs Vegas' mechanism for calculating
|
||||
* the backlog as in Equation (1). The estimation of the network congestion
|
||||
* level is shown in Equation (2).
|
||||
*
|
||||
* Q = (RTT - BaseRTT) (cwnd / RTT) (1)
|
||||
* L = (RTT - BaseRTT) / BaseRTT (2)
|
||||
*
|
||||
* To ensure TCP friendliness, YeAH also implements an algorithm to detect the
|
||||
* presence of legacy Reno flows. Upon the receipt of 3 duplicate ACKs,
|
||||
* YeAH decreases its slow start threshold according to Equation (3) if
|
||||
* it's not competing with Reno flows. Otherwise, the ssthresh is halved
|
||||
* as in Reno.
|
||||
*
|
||||
* ssthresh = min{max{cwnd/8, Q}, cwnd/2}
|
||||
*
|
||||
* More information: http://www.csc.lsu.edu/~sjpark/cs7601/4-YeAH_TCP.pdf
|
||||
*/
|
||||
|
||||
class TcpYeah : public TcpNewReno
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* Create an unbound tcp socket.
|
||||
*/
|
||||
TcpYeah (void);
|
||||
|
||||
/**
|
||||
* \brief Copy constructor
|
||||
* \param sock the object to copy
|
||||
*/
|
||||
TcpYeah (const TcpYeah& sock);
|
||||
virtual ~TcpYeah (void);
|
||||
|
||||
virtual std::string GetName () const;
|
||||
|
||||
/**
|
||||
* \brief Compute RTTs needed to execute YeAH algorithm
|
||||
*
|
||||
* The function filters RTT samples from the last RTT to find
|
||||
* the current smallest propagation delay + queueing delay (minRtt).
|
||||
* We take the minimum to avoid the effects of delayed ACKs.
|
||||
*
|
||||
* The function also min-filters all RTT measurements seen to find the
|
||||
* propagation delay (baseRtt).
|
||||
*
|
||||
* \param tcb internal congestion state
|
||||
* \param segementsAcked count of segments ACKed
|
||||
* \param rtt last RTT
|
||||
*
|
||||
*/
|
||||
virtual void PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked,
|
||||
const Time& rtt);
|
||||
|
||||
/**
|
||||
* \brief Enable/disable YeAH algorithm depending on the congestion state
|
||||
*
|
||||
* We only start a YeAH cycle when we are in normal congestion state (CA_OPEN state).
|
||||
*
|
||||
* \param tcb internal congestion state
|
||||
* \param newState new congestion state to which the TCP is going to switch
|
||||
*/
|
||||
virtual void CongestionStateSet (Ptr<TcpSocketState> tcb,
|
||||
const TcpSocketState::TcpCongState_t newState);
|
||||
|
||||
/**
|
||||
* \brief Adjust cwnd following YeAH dual-mode algorithm
|
||||
*
|
||||
* \param tcb internal congestion state
|
||||
* \param segmentsAcked count of segments ACKed
|
||||
*/
|
||||
virtual void IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked);
|
||||
|
||||
/**
|
||||
* \brief Get slow start threshold upon the receipt of 3 dupACKs
|
||||
*
|
||||
* \param tcb internal congestion state
|
||||
* \param bytesInFlight number of outstanding bytes
|
||||
*
|
||||
* \return the slow start threshold value
|
||||
*/
|
||||
virtual uint32_t GetSsThresh (Ptr<const TcpSocketState> tcb,
|
||||
uint32_t bytesInFlight);
|
||||
|
||||
virtual Ptr<TcpCongestionOps> Fork ();
|
||||
|
||||
protected:
|
||||
private:
|
||||
/**
|
||||
* \brief Enable YeAH algorithm to start taking YeAH samples
|
||||
*
|
||||
* YeAH algorithm is enabled in the following situations:
|
||||
* 1. at the establishment of a connection
|
||||
* 2. after an RTO
|
||||
* 3. after fast recovery
|
||||
* 4. when an idle connection is restarted
|
||||
*
|
||||
* \param nextTxSequence Sequence to transmit next
|
||||
*/
|
||||
void EnableYeah (const SequenceNumber32 &nextTxSequence);
|
||||
|
||||
/**
|
||||
* \brief Stop taking YeAH samples
|
||||
*/
|
||||
void DisableYeah ();
|
||||
|
||||
private:
|
||||
uint32_t m_alpha; //!< Maximum backlog allowed at the bottleneck queue; Q_max in the paper
|
||||
uint32_t m_gamma; //!< Fraction of queue to be removed per RTT when precautionary decongestion executed
|
||||
uint32_t m_delta; //!< Log minimum fraction of cwnd to be removed on loss
|
||||
uint32_t m_epsilon; //!< Log maximum fraction to be removed on early decongestion
|
||||
uint32_t m_phy; //!< Maximum delta from base
|
||||
uint32_t m_rho; //!< Minimum # of consecutive RTT to consider competition with Reno flows on loss
|
||||
uint32_t m_zeta; //!< Minimum # of state switches to reset m_renoCount
|
||||
|
||||
uint32_t m_stcpAiFactor; //!< STCP additive increase parameter
|
||||
Ptr<TcpScalable> m_stcp; //!< TcpScalable object
|
||||
Time m_baseRtt; //!< Minimum of all YeAH RTT measurements seen during connection
|
||||
Time m_minRtt; //!< Minimum of all RTTs measured within last RTT
|
||||
uint32_t m_cntRtt; //!< # of RTT measurements during last RTT
|
||||
bool m_doingYeahNow; //!< If true, do YeAH for this RTT
|
||||
SequenceNumber32 m_begSndNxt; //!< Right edge during last RTT
|
||||
uint32_t m_lastQ; //!< Last # of packets in the bottleneck queue
|
||||
uint32_t m_doingRenoNow; //!< # of RTTs in "Slow" mode
|
||||
uint32_t m_renoCount; //!< Estimated cwnd of competing Reno flow
|
||||
uint32_t m_fastCount; //!< # of RTTs in "Fast" mode
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif // TCPYEAH_H
|
||||
367
src/internet/test/tcp-yeah-test.cc
Normal file
367
src/internet/test/tcp-yeah-test.cc
Normal file
@@ -0,0 +1,367 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* 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: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
|
||||
*
|
||||
* James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
|
||||
* ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
|
||||
* Information and Telecommunication Technology Center (ITTC)
|
||||
* and Department of Electrical Engineering and Computer Science
|
||||
* The University of Kansas Lawrence, KS USA.
|
||||
*/
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/tcp-congestion-ops.h"
|
||||
#include "ns3/tcp-socket-base.h"
|
||||
#include "ns3/tcp-yeah.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("TcpYeahTestSuite");
|
||||
|
||||
/**
|
||||
* \brief Testing TcpYeah additive increase algorithm
|
||||
*/
|
||||
class TcpYeahIncrementTest : public TestCase
|
||||
{
|
||||
public:
|
||||
TcpYeahIncrementTest (uint32_t cWnd,
|
||||
uint32_t ssThresh,
|
||||
uint32_t segmentSize,
|
||||
SequenceNumber32 nextTxSeq,
|
||||
SequenceNumber32 lastAckedSeq,
|
||||
uint32_t segmentsAcked,
|
||||
Time minRtt,
|
||||
const std::string &name);
|
||||
|
||||
private:
|
||||
virtual void DoRun ();
|
||||
void IncreaseWindow (Ptr<TcpYeah> cong);
|
||||
|
||||
uint32_t m_cWnd;
|
||||
uint32_t m_ssThresh;
|
||||
uint32_t m_segmentSize;
|
||||
SequenceNumber32 m_nextTxSeq;
|
||||
SequenceNumber32 m_lastAckedSeq;
|
||||
uint32_t m_segmentsAcked;
|
||||
Time m_baseRtt;
|
||||
Time m_minRtt;
|
||||
uint32_t m_doingRenoNow;
|
||||
uint32_t m_cntRtt;
|
||||
uint32_t m_renoCount;
|
||||
uint32_t m_fastCount;
|
||||
};
|
||||
|
||||
TcpYeahIncrementTest::TcpYeahIncrementTest (uint32_t cWnd,
|
||||
uint32_t ssThresh,
|
||||
uint32_t segmentSize,
|
||||
SequenceNumber32 nextTxSeq,
|
||||
SequenceNumber32 lastAckedSeq,
|
||||
uint32_t segmentsAcked,
|
||||
Time minRtt,
|
||||
const std::string &name)
|
||||
: TestCase (name),
|
||||
m_cWnd (cWnd),
|
||||
m_ssThresh (ssThresh),
|
||||
m_segmentSize (segmentSize),
|
||||
m_nextTxSeq (nextTxSeq),
|
||||
m_lastAckedSeq (lastAckedSeq),
|
||||
m_segmentsAcked (segmentsAcked),
|
||||
m_baseRtt (MilliSeconds (100)),
|
||||
m_minRtt (minRtt),
|
||||
m_doingRenoNow (0),
|
||||
m_cntRtt (4),
|
||||
m_renoCount (2),
|
||||
m_fastCount (0)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeahIncrementTest::DoRun ()
|
||||
{
|
||||
Ptr<TcpSocketState> state = CreateObject <TcpSocketState> ();
|
||||
state->m_cWnd = m_cWnd;
|
||||
state->m_ssThresh = m_ssThresh;
|
||||
state->m_segmentSize = m_segmentSize;
|
||||
state->m_nextTxSequence = m_nextTxSeq;
|
||||
state->m_lastAckedSeq = m_lastAckedSeq;
|
||||
|
||||
Ptr<TcpYeah> cong = CreateObject <TcpYeah> ();
|
||||
|
||||
// Set baseRtt to 100 ms
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_baseRtt);
|
||||
|
||||
// Reset YeAH to assign a new value of minRtt
|
||||
cong->CongestionStateSet (state, TcpSocketState::CA_OPEN);
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_minRtt);
|
||||
|
||||
// 2 more calls to PktsAcked to increment cntRtt beyond 2
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_minRtt);
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_minRtt);
|
||||
|
||||
cong->IncreaseWindow (state, m_segmentsAcked);
|
||||
IncreaseWindow (cong);
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (state->m_cWnd.Get (), m_cWnd,
|
||||
"CWnd has not updated correctly");
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeahIncrementTest::IncreaseWindow (Ptr<TcpYeah> cong)
|
||||
{
|
||||
uint32_t segCwnd = m_cWnd / m_segmentSize;
|
||||
|
||||
if (m_cWnd < m_ssThresh)
|
||||
{ // NewReno slow start
|
||||
if (m_segmentsAcked >= 1)
|
||||
{
|
||||
m_cWnd += m_segmentSize;
|
||||
m_segmentsAcked -= 1;
|
||||
NS_LOG_INFO ("In SlowStart, updated to cwnd " << m_cWnd <<
|
||||
" ssthresh " << m_ssThresh);
|
||||
}
|
||||
}
|
||||
else if (!m_doingRenoNow)
|
||||
{ // Fast mode, follow STCP increment rule
|
||||
UintegerValue aiFactor;
|
||||
cong->GetAttribute ("StcpAiFactor", aiFactor);
|
||||
uint32_t w = std::min (segCwnd, (uint32_t) aiFactor.Get ());
|
||||
uint32_t delta = m_segmentsAcked / w;
|
||||
m_cWnd += delta * m_segmentSize;
|
||||
NS_LOG_INFO ("In Fast mode, updated to cwnd " << m_cWnd <<
|
||||
" ssthresh " << m_ssThresh);
|
||||
}
|
||||
else
|
||||
{ // NewReno congestion avoidance
|
||||
if (m_segmentsAcked > 0)
|
||||
{
|
||||
double adder = static_cast<double> (m_segmentSize * m_segmentSize) / m_cWnd;
|
||||
adder = std::max (1.0, adder);
|
||||
m_cWnd += static_cast<uint32_t> (adder);
|
||||
NS_LOG_INFO ("In CongAvoid, updated to cwnd " << m_cWnd <<
|
||||
" ssthresh " << m_ssThresh);
|
||||
}
|
||||
|
||||
}
|
||||
if (m_lastAckedSeq >= m_nextTxSeq)
|
||||
{
|
||||
if (m_cntRtt > 2)
|
||||
{
|
||||
/*
|
||||
* Calculate the extra number of packets in queue
|
||||
*/
|
||||
Time rttQueue = m_minRtt - m_baseRtt;
|
||||
double bw = segCwnd / m_minRtt.GetSeconds ();
|
||||
uint32_t queue = bw * rttQueue.GetSeconds ();
|
||||
|
||||
// Calculate network congestion level
|
||||
double L = rttQueue.GetSeconds () / m_baseRtt.GetSeconds ();
|
||||
|
||||
UintegerValue alpha;
|
||||
cong->GetAttribute ("Alpha", alpha);
|
||||
UintegerValue phy;
|
||||
cong->GetAttribute ("Phy", phy);
|
||||
UintegerValue gamma;
|
||||
cong->GetAttribute ("Gamma", gamma);
|
||||
UintegerValue epsilon;
|
||||
cong->GetAttribute ("Epsilon", epsilon);
|
||||
UintegerValue zeta;
|
||||
cong->GetAttribute ("Zeta", zeta);
|
||||
|
||||
if (queue > alpha.Get () || L > (1 / phy.Get ()) )
|
||||
{ // Slow mode
|
||||
NS_LOG_INFO ("Enter Slow mode");
|
||||
if (queue > alpha.Get () && segCwnd > m_renoCount)
|
||||
{ // Precautionary decongestion
|
||||
uint32_t reduction = std::min (queue / (uint32_t) gamma.Get (),
|
||||
segCwnd >> (uint32_t) epsilon.Get ());
|
||||
segCwnd -= reduction;
|
||||
segCwnd = std::max (segCwnd, m_renoCount);
|
||||
m_cWnd = segCwnd * m_segmentSize;
|
||||
m_ssThresh = m_cWnd;
|
||||
NS_LOG_INFO ("In Slow mode, after precautionary decongestion, "
|
||||
"updated to cwnd " << m_cWnd << " ssthresh " <<
|
||||
m_ssThresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Testing TcpYeah multiplicative decrease algorithm
|
||||
*/
|
||||
class TcpYeahDecrementTest : public TestCase
|
||||
{
|
||||
public:
|
||||
TcpYeahDecrementTest (uint32_t cWnd,
|
||||
uint32_t ssThresh,
|
||||
uint32_t segmentSize,
|
||||
SequenceNumber32 nextTxSeq,
|
||||
SequenceNumber32 lastAckedSeq,
|
||||
Time minRtt,
|
||||
UintegerValue rho,
|
||||
const std::string &name);
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
uint32_t CalculateSsThresh (Ptr<TcpYeah> cong);
|
||||
|
||||
uint32_t m_cWnd;
|
||||
uint32_t m_ssThresh;
|
||||
uint32_t m_segmentSize;
|
||||
uint32_t m_doingRenoNow;
|
||||
SequenceNumber32 m_nextTxSeq;
|
||||
SequenceNumber32 m_lastAckedSeq;
|
||||
Time m_minRtt;
|
||||
Time m_baseRtt;
|
||||
uint32_t m_segmentsAcked;
|
||||
UintegerValue m_rho;
|
||||
};
|
||||
|
||||
TcpYeahDecrementTest::TcpYeahDecrementTest (uint32_t cWnd,
|
||||
uint32_t ssThresh,
|
||||
uint32_t segmentSize,
|
||||
SequenceNumber32 nextTxSeq,
|
||||
SequenceNumber32 lastAckedSeq,
|
||||
Time minRtt,
|
||||
UintegerValue rho,
|
||||
const std::string &name)
|
||||
: TestCase (name),
|
||||
m_cWnd (cWnd),
|
||||
m_ssThresh (ssThresh),
|
||||
m_segmentSize (segmentSize),
|
||||
m_doingRenoNow (0),
|
||||
m_nextTxSeq (nextTxSeq),
|
||||
m_lastAckedSeq (lastAckedSeq),
|
||||
m_minRtt (minRtt),
|
||||
m_baseRtt (MilliSeconds (100)),
|
||||
m_segmentsAcked (2),
|
||||
m_rho (rho)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TcpYeahDecrementTest::DoRun ()
|
||||
{
|
||||
Ptr<TcpSocketState> state = CreateObject <TcpSocketState> ();
|
||||
state->m_cWnd = m_cWnd;
|
||||
state->m_nextTxSequence = m_nextTxSeq;
|
||||
state->m_lastAckedSeq = m_lastAckedSeq;
|
||||
state->m_segmentSize = m_segmentSize;
|
||||
state->m_ssThresh = m_ssThresh;
|
||||
|
||||
Ptr<TcpYeah> cong = CreateObject <TcpYeah> ();
|
||||
|
||||
// Re-set rho to 1 for this unit test
|
||||
cong->SetAttribute ("Rho", UintegerValue (m_rho));
|
||||
|
||||
// Set baseRtt to 100 ms
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_baseRtt);
|
||||
|
||||
// Set minRtt to a different value
|
||||
cong->CongestionStateSet (state, TcpSocketState::CA_OPEN);
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_minRtt);
|
||||
|
||||
// 2 more calls to PktsAcked to increment cntRtt beyond 2
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_minRtt);
|
||||
cong->PktsAcked (state, m_segmentsAcked, m_minRtt);
|
||||
|
||||
// Calculate queue backlog
|
||||
cong->IncreaseWindow (state, m_segmentsAcked);
|
||||
|
||||
// Now get the value of ssThresh
|
||||
uint32_t ssThresh = cong->GetSsThresh (state, m_cWnd);
|
||||
|
||||
// Our calculation of ssThresh
|
||||
uint32_t ssThreshVal = CalculateSsThresh (cong);
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (ssThresh, ssThreshVal,
|
||||
"SsThresh has not updated correctly");
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TcpYeahDecrementTest::CalculateSsThresh (Ptr<TcpYeah> cong)
|
||||
{
|
||||
// Calculate queue backlog
|
||||
uint32_t segCwnd = m_cWnd / m_segmentSize;
|
||||
uint32_t reduction;
|
||||
|
||||
UintegerValue delta;
|
||||
cong->GetAttribute ("Delta", delta);
|
||||
|
||||
Time rttQueue = m_minRtt - m_baseRtt;
|
||||
|
||||
// queue = rttQueue * bw = rttQueue * (cwnd/RTTmin)
|
||||
double bw = segCwnd / m_minRtt.GetSeconds ();
|
||||
uint32_t queue = bw * rttQueue.GetSeconds ();
|
||||
|
||||
NS_LOG_LOGIC ("queue backlog" << queue);
|
||||
|
||||
if (m_doingRenoNow < m_rho.Get ())
|
||||
{
|
||||
reduction = std::max (queue, segCwnd >> delta.Get ());
|
||||
reduction = std::min (reduction, std::max (segCwnd >> 1, (uint32_t) 2));
|
||||
NS_LOG_INFO ("Reduction amount for yeah upon loss = " << reduction);
|
||||
}
|
||||
else
|
||||
{
|
||||
reduction = std::max (segCwnd >> 1, (uint32_t) 2);
|
||||
NS_LOG_INFO ("Reduction amount for reno upon loss = " << reduction);
|
||||
}
|
||||
|
||||
|
||||
return (m_cWnd - (reduction * m_segmentSize));
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
static class TcpYeahTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
TcpYeahTestSuite () : TestSuite ("tcp-yeah-test", UNIT)
|
||||
{
|
||||
AddTestCase (new TcpYeahIncrementTest (20 * 1446, 25 * 1446, 1446, SequenceNumber32 (2893),
|
||||
SequenceNumber32 (1447), 1, MilliSeconds (105),
|
||||
"YeAH test on cWnd when in slow start"),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpYeahIncrementTest (30 * 1446, 25 * 1446, 1446, SequenceNumber32 (2893),
|
||||
SequenceNumber32 (1447), 30, MilliSeconds (105),
|
||||
"YeAH test on cWnd when in Fast mode"),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpYeahIncrementTest (40 * 356, 30 * 356, 356, SequenceNumber32 (20761),
|
||||
SequenceNumber32 (21117), 1, MilliSeconds (120),
|
||||
"YeAH test on cWnd when in slow mode without precautionary decongestion"),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpYeahIncrementTest (100 * 356, 70 * 356, 356, SequenceNumber32 (20761),
|
||||
SequenceNumber32 (21117), 1, MilliSeconds (600),
|
||||
"YeAH test on cWnd when in slow mode with precautionary decongestion"),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpYeahDecrementTest (40 * 1446, 30 * 1446, 1446, SequenceNumber32 (2893),
|
||||
SequenceNumber32 (7230), MilliSeconds (120), UintegerValue (0),
|
||||
"YeAH test on ssThresh upon loss while competing with Reno flows"),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpYeahDecrementTest (57 * 1446, 42 * 1446, 1446, SequenceNumber32 (2893),
|
||||
SequenceNumber32 (7230), MilliSeconds (200), UintegerValue (2),
|
||||
"YeAH test on ssThresh upon loss while not competing with Reno flows"),
|
||||
TestCase::QUICK);
|
||||
}
|
||||
} g_tcpYeahTest;
|
||||
|
||||
} // namespace ns3
|
||||
@@ -153,6 +153,7 @@ def build(bld):
|
||||
'model/tcp-scalable.cc',
|
||||
'model/tcp-veno.cc',
|
||||
'model/tcp-bic.cc',
|
||||
'model/tcp-yeah.cc',
|
||||
'model/tcp-rx-buffer.cc',
|
||||
'model/tcp-tx-buffer.cc',
|
||||
'model/tcp-option.cc',
|
||||
@@ -256,6 +257,7 @@ def build(bld):
|
||||
'test/tcp-scalable-test.cc',
|
||||
'test/tcp-veno-test.cc',
|
||||
'test/tcp-bic-test.cc',
|
||||
'test/tcp-yeah-test.cc',
|
||||
'test/tcp-zero-window-test.cc',
|
||||
'test/tcp-pkts-acked-test.cc',
|
||||
'test/tcp-rtt-estimation.cc',
|
||||
@@ -364,6 +366,7 @@ def build(bld):
|
||||
'model/tcp-scalable.h',
|
||||
'model/tcp-veno.h',
|
||||
'model/tcp-bic.h',
|
||||
'model/tcp-yeah.h',
|
||||
'model/tcp-socket-base.h',
|
||||
'model/tcp-tx-buffer.h',
|
||||
'model/tcp-rx-buffer.h',
|
||||
|
||||
Reference in New Issue
Block a user