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