Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | |
2 /* | |
3 * Copyright (c) 2017 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 * Author: Shravya K.S. <shravya.ks0@gmail.com> | |
19 * | |
20 */ | |
21 | |
22 #include "tcp-dctcp.h" | |
23 #include "ns3/log.h" | |
24 #include "ns3/trace-source-accessor.h" | |
25 #include "ns3/simulator.h" | |
26 #include "ns3/abort.h" | |
27 #include "ns3/node.h" | |
28 #include "math.h" | |
29 #include "ns3/tcp-socket-base.h" | |
30 #include "ns3/sequence-number.h" | |
31 #include "ns3/double.h" | |
32 #include "ns3/nstime.h" | |
33 | |
34 namespace ns3 { | |
35 | |
36 NS_LOG_COMPONENT_DEFINE ("TcpDctcp"); | |
37 | |
38 NS_OBJECT_ENSURE_REGISTERED (TcpDctcp); | |
39 | |
40 TypeId TcpDctcp::GetTypeId (void) | |
41 { | |
42 static TypeId tid = TypeId ("ns3::TcpDctcp") | |
43 .SetParent<TcpNewReno> () | |
44 .AddConstructor<TcpDctcp> () | |
45 .SetGroupName ("Internet") | |
46 .AddAttribute ("DctcpShiftG", | |
Tom Henderson
2017/08/06 17:33:08
Why do these attribute names need to be prefixed b
Shravya
2017/08/26 08:25:12
Yes have corrected it
| |
47 "Parameter G for updating dctcp_alpha", | |
48 DoubleValue (0.0625), | |
49 MakeDoubleAccessor (&TcpDctcp::m_dctcpG), | |
50 MakeDoubleChecker<double> (0)) | |
51 .AddAttribute ("DctcpAlphaOnInit", | |
52 "Parameter for initial alpha value", | |
53 DoubleValue (0.0), | |
54 MakeDoubleAccessor (&TcpDctcp::SetDctcpAlpha), | |
55 MakeDoubleChecker<double> (0)) | |
56 ; | |
57 return tid; | |
58 } | |
59 | |
60 std::string TcpDctcp::GetName () const | |
61 { | |
62 return "TcpDctcp"; | |
63 } | |
64 | |
65 TcpDctcp::TcpDctcp () | |
66 : TcpNewReno (), | |
67 m_tsb (0) | |
68 { | |
69 NS_LOG_FUNCTION (this); | |
70 m_delayedAckReserved = false; | |
71 m_ceState = false; | |
72 m_ackedBytesEcn = 0; | |
73 m_ackedBytesTotal = 0; | |
74 m_priorRcvNxtFlag = false; | |
75 m_nextSeqFlag = false; | |
76 } | |
77 | |
78 TcpDctcp::TcpDctcp (const TcpDctcp& sock) | |
79 : TcpNewReno (sock), | |
80 m_tsb (sock.m_tsb) | |
81 { | |
82 NS_LOG_FUNCTION (this); | |
83 m_delayedAckReserved = (sock.m_delayedAckReserved); | |
84 m_ceState = (sock.m_ceState); | |
85 } | |
86 | |
87 TcpDctcp::~TcpDctcp (void) | |
88 { | |
89 NS_LOG_FUNCTION (this); | |
90 } | |
91 | |
92 void | |
93 TcpDctcp::SetSocketBase (Ptr<TcpSocketBase> tsb) | |
94 { | |
95 NS_LOG_FUNCTION (this << tsb); | |
96 m_tsb = tsb; | |
97 m_tsb->SetEcn (); | |
98 } | |
99 | |
100 Ptr<TcpCongestionOps> TcpDctcp::Fork (void) | |
101 { | |
102 NS_LOG_FUNCTION (this); | |
103 return CopyObject<TcpDctcp> (this); | |
104 } | |
105 | |
106 void | |
107 TcpDctcp::ReduceCwnd (Ptr<TcpSocketState> tcb) | |
108 { | |
109 NS_LOG_FUNCTION (this << tcb); | |
110 uint32_t val = (int)((1 - m_dctcpAlpha / 2.0) * tcb->m_cWnd); | |
111 tcb->m_cWnd = std::max (val, tcb->m_segmentSize); | |
112 } | |
113 | |
114 void | |
115 TcpDctcp::PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked, const Time &rtt) | |
116 { | |
117 NS_LOG_FUNCTION (this << tcb << segmentsAcked << rtt); | |
118 m_ackedBytesTotal += segmentsAcked * tcb->m_segmentSize; | |
119 if (tcb->m_ecnState == TcpSocketState::ECN_ECE_RCVD) | |
120 { | |
121 m_ackedBytesEcn += segmentsAcked * tcb->m_segmentSize; | |
122 } | |
123 if (m_nextSeqFlag == false) | |
124 { | |
125 m_nextSeq = tcb->m_nextTxSequence; | |
126 m_nextSeqFlag = true; | |
127 } | |
128 if (tcb->m_lastAckedSeq >= m_nextSeq) | |
129 { | |
130 double bytesEcn; | |
131 if (m_ackedBytesTotal > 0) | |
132 { | |
133 bytesEcn = (double) m_ackedBytesEcn / m_ackedBytesTotal; | |
134 } | |
135 else | |
136 { | |
137 bytesEcn = 0.0; | |
138 } | |
139 m_dctcpAlpha = (1.0 - m_dctcpG) * m_dctcpAlpha + m_dctcpG * bytesEcn; | |
140 Reset (tcb); | |
141 } | |
142 } | |
143 | |
144 void | |
145 TcpDctcp::SetDctcpAlpha (double alpha) | |
146 { | |
147 NS_LOG_FUNCTION (this << alpha); | |
148 m_dctcpAlpha = alpha; | |
149 } | |
150 | |
151 void | |
152 TcpDctcp::Reset (Ptr<TcpSocketState> tcb) | |
153 { | |
154 NS_LOG_FUNCTION (this << tcb); | |
155 m_nextSeq = tcb->m_nextTxSequence; | |
156 m_ackedBytesEcn = 0; | |
157 m_ackedBytesTotal = 0; | |
158 } | |
159 | |
160 void | |
161 TcpDctcp::CeState0to1 (Ptr<TcpSocketState> tcb) | |
162 { | |
163 NS_LOG_FUNCTION (this << tcb); | |
164 if (!m_ceState && m_delayedAckReserved && m_priorRcvNxtFlag) | |
165 { | |
166 SequenceNumber32 tmpRcvNxt; | |
167 /* Save current NextRxSequence. */ | |
168 tmpRcvNxt = m_tsb->m_rxBuffer->NextRxSequence (); | |
169 | |
170 /* Generate previous ack without ECE */ | |
171 m_tsb->m_rxBuffer->SetNextRxSequence (m_priorRcvNxt); | |
172 m_tsb->SendEmptyPacket (TcpHeader::ACK); | |
173 | |
174 /* Recover current rcv_nxt. */ | |
175 m_tsb->m_rxBuffer->SetNextRxSequence (tmpRcvNxt); | |
176 } | |
177 | |
178 if (m_priorRcvNxtFlag == false) | |
179 { | |
180 m_priorRcvNxtFlag = true; | |
181 } | |
182 m_priorRcvNxt = m_tsb->m_rxBuffer->NextRxSequence (); | |
183 m_ceState = true; | |
184 tcb->m_ecnState = TcpSocketState::ECN_CE_RCVD; | |
185 } | |
186 | |
187 void | |
188 TcpDctcp::CeState1to0 (Ptr<TcpSocketState> tcb) | |
189 { | |
190 NS_LOG_FUNCTION (this << tcb); | |
191 if (m_ceState && m_delayedAckReserved && m_priorRcvNxtFlag) | |
192 { | |
193 SequenceNumber32 tmpRcvNxt; | |
194 /* Save current NextRxSequence. */ | |
195 tmpRcvNxt = m_tsb->m_rxBuffer->NextRxSequence (); | |
196 | |
197 /* Generate previous ack with ECE */ | |
198 m_tsb->m_rxBuffer->SetNextRxSequence (m_priorRcvNxt); | |
199 m_tsb->SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | |
200 | |
201 /* Recover current rcv_nxt. */ | |
202 m_tsb->m_rxBuffer->SetNextRxSequence (tmpRcvNxt); | |
203 } | |
204 | |
205 if (m_priorRcvNxtFlag == false) | |
206 { | |
207 m_priorRcvNxtFlag = true; | |
208 } | |
209 m_priorRcvNxt = m_tsb->m_rxBuffer->NextRxSequence (); | |
210 m_ceState = false; | |
211 tcb->m_ecnState = TcpSocketState::ECN_IDLE; | |
212 } | |
213 | |
214 void | |
215 TcpDctcp::UpdateAckReserved (Ptr<TcpSocketState> tcb, | |
216 const TcpSocketState::TcpCaEvent_t event) | |
217 { | |
218 NS_LOG_FUNCTION (this << tcb << event); | |
219 switch (event) | |
220 { | |
221 case TcpSocketState::CA_EVENT_DELAYED_ACK: | |
222 if (!m_delayedAckReserved) | |
223 { | |
224 m_delayedAckReserved = true; | |
225 } | |
226 break; | |
227 case TcpSocketState::CA_EVENT_NON_DELAYED_ACK: | |
228 if (m_delayedAckReserved) | |
229 { | |
230 m_delayedAckReserved = false; | |
231 } | |
232 break; | |
233 default: | |
234 /* Don't care for the rest. */ | |
235 break; | |
236 } | |
237 } | |
238 | |
239 void | |
240 TcpDctcp::CwndEvent (Ptr<TcpSocketState> tcb, | |
241 const TcpSocketState::TcpCaEvent_t event) | |
242 { | |
243 NS_LOG_FUNCTION (this << tcb << event); | |
244 switch (event) | |
245 { | |
246 case TcpSocketState::CA_EVENT_ECN_IS_CE: | |
247 CeState0to1 (tcb); | |
248 break; | |
249 case TcpSocketState::CA_EVENT_ECN_NO_CE: | |
250 CeState1to0 (tcb); | |
251 break; | |
252 case TcpSocketState::CA_EVENT_DELAYED_ACK: | |
253 case TcpSocketState::CA_EVENT_NON_DELAYED_ACK: | |
254 UpdateAckReserved (tcb, event); | |
255 break; | |
256 default: | |
257 /* Don't care for the rest. */ | |
258 break; | |
259 } | |
260 | |
261 } | |
262 } | |
OLD | NEW |