186 changes: 186 additions & 0 deletions src/internet/model/tcp-yeah.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/* -*- 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"

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 tcb internal congestion state
*/
void EnableYeah (Ptr<TcpSocketState> tcb);

/**
* \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
uint32_t m_ackCnt; //!< Number of received ACKs
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