1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2018 NITK Surathkal
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  * Authors: Vivek Jain <jain.vivek.anand@gmail.com>
19  *          Viyom Mittal <viyommittal@gmail.com>
20  *          Mohit P. Tahiliani <tahiliani@nitk.edu.in>
21  */
22 
23 #ifndef TCPBBR_H
24 #define TCPBBR_H
25 
26 #include "ns3/tcp-congestion-ops.h"
27 #include "ns3/traced-value.h"
28 #include "ns3/data-rate.h"
29 #include "ns3/random-variable-stream.h"
30 #include "ns3/windowed-filter.h"
31 
32 class TcpBbrCheckGainValuesTest;
33 
34 namespace ns3 {
35 
36 class TcpBbr : public TcpCongestionOps
37 {
38 public:
39   /**
40    * \brief The number of phases in the BBR ProbeBW gain cycle.
41    */
42   static const uint8_t GAIN_CYCLE_LENGTH = 8;
43 
44   /**
45    * \brief BBR uses an eight-phase cycle with the given pacing_gain value
46    * in the BBR ProbeBW gain cycle.
47    */
48   const static double PACING_GAIN_CYCLE [];
49   /**
50    * \brief Get the type ID.
51    * \return the object TypeId
52    */
53   static TypeId GetTypeId (void);
54 
55   /**
56    * \brief Constructor
57    */
58   TcpBbr ();
59 
60   /**
61    * Copy constructor.
62    * \param sock The socket to copy from.
63    */
64   TcpBbr (const TcpBbr &sock);
65 
66   /**
67    * \brief BBR has the following 4 modes for deciding how fast to send:
68    */
69   typedef enum
70   {
71     BBR_STARTUP,        /**< Ramp up sending rate rapidly to fill pipe */
72     BBR_DRAIN,          /**< Drain any queue created during startup */
73     BBR_PROBE_BW,       /**< Discover, share bw: pace around estimated bw */
74     BBR_PROBE_RTT,      /**< Cut inflight to min to probe min_rtt */
75   } BbrMode_t;
76 
77   typedef WindowedFilter<DataRate,
78                          MaxFilter<DataRate>,
79                          uint32_t,
80                          uint32_t>
81   MaxBandwidthFilter_t; //!< Definition of max bandwidth filter.
82 
83   /**
84    * \brief Literal names of BBR mode for use in log messages
85    */
86   static const char* const BbrModeName[BBR_PROBE_RTT + 1];
87 
88   /**
89    * Assign a fixed random variable stream number to the random variables
90    * used by this model.
91    *
92    * \param stream first stream index to use
93    */
94   virtual void SetStream (uint32_t stream);
95 
96   virtual std::string GetName () const;
97   virtual bool HasCongControl () const;
98   virtual void CongControl (Ptr<TcpSocketState> tcb,
99                             const TcpRateOps::TcpRateConnection &rc,
100                             const TcpRateOps::TcpRateSample &rs);
101   virtual void CongestionStateSet (Ptr<TcpSocketState> tcb,
102                                    const TcpSocketState::TcpCongState_t newState);
103   virtual void CwndEvent (Ptr<TcpSocketState> tcb,
104                           const TcpSocketState::TcpCAEvent_t event);
105   virtual uint32_t GetSsThresh (Ptr<const TcpSocketState> tcb,
106                                 uint32_t bytesInFlight);
107   virtual Ptr<TcpCongestionOps> Fork ();
108 
109 protected:
110   /**
111    * \brief TcpBbrCheckGainValuesTest friend class (for tests).
112    * \relates TcpBbrCheckGainValuesTest
113    */
114   friend class TcpBbrCheckGainValuesTest;
115 
116   /**
117    * \brief Advances pacing gain using cycle gain algorithm, while in BBR_PROBE_BW state
118    */
119   void AdvanceCyclePhase ();
120 
121   /**
122    * \brief Checks whether to advance pacing gain in BBR_PROBE_BW state,
123    *  and if allowed calls AdvanceCyclePhase ()
124    * \param tcb the socket state.
125    * \param rs rate sample.
126    */
127   void CheckCyclePhase (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
128 
129   /**
130    * \brief Checks whether its time to enter BBR_DRAIN or BBR_PROBE_BW state
131    * \param tcb the socket state.
132    */
133   void CheckDrain (Ptr<TcpSocketState> tcb);
134 
135   /**
136    * \brief Identifies whether pipe or BDP is already full
137    * \param rs rate sample.
138    */
139   void CheckFullPipe (const TcpRateOps::TcpRateSample &rs);
140 
141   /**
142    * \brief This method handles the steps related to the ProbeRTT state
143    * \param tcb the socket state.
144    * \param rs rate sample.
145    */
146   void CheckProbeRTT (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
147 
148   /**
149    * \brief Updates variables specific to BBR_DRAIN state
150    */
151   void EnterDrain ();
152 
153   /**
154    * \brief Updates variables specific to BBR_PROBE_BW state
155    */
156   void EnterProbeBW ();
157 
158   /**
159    * \brief Updates variables specific to BBR_PROBE_RTT state
160    */
161   void EnterProbeRTT ();
162 
163   /**
164    * \brief Updates variables specific to BBR_STARTUP state
165    */
166   void EnterStartup ();
167 
168   /**
169    * \brief Called on exiting from BBR_PROBE_RTT state, it eithers invoke EnterProbeBW () or EnterStartup ()
170    */
171   void ExitProbeRTT ();
172 
173   /**
174    * \brief Gets BBR state.
175    * \return returns BBR state.
176    */
177   uint32_t GetBbrState ();
178 
179   /**
180    * \brief Gets current pacing gain.
181    * \return returns current pacing gain.
182    */
183   double GetPacingGain ();
184 
185   /**
186    * \brief Gets current cwnd gain.
187    * \return returns current cwnd gain.
188    */
189   double GetCwndGain ();
190 
191   /**
192    * \brief Handles the steps for BBR_PROBE_RTT state.
193    * \param tcb the socket state.
194    */
195   void HandleProbeRTT (Ptr<TcpSocketState> tcb);
196 
197   /**
198    * \brief Updates pacing rate if socket is restarting from idle state.
199    * \param tcb the socket state.
200    * \param rs rate sample.
201    */
202   void HandleRestartFromIdle (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
203 
204   /**
205    * \brief Estimates the target value for congestion window
206    * \param tcb  the socket state.
207    * \param gain cwnd gain.
208    * \return returns congestion window based on max bandwidth and min RTT.
209    */
210   uint32_t InFlight (Ptr<TcpSocketState> tcb, double gain);
211 
212   /**
213    * \brief Intializes the full pipe estimator.
214    */
215   void InitFullPipe ();
216 
217   /**
218    * \brief Intializes the pacing rate.
219    * \param tcb  the socket state.
220    */
221   void InitPacingRate (Ptr<TcpSocketState> tcb);
222 
223   /**
224    * \brief Intializes the round counting related variables.
225    */
226   void InitRoundCounting ();
227 
228   /**
229    * \brief Checks whether to move to next value of pacing gain while in BBR_PROBE_BW.
230    * \param tcb the socket state.
231    * \param rs  rate sample.
232    * \returns true if want to move to next value otherwise false.
233    */
234   bool IsNextCyclePhase (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
235 
236   /**
237    * \brief Modulates congestion window in BBR_PROBE_RTT.
238    * \param tcb the socket state.
239    */
240   void ModulateCwndForProbeRTT (Ptr<TcpSocketState> tcb);
241 
242   /**
243    * \brief Modulates congestion window in CA_RECOVERY.
244    * \param tcb the socket state.
245    * \param rs rate sample.
246    * \return true if congestion window is updated in CA_RECOVERY.
247    */
248   bool ModulateCwndForRecovery (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
249 
250   /**
251    * \brief Helper to restore the last-known good congestion window
252    * \param tcb the socket state.
253    */
254   void RestoreCwnd (Ptr<TcpSocketState> tcb);
255 
256   /**
257    * \brief Helper to remember the last-known good congestion window or
258    *        the latest congestion window unmodulated by loss recovery or ProbeRTT.
259    * \param tcb the socket state.
260    */
261   void SaveCwnd (Ptr<const TcpSocketState> tcb);
262 
263   /**
264    * \brief Updates congestion window based on the network model.
265    * \param tcb the socket state.
266    * \param rs  rate sample
267    */
268   void SetCwnd (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
269 
270   /**
271    * \brief Updates pacing rate based on network model.
272    * \param tcb the socket state.
273    * \param gain pacing gain.
274    */
275   void SetPacingRate (Ptr<TcpSocketState> tcb, double gain);
276 
277   /**
278    * \brief Updates send quantum based on the network model.
279    * \param tcb the socket state.
280    */
281   void SetSendQuantum (Ptr<TcpSocketState> tcb);
282 
283   /**
284    * \brief Updates maximum bottleneck.
285    * \param tcb the socket state.
286    * \param rs rate sample.
287    */
288   void UpdateBtlBw (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
289 
290   /**
291    * \brief Updates control parameters congestion windowm, pacing rate, send quantum.
292    * \param tcb the socket state.
293    * \param rs rate sample.
294    */
295   void UpdateControlParameters (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
296 
297   /**
298    * \brief Updates BBR network model (Maximum bandwidth and minimum RTT).
299    * \param tcb the socket state.
300    * \param rs rate sample.
301    */
302   void UpdateModelAndState (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
303 
304   /**
305    * \brief Updates round counting related variables.
306    * \param tcb the socket state.
307    * \param rs rate sample.
308    */
309   void UpdateRound (Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
310 
311   /**
312    * \brief Updates minimum RTT.
313    * \param tcb the socket state.
314    */
315   void UpdateRTprop (Ptr<TcpSocketState> tcb);
316 
317   /**
318    * \brief Updates target congestion window.
319    * \param tcb the socket state.
320    */
321   void UpdateTargetCwnd (Ptr<TcpSocketState> tcb);
322 
323   /**
324    * \brief Sets BBR state.
325    * \param state BBR state.
326    */
327   void SetBbrState (BbrMode_t state);
328 
329   /**
330   * \brief Find Cwnd increment based on ack aggregation.
331   * \return uint32_t aggregate cwnd.
332   */
333   uint32_t AckAggregationCwnd();
334 
335   /**
336   * \brief Estimates max degree of aggregation.
337   * \param tcb the socket state.
338   * \param rs rate sample.
339   */
340   void UpdateAckAggregation(Ptr<TcpSocketState> tcb, const TcpRateOps::TcpRateSample &rs);
341 
342 private:
343   BbrMode_t   m_state        {BbrMode_t::BBR_STARTUP};           //!< Current state of BBR state machine
344   MaxBandwidthFilter_t   m_maxBwFilter;                          //!< Maximum bandwidth filter
345   uint32_t    m_bandwidthWindowLength       {0};                 //!< A constant specifying the length of the BBR.BtlBw max filter window, default 10 packet-timed round trips.
346   double      m_pacingGain                  {0};                 //!< The dynamic pacing gain factor
347   double      m_cWndGain                    {0};                 //!< The dynamic congestion window gain factor
348   double      m_highGain                    {0};                 //!< A constant specifying highest gain factor, default is 2.89
349   bool        m_isPipeFilled                {false};             //!< A boolean that records whether BBR has filled the pipe
350   uint32_t    m_minPipeCwnd                 {0};                 //!< The minimal congestion window value BBR tries to target, default 4 Segment size
351   uint32_t    m_roundCount                  {0};                 //!< Count of packet-timed round trips
352   bool        m_roundStart                  {false};             //!< A boolean that BBR sets to true once per packet-timed round trip
353   uint32_t    m_nextRoundDelivered          {0};                 //!< Denotes the end of a packet-timed round trip
354   Time        m_probeRttDuration            {MilliSeconds (200)};//!< A constant specifying the minimum duration for which ProbeRTT state, default 200 millisecs
355   Time        m_probeRtPropStamp            {Seconds (0)};       //!< The wall clock time at which the current BBR.RTProp sample was obtained.
356   Time        m_probeRttDoneStamp           {Seconds (0)};       //!< Time to exit from BBR_PROBE_RTT state
357   bool        m_probeRttRoundDone           {false};             //!< True when it is time to exit BBR_PROBE_RTT
358   bool        m_packetConservation          {false};             //!< Enable/Disable packet conservation mode
359   uint32_t    m_priorCwnd                   {0};                 //!< The last-known good congestion window
360   bool        m_idleRestart                 {false};             //!< When restarting from idle, set it true
361   uint32_t    m_targetCWnd                  {0};                 //!< Target value for congestion window, adapted to the estimated BDP
362   DataRate    m_fullBandwidth               {0};                 //!< Value of full bandwidth recorded
363   uint32_t    m_fullBandwidthCount          {0};                 //!< Count of full bandwidth recorded consistently
364   Time        m_rtProp                      {Time::Max ()};      //!< Estimated two-way round-trip propagation delay of the path, estimated from the windowed minimum recent round-trip delay sample.
365   uint32_t    m_sendQuantum                 {0};                 //!< The maximum size of a data aggregate scheduled and transmitted together
366   Time        m_cycleStamp                  {Seconds (0)};       //!< Last time gain cycle updated
367   uint32_t    m_cycleIndex                  {0};                 //!< Current index of gain cycle
368   bool        m_rtPropExpired               {false};             //!< A boolean recording whether the BBR.RTprop has expired
369   Time        m_rtPropFilterLen             {Seconds (10)};      //!< A constant specifying the length of the RTProp min filter window, default 10 secs.
370   Time        m_rtPropStamp                 {Seconds (0)};       //!< The wall clock time at which the current BBR.RTProp sample was obtained
371   bool        m_isInitialized               {false};             //!< Set to true after first time initializtion variables
372   Ptr<UniformRandomVariable> m_uv           {nullptr};           //!< Uniform Random Variable
373   uint64_t    m_delivered                   {0};                 //!< The total amount of data in bytes delivered so far
374   uint32_t    m_appLimited                  {0};                 //!< The index of the last transmitted packet marked as application-limited
375   uint32_t    m_txItemDelivered             {0};                 //!< The number of bytes already delivered at the time of new packet transmission
376   uint32_t    m_extraAckedGain              {1};                 //!< Gain factor for adding extra ack to cwnd
377   uint32_t    m_extraAcked [2]              {0, 0};              //!< Maximum excess data acked in epoch
378   uint32_t    m_extraAckedWinRtt            {0};                 //!< Age of extra acked in rtt
379   uint32_t    m_extraAckedWinRttLength      {5};                 //!< Window length of extra acked window
380   uint32_t    m_ackEpochAckedResetThresh    {1 << 17};           //!< Max allowed val for m_ackEpochAcked, after which sampling epoch is reset
381   uint32_t    m_extraAckedIdx               {0};                 //!< Current index in extra acked array
382   Time        m_ackEpochTime                {Seconds(0)};        //!< Starting of ACK sampling epoch time
383   uint32_t    m_ackEpochAcked               {0};                 //!< Bytes ACked in sampling epoch
384   bool        m_hasSeenRtt                  {false};             //!< Have we seen RTT sample yet?
385 };
386 
387 } // namespace ns3
388 #endif // TCPBBR_H
389