1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com> 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 */ 19 #ifndef TCPCONGESTIONOPS_H 20 #define TCPCONGESTIONOPS_H 21 22 #include "tcp-rate-ops.h" 23 #include "tcp-socket-state.h" 24 25 namespace ns3 { 26 27 /** 28 * \ingroup tcp 29 * \defgroup congestionOps Congestion Control Algorithms. 30 * 31 * The various congestion control algorithms, also known as "TCP flavors". 32 */ 33 34 /** 35 * \ingroup congestionOps 36 * 37 * \brief Congestion control abstract class 38 * 39 * The design is inspired by what Linux v4.0 does (but it has been 40 * in place for years). The congestion control is split from the main 41 * socket code, and it is a pluggable component. An interface has been defined; 42 * variables are maintained in the TcpSocketState class, while subclasses of 43 * TcpCongestionOps operate over an instance of that class. 44 * 45 * Only three methods have been implemented right now; however, Linux has many others, 46 * which can be added later in ns-3. 47 * 48 * \see IncreaseWindow 49 * \see PktsAcked 50 */ 51 class TcpCongestionOps : public Object 52 { 53 public: 54 /** 55 * \brief Get the type ID. 56 * \return the object TypeId 57 */ 58 static TypeId GetTypeId (void); 59 60 TcpCongestionOps (); 61 62 /** 63 * \brief Copy constructor. 64 * \param other object to copy. 65 */ 66 TcpCongestionOps (const TcpCongestionOps &other); 67 68 virtual ~TcpCongestionOps (); 69 70 /** 71 * \brief Get the name of the congestion control algorithm 72 * 73 * \return A string identifying the name 74 */ 75 virtual std::string GetName () const = 0; 76 77 /** 78 * \brief Set configuration required by congestion control algorithm 79 * 80 * \param tcb internal congestion state 81 */ Init(Ptr<TcpSocketState> tcb)82 virtual void Init (Ptr<TcpSocketState> tcb) 83 { 84 NS_UNUSED (tcb); 85 } 86 87 /** 88 * \brief Get the slow start threshold after a loss event 89 * 90 * Is guaranteed that the congestion control state (\p TcpAckState_t) is 91 * changed BEFORE the invocation of this method. 92 * The implementator should return the slow start threshold (and not change 93 * it directly) because, in the future, the TCP implementation may require to 94 * instantly recover from a loss event (e.g. when there is a network with an high 95 * reordering factor). 96 * 97 * \param tcb internal congestion state 98 * \param bytesInFlight total bytes in flight 99 * \return Slow start threshold 100 */ 101 virtual uint32_t GetSsThresh (Ptr<const TcpSocketState> tcb, 102 uint32_t bytesInFlight) = 0; 103 104 /** 105 * \brief Congestion avoidance algorithm implementation 106 * 107 * Mimic the function \pname{cong_avoid} in Linux. New segments have been ACKed, 108 * and the congestion control duty is to update the window. 109 * 110 * The function is allowed to change directly cWnd and/or ssThresh. 111 * 112 * \param tcb internal congestion state 113 * \param segmentsAcked count of segments acked 114 */ 115 virtual void IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked); 116 117 /** 118 * \brief Timing information on received ACK 119 * 120 * The function is called every time an ACK is received (only one time 121 * also for cumulative ACKs) and contains timing information. It is 122 * optional (congestion controls need not implement it) and the default 123 * implementation does nothing. 124 * 125 * \param tcb internal congestion state 126 * \param segmentsAcked count of segments acked 127 * \param rtt last rtt 128 */ 129 virtual void PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked, 130 const Time& rtt); 131 132 /** 133 * \brief Trigger events/calculations specific to a congestion state 134 * 135 * This function mimics the notification function \pname{set_state} in Linux. 136 * The function does not change the congestion state in the tcb; it notifies 137 * the congestion control algorithm that this state is about to be changed. 138 * The tcb->m_congState variable must be separately set; for example: 139 * 140 * \code 141 * m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_RECOVERY); 142 * m_tcb->m_congState = TcpSocketState::CA_RECOVERY; 143 * \endcode 144 * 145 * \param tcb internal congestion state 146 * \param newState new congestion state to which the TCP is going to switch 147 */ 148 virtual void CongestionStateSet (Ptr<TcpSocketState> tcb, 149 const TcpSocketState::TcpCongState_t newState); 150 151 /** 152 * \brief Trigger events/calculations on occurrence of congestion window event 153 * 154 * This function mimics the function \pname{cwnd_event} in Linux. 155 * The function is called in case of congestion window events. 156 * 157 * \param tcb internal congestion state 158 * \param event the event which triggered this function 159 */ 160 virtual void CwndEvent (Ptr<TcpSocketState> tcb, 161 const TcpSocketState::TcpCAEvent_t event); 162 163 /** 164 * \brief Returns true when Congestion Control Algorithm implements CongControl 165 * 166 * \return true if CC implements CongControl function 167 * 168 * This function is the equivalent in C++ of the C checks that are used 169 * in the Linux kernel to see if an optional function has been defined. 170 * Since CongControl is optional, not all congestion controls have it. But, 171 * from the perspective of TcpSocketBase, the behavior is different if 172 * CongControl is present. Therefore, this check should return true for any 173 * congestion controls that implements the CongControl optional function. 174 */ 175 virtual bool HasCongControl () const; 176 177 /** 178 * \brief Called when packets are delivered to update cwnd and pacing rate 179 * 180 * This function mimics the function cong_control in Linux. It is allowed to 181 * change directly cWnd and pacing rate. 182 * 183 * \param tcb internal congestion state 184 * \param rc Rate information for the connection 185 * \param rs Rate sample (over a period of time) information 186 */ 187 virtual void CongControl (Ptr<TcpSocketState> tcb, 188 const TcpRateOps::TcpRateConnection &rc, 189 const TcpRateOps::TcpRateSample &rs); 190 191 // Present in Linux but not in ns-3 yet: 192 /* call when ack arrives (optional) */ 193 // void (*in_ack_event)(struct sock *sk, u32 flags); 194 /* new value of cwnd after loss (optional) */ 195 // u32 (*undo_cwnd)(struct sock *sk); 196 /* hook for packet ack accounting (optional) */ 197 // void (*pkts_acked)(struct sock *sk, u32 ext, int *attr, union tcp_cc_info *info); 198 199 /** 200 * \brief Copy the congestion control algorithm across sockets 201 * 202 * \return a pointer of the copied object 203 */ 204 virtual Ptr<TcpCongestionOps> Fork () = 0; 205 }; 206 207 /** 208 * \brief The NewReno implementation 209 * 210 * New Reno introduces partial ACKs inside the well-established Reno algorithm. 211 * This and other modifications are described in RFC 6582. 212 * 213 * \see IncreaseWindow 214 */ 215 class TcpNewReno : public TcpCongestionOps 216 { 217 public: 218 /** 219 * \brief Get the type ID. 220 * \return the object TypeId 221 */ 222 static TypeId GetTypeId (void); 223 224 TcpNewReno (); 225 226 /** 227 * \brief Copy constructor. 228 * \param sock object to copy. 229 */ 230 TcpNewReno (const TcpNewReno& sock); 231 232 ~TcpNewReno (); 233 234 std::string GetName () const; 235 236 virtual void IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked); 237 virtual uint32_t GetSsThresh (Ptr<const TcpSocketState> tcb, 238 uint32_t bytesInFlight); 239 virtual Ptr<TcpCongestionOps> Fork (); 240 241 protected: 242 virtual uint32_t SlowStart (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked); 243 virtual void CongestionAvoidance (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked); 244 }; 245 246 } // namespace ns3 247 248 #endif // TCPCONGESTIONOPS_H 249