1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
19  *
20  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
21  * ResiliNets Research Group  http://wiki.ittc.ku.edu/resilinets
22  * Information and Telecommunication Technology Center (ITTC)
23  * and Department of Electrical Engineering and Computer Science
24  * The University of Kansas Lawrence, KS USA.
25  */
26 
27 #ifndef TCPYEAH_H
28 #define TCPYEAH_H
29 
30 #include "ns3/tcp-scalable.h"
31 #include "ns3/tcp-recovery-ops.h"
32 
33 namespace ns3 {
34 
35 /**
36  * \ingroup congestionOps
37  *
38  * \brief An implementation of TCP YeAH
39  *
40  *  YeAH-TCP (Yet Another HighSpeed TCP) is a heuristic designed to balance various
41  *  requirements of a state-of-the-art congestion control algorithm:
42  *  1) fully exploit the link capacity of high BDP networks while inducing a small
43  *  number of congestion events
44  *  2) compete friendly with Reno flows
45  *  3) achieve intra and RTT fairness
46  *  4) robust to random losses
47  *  5) achieve high performance regardless of buffer size
48  *
49  * YeAH operates between 2 modes: Fast and Slow mode.  In the Fast mode when the
50  * queue occupancy is small and the network congestion level is low, YeAH
51  * increments its congestion window according to the aggressive STCP rule.
52  * When the number of packets in the queue grows beyond a threshold and the
53  * network congestion level is high, YeAH enters its Slow mode, acting as Reno
54  * with a decongestion algorithm.  YeAH employs Vegas' mechanism for calculating
55  * the backlog as in Equation (1).  The estimation of the network congestion
56  * level is shown in Equation (2).
57  *
58  *                      Q = (RTT - BaseRTT) (cwnd / RTT)    (1)
59  *                      L = (RTT - BaseRTT) / BaseRTT       (2)
60  *
61  * To ensure TCP friendliness, YeAH also implements an algorithm to detect the
62  * presence of legacy Reno flows. Upon the receipt of 3 duplicate ACKs,
63  * YeAH decreases its slow start threshold according to Equation (3) if
64  * it's not competing with Reno flows.  Otherwise,  the ssthresh is halved
65  * as in Reno.
66  *
67  *                      ssthresh = min{max{cwnd/8, Q}, cwnd/2}
68  *
69  * More information: http://www.csc.lsu.edu/~sjpark/cs7601/4-YeAH_TCP.pdf
70  */
71 
72 class TcpYeah : public TcpNewReno
73 {
74 public:
75   /**
76    * \brief Get the type ID.
77    * \return the object TypeId
78    */
79   static TypeId GetTypeId (void);
80 
81   /**
82    * Create an unbound tcp socket.
83    */
84   TcpYeah (void);
85 
86   /**
87    * \brief Copy constructor
88    * \param sock the object to copy
89    */
90   TcpYeah (const TcpYeah& sock);
91   virtual ~TcpYeah (void);
92 
93   virtual std::string GetName () const;
94 
95   /**
96    * \brief Compute RTTs needed to execute YeAH algorithm
97    *
98    * The function filters RTT samples from the last RTT to find
99    * the current smallest propagation delay + queueing delay (minRtt).
100    * We take the minimum to avoid the effects of delayed ACKs.
101    *
102    * The function also min-filters all RTT measurements seen to find the
103    * propagation delay (baseRtt).
104    *
105    * \param tcb internal congestion state
106    * \param segmentsAcked count of segments ACKed
107    * \param rtt last RTT
108    *
109    */
110   virtual void PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked,
111                           const Time& rtt);
112 
113   /**
114    * \brief Enable/disable YeAH algorithm depending on the congestion state
115    *
116    * We only start a YeAH cycle when we are in normal congestion state (CA_OPEN state).
117    *
118    * \param tcb internal congestion state
119    * \param newState new congestion state to which the TCP is going to switch
120    */
121   virtual void CongestionStateSet (Ptr<TcpSocketState> tcb,
122                                    const TcpSocketState::TcpCongState_t newState);
123 
124   /**
125    * \brief Adjust cwnd following YeAH dual-mode algorithm
126    *
127    * \param tcb internal congestion state
128    * \param segmentsAcked count of segments ACKed
129    */
130   virtual void IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked);
131 
132   /**
133    * \brief Get slow start threshold upon the receipt of 3 dupACKs
134    *
135    * \param tcb internal congestion state
136    * \param bytesInFlight number of outstanding bytes
137    *
138    * \return the slow start threshold value
139    */
140   virtual uint32_t GetSsThresh (Ptr<const TcpSocketState> tcb,
141                                 uint32_t bytesInFlight);
142 
143   virtual Ptr<TcpCongestionOps> Fork ();
144 
145 protected:
146 private:
147   /**
148    * \brief Enable YeAH algorithm to start taking YeAH samples
149    *
150    * YeAH algorithm is enabled in the following situations:
151    * 1. at the establishment of a connection
152    * 2. after an RTO
153    * 3. after fast recovery
154    * 4. when an idle connection is restarted
155    *
156    * \param nextTxSequence Sequence to transmit next
157    */
158   void EnableYeah (const SequenceNumber32 &nextTxSequence);
159 
160   /**
161    * \brief Stop taking YeAH samples
162    */
163   void DisableYeah ();
164 
165 private:
166   uint32_t m_alpha;   //!< Maximum backlog allowed at the bottleneck queue; Q_max in the paper
167   uint32_t m_gamma;   //!< Fraction of queue to be removed per RTT when precautionary decongestion executed
168   uint32_t m_delta;   //!< Log minimum fraction of cwnd to be removed on loss
169   uint32_t m_epsilon; //!< Log maximum fraction to be removed on early decongestion
170   uint32_t m_phy;     //!< Maximum delta from base
171   uint32_t m_rho;     //!< Minimum number of consecutive RTT to consider competition with Reno flows on loss
172   uint32_t m_zeta;    //!< Minimum number of state switches to reset m_renoCount
173 
174   uint32_t m_stcpAiFactor;  //!< STCP additive increase parameter
175   Ptr<TcpScalable> m_stcp;  //!< TcpScalable object
176   Time m_baseRtt;           //!< Minimum of all YeAH RTT measurements seen during connection
177   Time m_minRtt;            //!< Minimum of all RTTs measured within last RTT
178   uint32_t m_cntRtt;        //!< Number of RTT measurements during last RTT
179   bool m_doingYeahNow;          //!< If true, do YeAH for this RTT
180   SequenceNumber32 m_begSndNxt; //!< Right edge during last RTT
181   uint32_t m_lastQ;             //!< Last number of packets in the bottleneck queue
182   uint32_t m_doingRenoNow;      //!< Number of RTTs in "Slow" mode
183   uint32_t m_renoCount;         //!< Estimated cwnd of competing Reno flow
184   uint32_t m_fastCount;         //!< Number of RTTs in "Fast" mode
185 };
186 
187 } // namespace ns3
188 
189 #endif // TCPYEAH_H
190