Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2014 Natale Patriciello <natale.patriciello@gmail.com> | 3 * Copyright (c) 2014 Natale Patriciello <natale.patriciello@gmail.com> |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 11 matching lines...) Expand all Loading... | |
22 | 22 |
23 #include "ns3/tcp-socket-base.h" | 23 #include "ns3/tcp-socket-base.h" |
24 #include "ns3/timer.h" | 24 #include "ns3/timer.h" |
25 | 25 |
26 | 26 |
27 namespace ns3 { | 27 namespace ns3 { |
28 | 28 |
29 /** | 29 /** |
30 * \brief The Cubic Congestion Control Algorithm | 30 * \brief The Cubic Congestion Control Algorithm |
31 * | 31 * |
32 * CUBIC is an implementation of TCP with an optimized congestion control | 32 * TCP Cubic is a protocol that enhances the fairness property |
33 * algorithm for high bandwidth networks with high latency (LFN: long fat | 33 * of Bic while retaining its scalability and stability. The main feature is |
34 * networks). | 34 * that the window growth function is defined in real time in order to be indepe ndent |
35 * | 35 * from the RTT. More specifically, the congestion window of Cubic is determined |
36 * It is a less aggressive and more systematic derivative of BIC TCP, | 36 * by a function of the elapsed time from the last window reduction. |
37 * in which the window is a cubic function of time since the last | 37 * |
38 * congestion event, with the inflection point set to the window prior to | 38 * The Cubic code is quite similar to that of Bic. |
39 * the event. Being a cubic function, there are two components to window | 39 * The main difference is located in the method Update, an edit |
40 * growth. The first is a concave portion where the window quickly ramps | 40 * necessary for satisfying the Cubic window growth, that can be tuned with |
41 * up to the window size before the last congestion event. Next is the convex | 41 * the attribute C (the Cubic scaling factor). |
42 * growth where CUBIC probes for more bandwidth, slowly at first then very | 42 * |
43 * rapidly. CUBIC spends a lot of time at a plateau between the concave | 43 * Following the Linux implementation, we included the Hybrid Slow Start, |
44 * and convex growth region which allows the network to stabilize before | 44 * that effectively prevents the overshooting of slow start |
45 * CUBIC begins looking for more bandwidth. | 45 * while maintaining a full utilization of the network. This new type of slow |
46 * | 46 * start can be disabled through the \Attribute{HyStart} attribute. |
47 * Another major difference between CUBIC and standard TCP flavors is | |
48 * that it does not rely on the receipt of ACKs to increase the | |
49 * window size. CUBIC's window size is dependent only on the last | |
50 * congestion event. With standard TCP, flows with very short RTTs | |
51 * will receive ACKs faster and therefore have their congestion windows | |
52 * grow faster than other flows with longer RTTs. CUBIC allows for more | |
53 * fairness between flows since the window growth is independent of RTT. | |
54 * | 47 * |
55 * CUBIC TCP is implemented and used by default in Linux kernels 2.6.19 | 48 * CUBIC TCP is implemented and used by default in Linux kernels 2.6.19 |
56 * and above; this version follows the implementation in Linux 3.14, which | 49 * and above; this version follows the implementation in Linux 3.14, which |
57 * slightly differ from the CUBIC paper. It also features HyStart. | 50 * slightly differ from the CUBIC paper. It also features HyStart. |
58 * | 51 * |
59 * Home page: | 52 * Home page: |
60 * http://netsrv.csc.ncsu.edu/twiki/bin/view/Main/BIC | 53 * http://netsrv.csc.ncsu.edu/twiki/bin/view/Main/BIC |
61 * The work starts from the implementation of CUBIC TCP in | 54 * The work starts from the implementation of CUBIC TCP in |
62 * Sangtae Ha, Injong Rhee and Lisong Xu, | 55 * Sangtae Ha, Injong Rhee and Lisong Xu, |
63 * "CUBIC: A New TCP-Friendly High-Speed TCP Variant" | 56 * "CUBIC: A New TCP-Friendly High-Speed TCP Variant" |
64 * in ACM SIGOPS Operating System Review, July 2008. | 57 * in ACM SIGOPS Operating System Review, July 2008. |
65 * Available from: | 58 * Available from: |
66 * http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf | 59 * http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf |
67 * | 60 * |
68 * CUBIC integrates a new slow start algorithm, called HyStart. | 61 * CUBIC integrates a new slow start algorithm, called HyStart. |
69 * The details of HyStart are presented in | 62 * The details of HyStart are presented in |
70 * Sangtae Ha and Injong Rhee, | 63 * Sangtae Ha and Injong Rhee, |
71 * "Taming the Elephants: New TCP Slow Start", NCSU TechReport 2008. | 64 * "Taming the Elephants: New TCP Slow Start", NCSU TechReport 2008. |
72 * Available from: | 65 * Available from: |
73 * http://netsrv.csc.ncsu.edu/export/hystart_techreport_2008.pdf | 66 * http://netsrv.csc.ncsu.edu/export/hystart_techreport_2008.pdf |
67 * | |
68 * More information on this implementation: http://dl.acm.org/citation.cfm?id=27 56518 | |
74 */ | 69 */ |
75 class TcpCubic : public TcpSocketBase | 70 class TcpCubic : public TcpSocketBase |
76 { | 71 { |
77 public: | 72 public: |
78 /** | 73 /** |
79 * \brief Get the type ID. | 74 * \brief Get the type ID. |
80 * \return the object TypeId | 75 * \return the object TypeId |
81 */ | 76 */ |
82 static TypeId GetTypeId (void); | 77 static TypeId GetTypeId (void); |
78 | |
79 /** | |
80 * \brief State of the congestion control machine: open or loss | |
81 */ | |
82 enum CubicState | |
83 { | |
84 OPEN = 0x1, //!< Open state | |
85 LOSS = 0x2, //!< Loss state | |
86 }; | |
83 | 87 |
84 TcpCubic (); | 88 TcpCubic (); |
85 | 89 |
86 // From TcpSocketBase | 90 // From TcpSocketBase |
87 virtual int Connect (const Address &address); | 91 virtual int Connect (const Address &address); |
88 virtual int Listen (void); | 92 virtual int Listen (void); |
89 | 93 |
90 protected: | 94 protected: |
91 // From TcpSocketBase | 95 // From TcpSocketBase |
92 virtual uint32_t Window (void); | 96 virtual uint32_t Window (void); |
93 virtual Ptr<TcpSocketBase> Fork (void); | 97 virtual Ptr<TcpSocketBase> Fork (void); |
94 virtual void NewAck (SequenceNumber32 const& seq); | 98 virtual void NewAck (SequenceNumber32 const& seq); |
95 virtual void DupAck (const TcpHeader& t, uint32_t count); | 99 virtual void DupAck (const TcpHeader& t, uint32_t count); |
96 virtual void Retransmit (void); | 100 virtual void Retransmit (void); |
97 | 101 |
98 // Implementing ns3::TcpSocket -- Attribute get/set | 102 // Implementing ns3::TcpSocket -- Attribute get/set |
99 virtual void SetInitialSSThresh (uint32_t threshold); | 103 virtual void SetInitialSSThresh (uint32_t threshold); |
100 virtual uint32_t GetInitialSSThresh (void) const; | 104 virtual uint32_t GetInitialSSThresh (void) const; |
101 virtual void SetInitialCwnd (uint32_t cwnd); | 105 virtual void SetInitialCwnd (uint32_t cwnd); |
102 virtual uint32_t GetInitialCwnd (void) const; | 106 virtual uint32_t GetInitialCwnd (void) const; |
103 virtual void ScaleSsThresh (uint8_t scaleFactor); | 107 virtual void ScaleSsThresh (uint8_t scaleFactor); |
104 | 108 |
105 | 109 |
106 protected: | 110 private: |
107 /** | 111 /** |
108 * \brief Values to detect the Slow Start mode of HyStart | 112 * \brief Values to detect the Slow Start mode of HyStart |
109 */ | 113 */ |
110 enum HybridSSDetectionMode | 114 enum HybridSSDetectionMode |
111 { | 115 { |
112 PACKET_TRAIN = 0x1, //!< Detection by trains of packet | 116 PACKET_TRAIN = 0x1, //!< Detection by trains of packet |
113 DELAY = 0x2 //!< Detection by delay value | 117 DELAY = 0x2 //!< Detection by delay value |
114 }; | |
115 | |
116 /** | |
117 * \brief State of the congestion control machine: open or loss | |
118 */ | |
119 enum CubicState | |
120 { | |
121 OPEN = 0x1, //!< Open state | |
122 LOSS = 0x2, //!< Loss state | |
123 }; | 118 }; |
Tom Henderson
2015/06/09 18:42:58
(question also applies to BIC) Do you think that C
| |
124 | 119 |
125 bool m_fastConvergence; //!< Enable or disable fast convergence algorithm | 120 bool m_fastConvergence; //!< Enable or disable fast convergence algorithm |
126 double m_beta; //!< Beta for cubic multiplicative increase | 121 double m_beta; //!< Beta for cubic multiplicative increase |
127 | 122 |
128 bool m_hystart; //!< Enable or disable HyStart algorithm | 123 bool m_hystart; //!< Enable or disable HyStart algorithm |
129 int m_hystartDetect; //!< Detect way for HyStart algorithm \see Hybrid SSDetectionMode | 124 int m_hystartDetect; //!< Detect way for HyStart algorithm \see Hybrid SSDetectionMode |
130 uint32_t m_hystartLowWindow; //!< Lower bound cWnd for hybrid slow start (segm ents) | 125 uint32_t m_hystartLowWindow; //!< Lower bound cWnd for hybrid slow start (segm ents) |
131 Time m_hystartAckDelta; //!< Spacing between ack's indicating train | 126 Time m_hystartAckDelta; //!< Spacing between ack's indicating train |
132 Time m_hystartDelayMin; //!< Minimum time for hystart algorithm | 127 Time m_hystartDelayMin; //!< Minimum time for hystart algorithm |
133 Time m_hystartDelayMax; //!< Maximum time for hystart algorithm | 128 Time m_hystartDelayMax; //!< Maximum time for hystart algorithm |
134 uint8_t m_hystartMinSamples;//!< Number of delay samples for detecting the in crease of delay | 129 uint8_t m_hystartMinSamples; //!< Number of delay samples for detecting the i ncrease of delay |
135 | 130 |
136 uint32_t m_initialCwnd; //!< Initial cWnd | 131 uint32_t m_initialCwnd; //!< Initial cWnd |
137 uint8_t m_cntClamp; //!< Modulo of the (avoided) float division for c Wnd | 132 uint8_t m_cntClamp; //!< Modulo of the (avoided) float division for c Wnd |
138 | 133 |
139 double m_c; //!< Cubic Scaling factor | 134 double m_c; //!< Cubic Scaling factor |
140 | 135 |
141 // Cubic parameters | 136 // Cubic parameters |
142 CubicState m_cubicState; //!< Cubic state \see CubicState | |
143 uint32_t m_cWndCnt; //!< cWnd integer-to-float counter | 137 uint32_t m_cWndCnt; //!< cWnd integer-to-float counter |
144 uint32_t m_lastMaxCwnd; //!< Last maximum cWnd | 138 uint32_t m_lastMaxCwnd; //!< Last maximum cWnd |
145 uint32_t m_bicOriginPoint; //!< Origin point of bic function | 139 uint32_t m_bicOriginPoint; //!< Origin point of bic function |
146 uint32_t m_bicK; //!< Time to origin point from the beginning of the current epoch | 140 uint32_t m_bicK; //!< Time to origin point from the beginning of the current epoch |
147 Time m_delayMin; //!< Min delay | 141 Time m_delayMin; //!< Min delay |
148 Time m_epochStart; //!< Beginning of an epoch | 142 Time m_epochStart; //!< Beginning of an epoch |
149 uint8_t m_found; //!< The exit point is found? | 143 uint8_t m_found; //!< The exit point is found? |
150 Time m_roundStart; //!< Beginning of each round | 144 Time m_roundStart; //!< Beginning of each round |
151 SequenceNumber32 m_endSeq; //!< End sequence of the round | 145 SequenceNumber32 m_endSeq; //!< End sequence of the round |
152 Time m_lastAck; //!< Last time when the ACK spacing is close | 146 Time m_lastAck; //!< Last time when the ACK spacing is close |
153 Time m_cubicDelta; //!< Time to wait after recovery before updat e | 147 Time m_cubicDelta; //!< Time to wait after recovery before updat e |
154 Time m_currRtt; //!< Current Rtt | 148 Time m_currRtt; //!< Current Rtt |
155 uint32_t m_sampleCnt; | 149 uint32_t m_sampleCnt; //!< Count of samples for HyStart |
156 | 150 |
157 TracedValue<uint32_t> m_cWnd; //!< Congestion window | 151 TracedValue<uint32_t> m_cWnd; //!< Congestion window |
158 TracedValue<uint32_t> m_ssThresh; //!< Slow start threshold | 152 TracedValue<uint32_t> m_ssThresh; //!< Slow start threshold |
153 TracedValue<uint8_t> m_cubicState;//!< Cubic state \see CubicState | |
159 | 154 |
160 private: | 155 private: |
161 /** | 156 /** |
162 * \brief Reset BIC parameters | 157 * \brief Reset BIC parameters |
163 */ | 158 */ |
164 void Reset (void); | 159 void Reset (void); |
165 | 160 |
166 /** | 161 /** |
167 * \brief Reset HyStart parameters | 162 * \brief Reset HyStart parameters |
168 */ | 163 */ |
169 void HystartReset (void); | 164 void HystartReset (void); |
170 | 165 |
171 /** | 166 /** |
172 * \brief Initialize the algorithm | 167 * \brief Initialize the algorithm |
173 */ | 168 */ |
174 void Init (void); | 169 void Init (void); |
175 | 170 |
176 /** | 171 /** |
177 * \brief Update HyStart parameters | 172 * \brief Update HyStart parameters |
178 * | 173 * |
179 * \param delay Delay for HyStart algorithm | 174 * \param delay Delay for HyStart algorithm |
180 */ | 175 */ |
181 void HystartUpdate (const Time& delay); | 176 void HystartUpdate (const Time &delay); |
Tom Henderson
2015/06/09 18:42:58
for API consistency, pass Time in as value (you do
| |
182 | 177 |
183 /** | 178 /** |
184 * \brief Clamp time value in a range | 179 * \brief Clamp time value in a range |
185 * | 180 * |
186 * The returned value is t, clamped in a range specified | 181 * The returned value is t, clamped in a range specified |
187 * by attributes (HystartDelayMin < t < HystartDelayMax) | 182 * by attributes (HystartDelayMin < t < HystartDelayMax) |
188 * | 183 * |
189 * \param t Time value to clamp | 184 * \param t Time value to clamp |
190 * \return t itself if it is in range, otherwise the min or max | 185 * \return t itself if it is in range, otherwise the min or max |
191 * value | 186 * value |
192 */ | 187 */ |
193 Time HystartDelayThresh (Time t) const; | 188 Time HystartDelayThresh (const Time &t) const; |
194 | 189 |
195 /** | 190 /** |
196 * \brief Timing calculation about acks | 191 * \brief Timing calculation about acks |
197 */ | 192 */ |
198 void PktsAcked (void); | 193 void PktsAcked (void); |
199 | 194 |
200 /** | 195 /** |
201 * \brief The congestion avoidance phase of Cubic | 196 * \brief The congestion avoidance phase of Cubic |
202 * | 197 * |
203 * \param seq The sequence number acked | 198 * \param seq The sequence number acked |
204 */ | 199 */ |
205 void CongAvoid (const SequenceNumber32 &seq); | 200 void CongAvoid (const SequenceNumber32 &seq); |
206 | 201 |
207 /** | 202 /** |
208 * \brief Cubic window update after a new ack received | 203 * \brief Cubic window update after a new ack received |
209 */ | 204 */ |
210 uint32_t WindowUpdate (void); | 205 uint32_t WindowUpdate (void); |
211 | 206 |
212 /** | 207 /** |
213 * \brief Cubic window update after a loss | 208 * \brief Cubic window update after a loss |
214 */ | 209 */ |
215 void RecalcSsthresh (void); | 210 void RecalcSsthresh (void); |
216 }; | 211 }; |
217 | 212 |
218 } | 213 } |
219 | 214 |
220 #endif // TCPCUBIC_H | 215 #endif // TCPCUBIC_H |
LEFT | RIGHT |