OLD | NEW |
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) 2007 Georgia Tech Research Corporation | 3 * Copyright (c) 2007 Georgia Tech Research Corporation |
4 * Copyright (c) 2010 Adrian Sai-wah Tam | 4 * Copyright (c) 2010 Adrian Sai-wah Tam |
5 * | 5 * |
6 * This program is free software; you can redistribute it and/or modify | 6 * This program is free software; you can redistribute it and/or modify |
7 * it under the terms of the GNU General Public License version 2 as | 7 * it under the terms of the GNU General Public License version 2 as |
8 * published by the Free Software Foundation; | 8 * published by the Free Software Foundation; |
9 * | 9 * |
10 * This program is distributed in the hope that it will be useful, | 10 * This program is distributed in the hope that it will be useful, |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 MakePointerAccessor (&TcpSocketBase::GetRxBuffer), | 128 MakePointerAccessor (&TcpSocketBase::GetRxBuffer), |
129 MakePointerChecker<TcpRxBuffer> ()) | 129 MakePointerChecker<TcpRxBuffer> ()) |
130 .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit", | 130 .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit", |
131 UintegerValue (3), | 131 UintegerValue (3), |
132 MakeUintegerAccessor (&TcpSocketBase::m_retxThresh), | 132 MakeUintegerAccessor (&TcpSocketBase::m_retxThresh), |
133 MakeUintegerChecker<uint32_t> ()) | 133 MakeUintegerChecker<uint32_t> ()) |
134 .AddAttribute ("LimitedTransmit", "Enable limited transmit", | 134 .AddAttribute ("LimitedTransmit", "Enable limited transmit", |
135 BooleanValue (true), | 135 BooleanValue (true), |
136 MakeBooleanAccessor (&TcpSocketBase::m_limitedTx), | 136 MakeBooleanAccessor (&TcpSocketBase::m_limitedTx), |
137 MakeBooleanChecker ()) | 137 MakeBooleanChecker ()) |
| 138 .AddAttribute ("UseEcn", "True to use ECN functionality", |
| 139 BooleanValue (false), |
| 140 MakeBooleanAccessor (&TcpSocketBase::m_ecn), |
| 141 MakeBooleanChecker ()) |
138 .AddTraceSource ("RTO", | 142 .AddTraceSource ("RTO", |
139 "Retransmission timeout", | 143 "Retransmission timeout", |
140 MakeTraceSourceAccessor (&TcpSocketBase::m_rto), | 144 MakeTraceSourceAccessor (&TcpSocketBase::m_rto), |
141 "ns3::Time::TracedValueCallback") | 145 "ns3::Time::TracedValueCallback") |
142 .AddTraceSource ("RTT", | 146 .AddTraceSource ("RTT", |
143 "Last RTT sample", | 147 "Last RTT sample", |
144 MakeTraceSourceAccessor (&TcpSocketBase::m_lastRtt), | 148 MakeTraceSourceAccessor (&TcpSocketBase::m_lastRtt), |
145 "ns3::Time::TracedValueCallback") | 149 "ns3::Time::TracedValueCallback") |
146 .AddTraceSource ("NextTxSequence", | 150 .AddTraceSource ("NextTxSequence", |
147 "Next sequence number to send (SND.NXT)", | 151 "Next sequence number to send (SND.NXT)", |
148 MakeTraceSourceAccessor (&TcpSocketBase::m_nextTxSequenceTr
ace), | 152 MakeTraceSourceAccessor (&TcpSocketBase::m_nextTxSequenceTr
ace), |
149 "ns3::SequenceNumber32TracedValueCallback") | 153 "ns3::SequenceNumber32TracedValueCallback") |
150 .AddTraceSource ("HighestSequence", | 154 .AddTraceSource ("HighestSequence", |
151 "Highest sequence number ever sent in socket's life time", | 155 "Highest sequence number ever sent in socket's life time", |
152 MakeTraceSourceAccessor (&TcpSocketBase::m_highTxMarkTrace)
, | 156 MakeTraceSourceAccessor (&TcpSocketBase::m_highTxMarkTrace)
, |
153 "ns3::SequenceNumber32TracedValueCallback") | 157 "ns3::SequenceNumber32TracedValueCallback") |
154 .AddTraceSource ("State", | 158 .AddTraceSource ("State", |
155 "TCP state", | 159 "TCP state", |
156 MakeTraceSourceAccessor (&TcpSocketBase::m_state), | 160 MakeTraceSourceAccessor (&TcpSocketBase::m_state), |
157 "ns3::TcpStatesTracedValueCallback") | 161 "ns3::TcpStatesTracedValueCallback") |
158 .AddTraceSource ("CongState", | 162 .AddTraceSource ("CongState", |
159 "TCP Congestion machine state", | 163 "TCP Congestion machine state", |
160 MakeTraceSourceAccessor (&TcpSocketBase::m_congStateTrace), | 164 MakeTraceSourceAccessor (&TcpSocketBase::m_congStateTrace), |
161 "ns3::TcpSocketState::TcpCongStatesTracedValueCallback") | 165 "ns3::TcpSocketState::TcpCongStatesTracedValueCallback") |
| 166 .AddTraceSource ("EcnState", |
| 167 "Current ECN State of TCP Socket", |
| 168 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnStateTrace), |
| 169 "ns3::TcpSocketState::EcnStatesTracedValueCallback") |
162 .AddTraceSource ("AdvWND", | 170 .AddTraceSource ("AdvWND", |
163 "Advertised Window Size", | 171 "Advertised Window Size", |
164 MakeTraceSourceAccessor (&TcpSocketBase::m_advWnd), | 172 MakeTraceSourceAccessor (&TcpSocketBase::m_advWnd), |
165 "ns3::TracedValueCallback::Uint32") | 173 "ns3::TracedValueCallback::Uint32") |
166 .AddTraceSource ("RWND", | 174 .AddTraceSource ("RWND", |
167 "Remote side's flow control window", | 175 "Remote side's flow control window", |
168 MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd), | 176 MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd), |
169 "ns3::TracedValueCallback::Uint32") | 177 "ns3::TracedValueCallback::Uint32") |
170 .AddTraceSource ("BytesInFlight", | 178 .AddTraceSource ("BytesInFlight", |
171 "Socket estimation of bytes in flight", | 179 "Socket estimation of bytes in flight", |
(...skipping 16 matching lines...) Expand all Loading... |
188 MakeTraceSourceAccessor (&TcpSocketBase::m_ssThTrace), | 196 MakeTraceSourceAccessor (&TcpSocketBase::m_ssThTrace), |
189 "ns3::TracedValueCallback::Uint32") | 197 "ns3::TracedValueCallback::Uint32") |
190 .AddTraceSource ("Tx", | 198 .AddTraceSource ("Tx", |
191 "Send tcp packet to IP protocol", | 199 "Send tcp packet to IP protocol", |
192 MakeTraceSourceAccessor (&TcpSocketBase::m_txTrace), | 200 MakeTraceSourceAccessor (&TcpSocketBase::m_txTrace), |
193 "ns3::TcpSocketBase::TcpTxRxTracedCallback") | 201 "ns3::TcpSocketBase::TcpTxRxTracedCallback") |
194 .AddTraceSource ("Rx", | 202 .AddTraceSource ("Rx", |
195 "Receive tcp packet from IP protocol", | 203 "Receive tcp packet from IP protocol", |
196 MakeTraceSourceAccessor (&TcpSocketBase::m_rxTrace), | 204 MakeTraceSourceAccessor (&TcpSocketBase::m_rxTrace), |
197 "ns3::TcpSocketBase::TcpTxRxTracedCallback") | 205 "ns3::TcpSocketBase::TcpTxRxTracedCallback") |
| 206 .AddTraceSource ("EcnEchoSeq", |
| 207 "Sequence of last received ECN Echo", |
| 208 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnEchoSeq), |
| 209 "ns3::SequenceNumber32TracedValueCallback") |
| 210 .AddTraceSource ("EcnCESeq", |
| 211 "Sequence of last received CE ", |
| 212 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnCESeq), |
| 213 "ns3::SequenceNumber32TracedValueCallback") |
| 214 .AddTraceSource ("EcnCWRSeq", |
| 215 "Sequence of last received CWR", |
| 216 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnCWRSeq), |
| 217 "ns3::SequenceNumber32TracedValueCallback") |
198 ; | 218 ; |
199 return tid; | 219 return tid; |
200 } | 220 } |
201 | 221 |
202 TypeId | 222 TypeId |
203 TcpSocketBase::GetInstanceTypeId () const | 223 TcpSocketBase::GetInstanceTypeId () const |
204 { | 224 { |
205 return TcpSocketBase::GetTypeId (); | 225 return TcpSocketBase::GetTypeId (); |
206 } | 226 } |
207 | 227 |
(...skipping 10 matching lines...) Expand all Loading... |
218 MakeTraceSourceAccessor (&TcpSocketState::m_cWnd), | 238 MakeTraceSourceAccessor (&TcpSocketState::m_cWnd), |
219 "ns3::TracedValue::Uint32Callback") | 239 "ns3::TracedValue::Uint32Callback") |
220 .AddTraceSource ("SlowStartThreshold", | 240 .AddTraceSource ("SlowStartThreshold", |
221 "TCP slow start threshold (bytes)", | 241 "TCP slow start threshold (bytes)", |
222 MakeTraceSourceAccessor (&TcpSocketState::m_ssThresh), | 242 MakeTraceSourceAccessor (&TcpSocketState::m_ssThresh), |
223 "ns3::TracedValue::Uint32Callback") | 243 "ns3::TracedValue::Uint32Callback") |
224 .AddTraceSource ("CongState", | 244 .AddTraceSource ("CongState", |
225 "TCP Congestion machine state", | 245 "TCP Congestion machine state", |
226 MakeTraceSourceAccessor (&TcpSocketState::m_congState), | 246 MakeTraceSourceAccessor (&TcpSocketState::m_congState), |
227 "ns3::TracedValue::TcpCongStatesTracedValueCallback") | 247 "ns3::TracedValue::TcpCongStatesTracedValueCallback") |
| 248 .AddTraceSource ("EcnState", |
| 249 "Current ECN State of TCP Socket", |
| 250 MakeTraceSourceAccessor (&TcpSocketState::m_ecnState), |
| 251 "ns3::TracedValue::EcnStatesTracedValueCallback") |
228 .AddTraceSource ("HighestSequence", | 252 .AddTraceSource ("HighestSequence", |
229 "Highest sequence number received from peer", | 253 "Highest sequence number received from peer", |
230 MakeTraceSourceAccessor (&TcpSocketState::m_highTxMark), | 254 MakeTraceSourceAccessor (&TcpSocketState::m_highTxMark), |
231 "ns3::SequenceNumber32TracedValueCallback") | 255 "ns3::SequenceNumber32TracedValueCallback") |
232 .AddTraceSource ("NextTxSequence", | 256 .AddTraceSource ("NextTxSequence", |
233 "Next sequence number to send (SND.NXT)", | 257 "Next sequence number to send (SND.NXT)", |
234 MakeTraceSourceAccessor (&TcpSocketState::m_nextTxSequence)
, | 258 MakeTraceSourceAccessor (&TcpSocketState::m_nextTxSequence)
, |
235 "ns3::SequenceNumber32TracedValueCallback") | 259 "ns3::SequenceNumber32TracedValueCallback") |
236 ; | 260 ; |
237 return tid; | 261 return tid; |
238 } | 262 } |
239 | 263 |
240 TcpSocketState::TcpSocketState (void) | 264 TcpSocketState::TcpSocketState (void) |
241 : Object (), | 265 : Object (), |
242 m_cWnd (0), | 266 m_cWnd (0), |
243 m_ssThresh (0), | 267 m_ssThresh (0), |
244 m_initialCWnd (0), | 268 m_initialCWnd (0), |
245 m_initialSsThresh (0), | 269 m_initialSsThresh (0), |
246 m_segmentSize (0), | 270 m_segmentSize (0), |
247 m_lastAckedSeq (0), | 271 m_lastAckedSeq (0), |
248 m_congState (CA_OPEN), | 272 m_congState (CA_OPEN), |
| 273 m_ecnState (ECN_DISABLED), |
249 m_highTxMark (0), | 274 m_highTxMark (0), |
250 // Change m_nextTxSequence for non-zero initial sequence number | 275 // Change m_nextTxSequence for non-zero initial sequence number |
251 m_nextTxSequence (0), | 276 m_nextTxSequence (0), |
252 m_rcvTimestampValue (0), | 277 m_rcvTimestampValue (0), |
253 m_rcvTimestampEchoReply (0) | 278 m_rcvTimestampEchoReply (0) |
254 { | 279 { |
255 } | 280 } |
256 | 281 |
257 TcpSocketState::TcpSocketState (const TcpSocketState &other) | 282 TcpSocketState::TcpSocketState (const TcpSocketState &other) |
258 : Object (other), | 283 : Object (other), |
259 m_cWnd (other.m_cWnd), | 284 m_cWnd (other.m_cWnd), |
260 m_ssThresh (other.m_ssThresh), | 285 m_ssThresh (other.m_ssThresh), |
261 m_initialCWnd (other.m_initialCWnd), | 286 m_initialCWnd (other.m_initialCWnd), |
262 m_initialSsThresh (other.m_initialSsThresh), | 287 m_initialSsThresh (other.m_initialSsThresh), |
263 m_segmentSize (other.m_segmentSize), | 288 m_segmentSize (other.m_segmentSize), |
264 m_lastAckedSeq (other.m_lastAckedSeq), | 289 m_lastAckedSeq (other.m_lastAckedSeq), |
265 m_congState (other.m_congState), | 290 m_congState (other.m_congState), |
| 291 m_ecnState (other.m_ecnState), |
266 m_highTxMark (other.m_highTxMark), | 292 m_highTxMark (other.m_highTxMark), |
267 m_nextTxSequence (other.m_nextTxSequence), | 293 m_nextTxSequence (other.m_nextTxSequence), |
268 m_rcvTimestampValue (other.m_rcvTimestampValue), | 294 m_rcvTimestampValue (other.m_rcvTimestampValue), |
269 m_rcvTimestampEchoReply (other.m_rcvTimestampEchoReply) | 295 m_rcvTimestampEchoReply (other.m_rcvTimestampEchoReply) |
270 { | 296 { |
271 } | 297 } |
272 | 298 |
273 const char* const | 299 const char* const |
274 TcpSocketState::TcpCongStateName[TcpSocketState::CA_LAST_STATE] = | 300 TcpSocketState::TcpCongStateName[TcpSocketState::CA_LAST_STATE] = |
275 { | 301 { |
276 "CA_OPEN", "CA_DISORDER", "CA_CWR", "CA_RECOVERY", "CA_LOSS" | 302 "CA_OPEN", "CA_DISORDER", "CA_CWR", "CA_RECOVERY", "CA_LOSS" |
277 }; | 303 }; |
278 | 304 |
| 305 const char* const |
| 306 TcpSocketState::EcnStateName[TcpSocketState::ECN_CWR_SENT+1] =· |
| 307 {· |
| 308 "ECN_DISABLED", "ECN_IDLE", "ECN_CE_RCVD", "ECN_ECE_SENT", "ECN_ECE_RCVD", "EC
N_CWR_SENT" |
| 309 }; |
| 310 |
| 311 |
279 TcpSocketBase::TcpSocketBase (void) | 312 TcpSocketBase::TcpSocketBase (void) |
280 : TcpSocket (), | 313 : TcpSocket (), |
281 m_retxEvent (), | 314 m_retxEvent (), |
282 m_lastAckEvent (), | 315 m_lastAckEvent (), |
283 m_delAckEvent (), | 316 m_delAckEvent (), |
284 m_persistEvent (), | 317 m_persistEvent (), |
285 m_timewaitEvent (), | 318 m_timewaitEvent (), |
286 m_dupAckCount (0), | 319 m_dupAckCount (0), |
287 m_delAckCount (0), | 320 m_delAckCount (0), |
288 m_delAckMaxCount (0), | 321 m_delAckMaxCount (0), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 m_rcvWindShift (0), | 358 m_rcvWindShift (0), |
326 m_sndWindShift (0), | 359 m_sndWindShift (0), |
327 m_timestampEnabled (true), | 360 m_timestampEnabled (true), |
328 m_timestampToEcho (0), | 361 m_timestampToEcho (0), |
329 m_sendPendingDataEvent (), | 362 m_sendPendingDataEvent (), |
330 // Set m_recover to the initial sequence number | 363 // Set m_recover to the initial sequence number |
331 m_recover (0), | 364 m_recover (0), |
332 m_retxThresh (3), | 365 m_retxThresh (3), |
333 m_limitedTx (false), | 366 m_limitedTx (false), |
334 m_congestionControl (0), | 367 m_congestionControl (0), |
335 m_isFirstPartialAck (true) | 368 m_isFirstPartialAck (true), |
| 369 m_ecn(false), |
| 370 m_ecnEchoSeq (0), |
| 371 m_ecnCESeq (0), |
| 372 m_ecnCWRSeq (0) |
| 373 ···· |
336 { | 374 { |
337 NS_LOG_FUNCTION (this); | 375 NS_LOG_FUNCTION (this); |
338 m_rxBuffer = CreateObject<TcpRxBuffer> (); | 376 m_rxBuffer = CreateObject<TcpRxBuffer> (); |
339 m_txBuffer = CreateObject<TcpTxBuffer> (); | 377 m_txBuffer = CreateObject<TcpTxBuffer> (); |
340 m_tcb = CreateObject<TcpSocketState> (); | 378 m_tcb = CreateObject<TcpSocketState> (); |
341 | 379 |
342 bool ok; | 380 bool ok; |
343 | 381 |
344 ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow", | 382 ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow", |
345 MakeCallback (&TcpSocketBase::UpdateCw
nd, this)); | 383 MakeCallback (&TcpSocketBase::UpdateCw
nd, this)); |
346 NS_ASSERT (ok == true); | 384 NS_ASSERT (ok == true); |
347 | 385 |
348 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", | 386 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", |
349 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); | 387 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); |
350 NS_ASSERT (ok == true); | 388 NS_ASSERT (ok == true); |
351 | 389 |
352 ok = m_tcb->TraceConnectWithoutContext ("CongState", | 390 ok = m_tcb->TraceConnectWithoutContext ("CongState", |
353 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); | 391 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); |
354 NS_ASSERT (ok == true); | 392 NS_ASSERT (ok == true); |
355 | 393 |
| 394 ok = m_tcb->TraceConnectWithoutContext ("EcnState", |
| 395 MakeCallback (&TcpSocketBase::UpdateEc
nState, this)); |
| 396 NS_ASSERT (ok == true); |
| 397 |
356 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", | 398 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", |
357 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); | 399 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); |
358 NS_ASSERT (ok == true); | 400 NS_ASSERT (ok == true); |
359 | 401 |
360 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", | 402 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", |
361 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); | 403 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); |
362 NS_ASSERT (ok == true); | 404 NS_ASSERT (ok == true); |
363 } | 405 } |
364 | 406 |
365 TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) | 407 TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 m_winScalingEnabled (sock.m_winScalingEnabled), | 444 m_winScalingEnabled (sock.m_winScalingEnabled), |
403 m_rcvWindShift (sock.m_rcvWindShift), | 445 m_rcvWindShift (sock.m_rcvWindShift), |
404 m_sndWindShift (sock.m_sndWindShift), | 446 m_sndWindShift (sock.m_sndWindShift), |
405 m_timestampEnabled (sock.m_timestampEnabled), | 447 m_timestampEnabled (sock.m_timestampEnabled), |
406 m_timestampToEcho (sock.m_timestampToEcho), | 448 m_timestampToEcho (sock.m_timestampToEcho), |
407 m_recover (sock.m_recover), | 449 m_recover (sock.m_recover), |
408 m_retxThresh (sock.m_retxThresh), | 450 m_retxThresh (sock.m_retxThresh), |
409 m_limitedTx (sock.m_limitedTx), | 451 m_limitedTx (sock.m_limitedTx), |
410 m_isFirstPartialAck (sock.m_isFirstPartialAck), | 452 m_isFirstPartialAck (sock.m_isFirstPartialAck), |
411 m_txTrace (sock.m_txTrace), | 453 m_txTrace (sock.m_txTrace), |
412 m_rxTrace (sock.m_rxTrace) | 454 m_rxTrace (sock.m_rxTrace), |
| 455 m_ecn (sock.m_ecn), |
| 456 m_ecnEchoSeq (sock.m_ecnEchoSeq), |
| 457 m_ecnCWRSeq (sock.m_ecnCWRSeq) |
413 { | 458 { |
414 NS_LOG_FUNCTION (this); | 459 NS_LOG_FUNCTION (this); |
415 NS_LOG_LOGIC ("Invoked the copy constructor"); | 460 NS_LOG_LOGIC ("Invoked the copy constructor"); |
416 // Copy the rtt estimator if it is set | 461 // Copy the rtt estimator if it is set |
417 if (sock.m_rtt) | 462 if (sock.m_rtt) |
418 { | 463 { |
419 m_rtt = sock.m_rtt->Copy (); | 464 m_rtt = sock.m_rtt->Copy (); |
420 } | 465 } |
421 // Reset all callbacks to null | 466 // Reset all callbacks to null |
422 Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > (); | 467 Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > (); |
(...skipping 18 matching lines...) Expand all Loading... |
441 NS_ASSERT (ok == true); | 486 NS_ASSERT (ok == true); |
442 | 487 |
443 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", | 488 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", |
444 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); | 489 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); |
445 NS_ASSERT (ok == true); | 490 NS_ASSERT (ok == true); |
446 | 491 |
447 ok = m_tcb->TraceConnectWithoutContext ("CongState", | 492 ok = m_tcb->TraceConnectWithoutContext ("CongState", |
448 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); | 493 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); |
449 NS_ASSERT (ok == true); | 494 NS_ASSERT (ok == true); |
450 | 495 |
| 496 ok = m_tcb->TraceConnectWithoutContext ("EcnState", |
| 497 MakeCallback (&TcpSocketBase::UpdateEc
nState, this)); |
| 498 NS_ASSERT (ok == true); |
| 499 |
451 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", | 500 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", |
452 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); | 501 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); |
453 NS_ASSERT (ok == true); | 502 NS_ASSERT (ok == true); |
454 | 503 |
455 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", | 504 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", |
456 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); | 505 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); |
457 NS_ASSERT (ok == true); | 506 NS_ASSERT (ok == true); |
458 } | 507 } |
459 | 508 |
460 TcpSocketBase::~TcpSocketBase (void) | 509 TcpSocketBase::~TcpSocketBase (void) |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); | 621 InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); |
573 Ipv4Address ipv4 = transport.GetIpv4 (); | 622 Ipv4Address ipv4 = transport.GetIpv4 (); |
574 uint16_t port = transport.GetPort (); | 623 uint16_t port = transport.GetPort (); |
575 SetIpTos (transport.GetTos ()); | 624 SetIpTos (transport.GetTos ()); |
576 if (ipv4 == Ipv4Address::GetAny () && port == 0) | 625 if (ipv4 == Ipv4Address::GetAny () && port == 0) |
577 { | 626 { |
578 m_endPoint = m_tcp->Allocate (); | 627 m_endPoint = m_tcp->Allocate (); |
579 } | 628 } |
580 else if (ipv4 == Ipv4Address::GetAny () && port != 0) | 629 else if (ipv4 == Ipv4Address::GetAny () && port != 0) |
581 { | 630 { |
582 m_endPoint = m_tcp->Allocate (GetBoundNetDevice (), port); | 631 m_endPoint = m_tcp->Allocate (port); |
583 } | 632 } |
584 else if (ipv4 != Ipv4Address::GetAny () && port == 0) | 633 else if (ipv4 != Ipv4Address::GetAny () && port == 0) |
585 { | 634 { |
586 m_endPoint = m_tcp->Allocate (ipv4); | 635 m_endPoint = m_tcp->Allocate (ipv4); |
587 } | 636 } |
588 else if (ipv4 != Ipv4Address::GetAny () && port != 0) | 637 else if (ipv4 != Ipv4Address::GetAny () && port != 0) |
589 { | 638 { |
590 m_endPoint = m_tcp->Allocate (GetBoundNetDevice (), ipv4, port); | 639 m_endPoint = m_tcp->Allocate (ipv4, port); |
591 } | 640 } |
592 if (0 == m_endPoint) | 641 if (0 == m_endPoint) |
593 { | 642 { |
594 m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL; | 643 m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL; |
595 return -1; | 644 return -1; |
596 } | 645 } |
597 } | 646 } |
598 else if (Inet6SocketAddress::IsMatchingType (address)) | 647 else if (Inet6SocketAddress::IsMatchingType (address)) |
599 { | 648 { |
600 Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address); | 649 Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address); |
601 Ipv6Address ipv6 = transport.GetIpv6 (); | 650 Ipv6Address ipv6 = transport.GetIpv6 (); |
602 uint16_t port = transport.GetPort (); | 651 uint16_t port = transport.GetPort (); |
603 if (ipv6 == Ipv6Address::GetAny () && port == 0) | 652 if (ipv6 == Ipv6Address::GetAny () && port == 0) |
604 { | 653 { |
605 m_endPoint6 = m_tcp->Allocate6 (); | 654 m_endPoint6 = m_tcp->Allocate6 (); |
606 } | 655 } |
607 else if (ipv6 == Ipv6Address::GetAny () && port != 0) | 656 else if (ipv6 == Ipv6Address::GetAny () && port != 0) |
608 { | 657 { |
609 m_endPoint6 = m_tcp->Allocate6 (GetBoundNetDevice (), port); | 658 m_endPoint6 = m_tcp->Allocate6 (port); |
610 } | 659 } |
611 else if (ipv6 != Ipv6Address::GetAny () && port == 0) | 660 else if (ipv6 != Ipv6Address::GetAny () && port == 0) |
612 { | 661 { |
613 m_endPoint6 = m_tcp->Allocate6 (ipv6); | 662 m_endPoint6 = m_tcp->Allocate6 (ipv6); |
614 } | 663 } |
615 else if (ipv6 != Ipv6Address::GetAny () && port != 0) | 664 else if (ipv6 != Ipv6Address::GetAny () && port != 0) |
616 { | 665 { |
617 m_endPoint6 = m_tcp->Allocate6 (GetBoundNetDevice (), ipv6, port); | 666 m_endPoint6 = m_tcp->Allocate6 (ipv6, port); |
618 } | 667 } |
619 if (0 == m_endPoint6) | 668 if (0 == m_endPoint6) |
620 { | 669 { |
621 m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL; | 670 m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL; |
622 return -1; | 671 return -1; |
623 } | 672 } |
624 } | 673 } |
625 else | 674 else |
626 { | 675 { |
627 m_errno = ERROR_INVAL; | 676 m_errno = ERROR_INVAL; |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 | 1033 |
985 return 0; | 1034 return 0; |
986 } | 1035 } |
987 | 1036 |
988 /* Inherit from Socket class: Bind this socket to the specified NetDevice */ | 1037 /* Inherit from Socket class: Bind this socket to the specified NetDevice */ |
989 void | 1038 void |
990 TcpSocketBase::BindToNetDevice (Ptr<NetDevice> netdevice) | 1039 TcpSocketBase::BindToNetDevice (Ptr<NetDevice> netdevice) |
991 { | 1040 { |
992 NS_LOG_FUNCTION (netdevice); | 1041 NS_LOG_FUNCTION (netdevice); |
993 Socket::BindToNetDevice (netdevice); // Includes sanity check | 1042 Socket::BindToNetDevice (netdevice); // Includes sanity check |
994 if (m_endPoint != 0) | 1043 if (m_endPoint == 0) |
995 { | 1044 { |
996 m_endPoint->BindToNetDevice (netdevice); | 1045 if (Bind () == -1) |
| 1046 { |
| 1047 NS_ASSERT (m_endPoint == 0); |
| 1048 return; |
| 1049 } |
| 1050 NS_ASSERT (m_endPoint != 0); |
997 } | 1051 } |
| 1052 m_endPoint->BindToNetDevice (netdevice); |
998 | 1053 |
999 if (m_endPoint6 != 0) | 1054 if (m_endPoint6 == 0) |
1000 { | 1055 { |
1001 m_endPoint6->BindToNetDevice (netdevice); | 1056 if (Bind6 () == -1) |
| 1057 { |
| 1058 NS_ASSERT (m_endPoint6 == 0); |
| 1059 return; |
| 1060 } |
| 1061 NS_ASSERT (m_endPoint6 != 0); |
1002 } | 1062 } |
| 1063 m_endPoint6->BindToNetDevice (netdevice); |
1003 | 1064 |
1004 return; | 1065 return; |
1005 } | 1066 } |
1006 | 1067 |
1007 /* Clean up after Bind. Set up callback functions in the end-point. */ | 1068 /* Clean up after Bind. Set up callback functions in the end-point. */ |
1008 int | 1069 int |
1009 TcpSocketBase::SetupCallback (void) | 1070 TcpSocketBase::SetupCallback (void) |
1010 { | 1071 { |
1011 NS_LOG_FUNCTION (this); | 1072 NS_LOG_FUNCTION (this); |
1012 | 1073 |
(...skipping 19 matching lines...) Expand all Loading... |
1032 | 1093 |
1033 /* Perform the real connection tasks: Send SYN if allowed, RST if invalid */ | 1094 /* Perform the real connection tasks: Send SYN if allowed, RST if invalid */ |
1034 int | 1095 int |
1035 TcpSocketBase::DoConnect (void) | 1096 TcpSocketBase::DoConnect (void) |
1036 { | 1097 { |
1037 NS_LOG_FUNCTION (this); | 1098 NS_LOG_FUNCTION (this); |
1038 | 1099 |
1039 // A new connection is allowed only if this socket does not have a connection | 1100 // A new connection is allowed only if this socket does not have a connection |
1040 if (m_state == CLOSED || m_state == LISTEN || m_state == SYN_SENT || m_state =
= LAST_ACK || m_state == CLOSE_WAIT) | 1101 if (m_state == CLOSED || m_state == LISTEN || m_state == SYN_SENT || m_state =
= LAST_ACK || m_state == CLOSE_WAIT) |
1041 { // send a SYN packet and change state into SYN_SENT | 1102 { // send a SYN packet and change state into SYN_SENT |
1042 SendEmptyPacket (TcpHeader::SYN); | 1103 // send a SYN packet with ECE and CWR flags set if sender is ECN capable |
| 1104 if (m_ecn) |
| 1105 { |
| 1106 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR); |
| 1107 } |
| 1108 else |
| 1109 { |
| 1110 SendEmptyPacket (TcpHeader::SYN); |
| 1111 } |
1043 NS_LOG_DEBUG (TcpStateName[m_state] << " -> SYN_SENT"); | 1112 NS_LOG_DEBUG (TcpStateName[m_state] << " -> SYN_SENT"); |
1044 m_state = SYN_SENT; | 1113 m_state = SYN_SENT; |
| 1114 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; // because sender is
not yet aware about receiver's ECN capability· |
1045 } | 1115 } |
1046 else if (m_state != TIME_WAIT) | 1116 else if (m_state != TIME_WAIT) |
1047 { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, a
n connection | 1117 { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, a
n connection |
1048 // exists. We send RST, tear down everything, and close this socket. | 1118 // exists. We send RST, tear down everything, and close this socket. |
1049 SendRST (); | 1119 SendRST (); |
1050 CloseAndNotify (); | 1120 CloseAndNotify (); |
1051 } | 1121 } |
1052 return 0; | 1122 return 0; |
1053 } | 1123 } |
1054 | 1124 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 { | 1211 { |
1142 NS_LOG_LOGIC ("Socket " << this << " forward up " << | 1212 NS_LOG_LOGIC ("Socket " << this << " forward up " << |
1143 m_endPoint->GetPeerAddress () << | 1213 m_endPoint->GetPeerAddress () << |
1144 ":" << m_endPoint->GetPeerPort () << | 1214 ":" << m_endPoint->GetPeerPort () << |
1145 " to " << m_endPoint->GetLocalAddress () << | 1215 " to " << m_endPoint->GetLocalAddress () << |
1146 ":" << m_endPoint->GetLocalPort ()); | 1216 ":" << m_endPoint->GetLocalPort ()); |
1147 | 1217 |
1148 Address fromAddress = InetSocketAddress (header.GetSource (), port); | 1218 Address fromAddress = InetSocketAddress (header.GetSource (), port); |
1149 Address toAddress = InetSocketAddress (header.GetDestination (), | 1219 Address toAddress = InetSocketAddress (header.GetDestination (), |
1150 m_endPoint->GetLocalPort ()); | 1220 m_endPoint->GetLocalPort ()); |
1151 | 1221 TcpHeader tcpHeader; |
| 1222 packet->PeekHeader (tcpHeader); |
| 1223 if (header.GetEcn() == Ipv4Header::ECN_CE && m_ecnCESeq < tcpHeader.GetAckNumb
er ()) |
| 1224 { |
| 1225 NS_LOG_INFO ("Received CE flag is valid"); |
| 1226 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
CE_RCVD"); |
| 1227 m_ecnCESeq = tcpHeader.GetAckNumber (); |
| 1228 m_tcb->m_ecnState = TcpSocketState::ECN_CE_RCVD;· |
| 1229 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_ECN_IS_CE)
; |
| 1230 } |
| 1231 else if (header.GetEcn() != Ipv4Header::ECN_NotECT && m_tcb->m_ecnState != Tcp
SocketState::ECN_DISABLED) |
| 1232 { |
| 1233 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_ECN_NO_CE)
; |
| 1234 } |
1152 DoForwardUp (packet, fromAddress, toAddress); | 1235 DoForwardUp (packet, fromAddress, toAddress); |
1153 } | 1236 } |
1154 | 1237 |
1155 void | 1238 void |
1156 TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, | 1239 TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, |
1157 Ptr<Ipv6Interface> incomingInterface) | 1240 Ptr<Ipv6Interface> incomingInterface) |
1158 { | 1241 { |
1159 NS_LOG_LOGIC ("Socket " << this << " forward up " << | 1242 NS_LOG_LOGIC ("Socket " << this << " forward up " << |
1160 m_endPoint6->GetPeerAddress () << | 1243 m_endPoint6->GetPeerAddress () << |
1161 ":" << m_endPoint6->GetPeerPort () << | 1244 ":" << m_endPoint6->GetPeerPort () << |
1162 " to " << m_endPoint6->GetLocalAddress () << | 1245 " to " << m_endPoint6->GetLocalAddress () << |
1163 ":" << m_endPoint6->GetLocalPort ()); | 1246 ":" << m_endPoint6->GetLocalPort ()); |
1164 | 1247 |
1165 Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port); | 1248 Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port); |
1166 Address toAddress = Inet6SocketAddress (header.GetDestinationAddress (), | 1249 Address toAddress = Inet6SocketAddress (header.GetDestinationAddress (), |
1167 m_endPoint6->GetLocalPort ()); | 1250 m_endPoint6->GetLocalPort ()); |
1168 | 1251 |
| 1252 TcpHeader tcpHeader; |
| 1253 packet->PeekHeader (tcpHeader); |
| 1254 if (header.GetEcn() == Ipv6Header::ECN_CE && m_ecnCESeq < tcpHeader.GetAckNumb
er ()) |
| 1255 { |
| 1256 NS_LOG_INFO ("Received CE flag is valid"); |
| 1257 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
CE_RCVD"); |
| 1258 m_ecnCESeq = tcpHeader.GetAckNumber (); |
| 1259 m_tcb->m_ecnState = TcpSocketState::ECN_CE_RCVD;·· |
| 1260 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_ECN_IS_CE)
; |
| 1261 } |
| 1262 else if (header.GetEcn() != Ipv6Header::ECN_NotECT) |
| 1263 { |
| 1264 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_ECN_NO_CE)
; |
| 1265 } |
1169 DoForwardUp (packet, fromAddress, toAddress); | 1266 DoForwardUp (packet, fromAddress, toAddress); |
1170 } | 1267 } |
1171 | 1268 |
1172 void | 1269 void |
1173 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, | 1270 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, |
1174 uint8_t icmpType, uint8_t icmpCode, | 1271 uint8_t icmpType, uint8_t icmpCode, |
1175 uint32_t icmpInfo) | 1272 uint32_t icmpInfo) |
1176 { | 1273 { |
1177 NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType
<< | 1274 NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType
<< |
1178 (uint32_t)icmpCode << icmpInfo); | 1275 (uint32_t)icmpCode << icmpInfo); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 { | 1313 { |
1217 // Discard fully out of range data packets | 1314 // Discard fully out of range data packets |
1218 NS_LOG_WARN ("At state " << TcpStateName[m_state] << | 1315 NS_LOG_WARN ("At state " << TcpStateName[m_state] << |
1219 " received packet of seq [" << seq << | 1316 " received packet of seq [" << seq << |
1220 ":" << seq + packet->GetSize () << | 1317 ":" << seq + packet->GetSize () << |
1221 ") out of range [" << m_rxBuffer->NextRxSequence () << ":" << | 1318 ") out of range [" << m_rxBuffer->NextRxSequence () << ":" << |
1222 m_rxBuffer->MaxRxSequence () << ")"); | 1319 m_rxBuffer->MaxRxSequence () << ")"); |
1223 // Acknowledgement should be sent for all unacceptable packets (RFC793, p.
69) | 1320 // Acknowledgement should be sent for all unacceptable packets (RFC793, p.
69) |
1224 if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST)) | 1321 if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST)) |
1225 { | 1322 { |
1226 SendEmptyPacket (TcpHeader::ACK); | 1323 // Check if the sender has responded to ECN echo by reducing the Conge
stion Window |
| 1324 if (tcpHeader.GetFlags () & TcpHeader::CWR ) |
| 1325 { |
| 1326 // Check if a packet with CE bit set is received. If there is no C
E bit set, then change the state to ECN_IDLE to· |
| 1327 // stop sending ECN Echo messages. If there is CE bit set, the pac
ket should continue sending ECN Echo messages |
| 1328 // |
| 1329 if (m_tcb->m_ecnState != TcpSocketState::ECN_CE_RCVD)· |
| 1330 { |
| 1331 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
| 1332 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState]
<< " -> ECN_IDLE"); |
| 1333 } |
| 1334 } |
| 1335 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnSt
ate == TcpSocketState::ECN_ECE_SENT ) |
| 1336 { |
| 1337 // Receiver sets ECE flags when it receives a packet with CE bit o
n or sender hasn’t responded to ECN echo sent by receiver |
| 1338 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
| 1339 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT;·· |
| 1340 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_SENT"); |
| 1341 } |
| 1342 else |
| 1343 { |
| 1344 SendEmptyPacket (TcpHeader::ACK); |
| 1345 } |
1227 } | 1346 } |
1228 return; | 1347 return; |
1229 } | 1348 } |
1230 | 1349 |
1231 m_rxTrace (packet, tcpHeader, this); | 1350 m_rxTrace (packet, tcpHeader, this); |
1232 | 1351 |
1233 if (tcpHeader.GetFlags () & TcpHeader::SYN) | 1352 if (tcpHeader.GetFlags () & TcpHeader::SYN) |
1234 { | 1353 { |
1235 /* The window field in a segment where the SYN bit is set (i.e., a <SYN> | 1354 /* The window field in a segment where the SYN bit is set (i.e., a <SYN> |
1236 * or <SYN,ACK>) MUST NOT be scaled (from RFC 7323 page 9). But should be | 1355 * or <SYN,ACK>) MUST NOT be scaled (from RFC 7323 page 9). But should be |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 } | 1516 } |
1398 } | 1517 } |
1399 | 1518 |
1400 /* Received a packet upon ESTABLISHED state. This function is mimicking the | 1519 /* Received a packet upon ESTABLISHED state. This function is mimicking the |
1401 role of tcp_rcv_established() in tcp_input.c in Linux kernel. */ | 1520 role of tcp_rcv_established() in tcp_input.c in Linux kernel. */ |
1402 void | 1521 void |
1403 TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeade
r) | 1522 TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeade
r) |
1404 { | 1523 { |
1405 NS_LOG_FUNCTION (this << tcpHeader); | 1524 NS_LOG_FUNCTION (this << tcpHeader); |
1406 | 1525 |
1407 // Extract the flags. PSH and URG are not honoured. | 1526 // Extract the flags. PSH, URG, CWR and ECE are not honoured. |
1408 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 1527 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG |
TcpHeader::CWR | TcpHeader::ECE); |
1409 | 1528 |
1410 // Different flags are different events | 1529 // Different flags are different events |
1411 if (tcpflags == TcpHeader::ACK) | 1530 if (tcpflags == TcpHeader::ACK) |
1412 { | 1531 { |
1413 if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ()) | 1532 if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ()) |
1414 { | 1533 { |
1415 // Case 1: If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be i
gnored. | 1534 // Case 1: If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be i
gnored. |
1416 // Pag. 72 RFC 793 | 1535 // Pag. 72 RFC 793 |
1417 NS_LOG_WARN ("Ignored ack of " << tcpHeader.GetAckNumber () << | 1536 NS_LOG_WARN ("Ignored ack of " << tcpHeader.GetAckNumber () << |
1418 " SND.UNA = " << m_txBuffer->HeadSequence ()); | 1537 " SND.UNA = " << m_txBuffer->HeadSequence ()); |
1419 | 1538 |
1420 // TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] | 1539 // TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] |
1421 } | 1540 } |
1422 else if (tcpHeader.GetAckNumber () > m_tcb->m_highTxMark) | 1541 else if (tcpHeader.GetAckNumber () > m_tcb->m_highTxMark) |
1423 { | 1542 { |
1424 // If the ACK acks something not yet sent (SEG.ACK > HighTxMark) then | 1543 // If the ACK acks something not yet sent (SEG.ACK > HighTxMark) then |
1425 // send an ACK, drop the segment, and return. | 1544 // send an ACK, drop the segment, and return. |
1426 // Pag. 72 RFC 793 | 1545 // Pag. 72 RFC 793 |
1427 NS_LOG_WARN ("Ignored ack of " << tcpHeader.GetAckNumber () << | 1546 NS_LOG_WARN ("Ignored ack of " << tcpHeader.GetAckNumber () << |
1428 " HighTxMark = " << m_tcb->m_highTxMark); | 1547 " HighTxMark = " << m_tcb->m_highTxMark); |
1429 | 1548 |
| 1549 // Receiver sets ECE flags when it receives a packet with CE bit on or
sender hasn’t responded to ECN echo sent by receiver |
| 1550 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnSt
ate == TcpSocketState::ECN_ECE_SENT) |
| 1551 { |
| 1552 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
| 1553 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
| 1554 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_SENT"); |
| 1555 } |
| 1556 else |
| 1557 { |
1430 SendEmptyPacket (TcpHeader::ACK); | 1558 SendEmptyPacket (TcpHeader::ACK); |
| 1559 } |
1431 } | 1560 } |
1432 else | 1561 else |
1433 { | 1562 { |
1434 // SND.UNA < SEG.ACK =< HighTxMark | 1563 // SND.UNA < SEG.ACK =< HighTxMark |
1435 // Pag. 72 RFC 793 | 1564 // Pag. 72 RFC 793 |
1436 ReceivedAck (packet, tcpHeader); | 1565 ReceivedAck (packet, tcpHeader); |
1437 } | 1566 } |
1438 } | 1567 } |
1439 else if (tcpflags == TcpHeader::SYN) | 1568 else if (tcpflags == TcpHeader::SYN) |
1440 { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and | 1569 { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1637 NS_ASSERT (m_tcb->m_segmentSize > 0); | 1766 NS_ASSERT (m_tcb->m_segmentSize > 0); |
1638 | 1767 |
1639 // RFC 6675, Section 5, 1st paragraph: | 1768 // RFC 6675, Section 5, 1st paragraph: |
1640 // Upon the receipt of any ACK containing SACK information, the | 1769 // Upon the receipt of any ACK containing SACK information, the |
1641 // scoreboard MUST be updated via the Update () routine (done in ReadOptions) | 1770 // scoreboard MUST be updated via the Update () routine (done in ReadOptions) |
1642 bool scoreboardUpdated = false; | 1771 bool scoreboardUpdated = false; |
1643 ReadOptions (tcpHeader, scoreboardUpdated); | 1772 ReadOptions (tcpHeader, scoreboardUpdated); |
1644 | 1773 |
1645 SequenceNumber32 ackNumber = tcpHeader.GetAckNumber (); | 1774 SequenceNumber32 ackNumber = tcpHeader.GetAckNumber (); |
1646 | 1775 |
| 1776 if (ackNumber > m_txBuffer->HeadSequence () && (m_tcb->m_ecnState != TcpSocket
State::ECN_DISABLED) && (tcpHeader.GetFlags () & TcpHeader::ECE)) |
| 1777 { |
| 1778 if (m_ecnEchoSeq < tcpHeader.GetAckNumber ()) |
| 1779 { |
| 1780 NS_LOG_INFO ("Received ECN Echo is valid"); |
| 1781 m_ecnEchoSeq = tcpHeader.GetAckNumber (); |
| 1782 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_RCVD; |
| 1783 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_RCVD"); |
| 1784 } |
| 1785 } |
| 1786 |
1647 // RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation | 1787 // RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation |
1648 // are inside the function ProcessAck | 1788 // are inside the function ProcessAck |
1649 ProcessAck (ackNumber, scoreboardUpdated); | 1789 ProcessAck (ackNumber, scoreboardUpdated); |
1650 | 1790 |
1651 // RFC 6675, Section 5, point (C), try to send more data. NB: (C) is implement
ed | 1791 // RFC 6675, Section 5, point (C), try to send more data. NB: (C) is implement
ed |
1652 // inside SendPendingData | 1792 // inside SendPendingData |
1653 SendPendingData (m_connected); | 1793 SendPendingData (m_connected); |
1654 | 1794 |
1655 // If there is any data piggybacked, store it into m_rxBuffer | 1795 // If there is any data piggybacked, store it into m_rxBuffer |
1656 if (packet->GetSize () > 0) | 1796 if (packet->GetSize () > 0) |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1826 // phase. | 1966 // phase. |
1827 else if (m_tcb->m_congState == TcpSocketState::CA_RECOVERY) | 1967 else if (m_tcb->m_congState == TcpSocketState::CA_RECOVERY) |
1828 { | 1968 { |
1829 m_isFirstPartialAck = true; | 1969 m_isFirstPartialAck = true; |
1830 | 1970 |
1831 // Recalculate the segs acked, that are from m_recover to ackNumbe
r | 1971 // Recalculate the segs acked, that are from m_recover to ackNumbe
r |
1832 // (which are the ones we have not passed to PktsAcked and that | 1972 // (which are the ones we have not passed to PktsAcked and that |
1833 // can increase cWnd) | 1973 // can increase cWnd) |
1834 segsAcked = (ackNumber - m_recover) / m_tcb->m_segmentSize; | 1974 segsAcked = (ackNumber - m_recover) / m_tcb->m_segmentSize; |
1835 m_congestionControl->PktsAcked (m_tcb, segsAcked, m_lastRtt); | 1975 m_congestionControl->PktsAcked (m_tcb, segsAcked, m_lastRtt); |
1836 | 1976 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_CO
MPLETE_CWR); |
1837 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA
_OPEN); | 1977 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA
_OPEN); |
1838 m_tcb->m_congState = TcpSocketState::CA_OPEN; | 1978 m_tcb->m_congState = TcpSocketState::CA_OPEN; |
1839 | 1979 |
1840 NS_LOG_DEBUG (segsAcked << " segments acked in CA_RECOVER, ack of
" << | 1980 NS_LOG_DEBUG (segsAcked << " segments acked in CA_RECOVER, ack of
" << |
1841 ackNumber << ", exiting CA_RECOVERY -> CA_OPEN"); | 1981 ackNumber << ", exiting CA_RECOVERY -> CA_OPEN"); |
1842 } | 1982 } |
1843 else if (m_tcb->m_congState == TcpSocketState::CA_LOSS) | 1983 else if (m_tcb->m_congState == TcpSocketState::CA_LOSS) |
1844 { | 1984 { |
1845 m_isFirstPartialAck = true; | 1985 m_isFirstPartialAck = true; |
1846 | 1986 |
(...skipping 22 matching lines...) Expand all Loading... |
1869 } | 2009 } |
1870 } | 2010 } |
1871 | 2011 |
1872 /* Received a packet upon LISTEN state. */ | 2012 /* Received a packet upon LISTEN state. */ |
1873 void | 2013 void |
1874 TcpSocketBase::ProcessListen (Ptr<Packet> packet, const TcpHeader& tcpHeader, | 2014 TcpSocketBase::ProcessListen (Ptr<Packet> packet, const TcpHeader& tcpHeader, |
1875 const Address& fromAddress, const Address& toAddre
ss) | 2015 const Address& fromAddress, const Address& toAddre
ss) |
1876 { | 2016 { |
1877 NS_LOG_FUNCTION (this << tcpHeader); | 2017 NS_LOG_FUNCTION (this << tcpHeader); |
1878 | 2018 |
1879 // Extract the flags. PSH and URG are not honoured. | 2019 // Extract the flags. PSH, URG, CWR and ECE are not honoured. |
1880 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 2020 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG |
TcpHeader::CWR | TcpHeader::ECE); |
1881 | 2021 |
1882 // Fork a socket if received a SYN. Do nothing otherwise. | 2022 // Fork a socket if received a SYN. Do nothing otherwise. |
1883 // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel | 2023 // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel |
1884 if (tcpflags != TcpHeader::SYN) | 2024 if (tcpflags != TcpHeader::SYN) |
1885 { | 2025 { |
1886 return; | 2026 return; |
1887 } | 2027 } |
1888 | 2028 |
1889 // Call socket's notify function to let the server app know we got a SYN | 2029 // Call socket's notify function to let the server app know we got a SYN |
1890 // If the server app refuses the connection, do nothing | 2030 // If the server app refuses the connection, do nothing |
1891 if (!NotifyConnectionRequest (fromAddress)) | 2031 if (!NotifyConnectionRequest (fromAddress)) |
1892 { | 2032 { |
1893 return; | 2033 return; |
1894 } | 2034 } |
1895 // Clone the socket, simulate fork | 2035 // Clone the socket, simulate fork |
1896 Ptr<TcpSocketBase> newSock = Fork (); | 2036 Ptr<TcpSocketBase> newSock = Fork (); |
1897 NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock); | 2037 NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock); |
1898 Simulator::ScheduleNow (&TcpSocketBase::CompleteFork, newSock, | 2038 Simulator::ScheduleNow (&TcpSocketBase::CompleteFork, newSock, |
1899 packet, tcpHeader, fromAddress, toAddress); | 2039 packet, tcpHeader, fromAddress, toAddress); |
1900 } | 2040 } |
1901 | 2041 |
1902 /* Received a packet upon SYN_SENT */ | 2042 /* Received a packet upon SYN_SENT */ |
1903 void | 2043 void |
1904 TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 2044 TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
1905 { | 2045 { |
1906 NS_LOG_FUNCTION (this << tcpHeader); | 2046 NS_LOG_FUNCTION (this << tcpHeader); |
1907 | 2047 |
1908 // Extract the flags. PSH and URG are not honoured. | 2048 // Extract the flags. PSH, URG, CWR and ECE are not honoured. |
1909 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 2049 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG |
TcpHeader::CWR | TcpHeader::ECE); |
1910 | 2050 |
1911 if (tcpflags == 0) | 2051 if (tcpflags == 0) |
1912 { // Bare data, accept it and move to ESTABLISHED state. This is not a norma
l behaviour. Remove this? | 2052 { // Bare data, accept it and move to ESTABLISHED state. This is not a norma
l behaviour. Remove this? |
1913 NS_LOG_DEBUG ("SYN_SENT -> ESTABLISHED"); | 2053 NS_LOG_DEBUG ("SYN_SENT -> ESTABLISHED"); |
1914 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); | 2054 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); |
1915 m_state = ESTABLISHED; | 2055 m_state = ESTABLISHED; |
1916 m_connected = true; | 2056 m_connected = true; |
1917 m_retxEvent.Cancel (); | 2057 m_retxEvent.Cancel (); |
1918 m_delAckCount = m_delAckMaxCount; | 2058 m_delAckCount = m_delAckMaxCount; |
1919 ReceivedData (packet, tcpHeader); | 2059 ReceivedData (packet, tcpHeader); |
1920 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); | 2060 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); |
1921 } | 2061 } |
1922 else if (tcpflags == TcpHeader::ACK) | 2062 else if (tcpflags == TcpHeader::ACK) |
1923 { // Ignore ACK in SYN_SENT | 2063 { // Ignore ACK in SYN_SENT |
1924 } | 2064 } |
1925 else if (tcpflags == TcpHeader::SYN) | 2065 else if (tcpflags == TcpHeader::SYN) |
1926 { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK | 2066 { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK |
1927 NS_LOG_DEBUG ("SYN_SENT -> SYN_RCVD"); | 2067 NS_LOG_DEBUG ("SYN_SENT -> SYN_RCVD"); |
1928 m_state = SYN_RCVD; | 2068 m_state = SYN_RCVD; |
1929 m_synCount = m_synRetries; | 2069 m_synCount = m_synRetries; |
1930 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); | 2070 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); |
1931 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 2071 |
| 2072 /* Check if we recieved an ECN SYN packet. Change the ECN state of receive
r to ECN_IDLE if the traffic is ECN capable and· |
| 2073 * sender has sent ECN SYN packet |
| 2074 */ |
| 2075 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::CWR | TcpHeader::ECE)) |
| 2076 { |
| 2077 NS_LOG_INFO ("Received ECN SYN packet"); |
| 2078 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK | TcpHeader::ECE); |
| 2079 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
| 2080 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_IDLE"); |
| 2081 } |
| 2082 else |
| 2083 { |
| 2084 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
| 2085 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);···· |
| 2086 } |
1932 } | 2087 } |
1933 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK) | 2088 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK) |
1934 && m_tcb->m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAck
Number ()) | 2089 && m_tcb->m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAck
Number ()) |
1935 { // Handshake completed | 2090 { // Handshake completed |
1936 NS_LOG_DEBUG ("SYN_SENT -> ESTABLISHED"); | 2091 NS_LOG_DEBUG ("SYN_SENT -> ESTABLISHED"); |
1937 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); | 2092 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); |
1938 m_state = ESTABLISHED; | 2093 m_state = ESTABLISHED; |
1939 m_connected = true; | 2094 m_connected = true; |
1940 m_retxEvent.Cancel (); | 2095 m_retxEvent.Cancel (); |
1941 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); | 2096 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); |
1942 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; | 2097 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; |
1943 m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence); | 2098 m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence); |
1944 SendEmptyPacket (TcpHeader::ACK); | 2099 SendEmptyPacket (TcpHeader::ACK); |
| 2100 |
| 2101 /* Check if we received an ECN SYN-ACK packet. Change the ECN state of sen
der to ECN_IDLE if receiver has sent an ECN SYN-ACK· |
| 2102 * packet and the traffic is ECN Capable |
| 2103 */ |
| 2104 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::ECE)) |
| 2105 { |
| 2106 NS_LOG_INFO ("Received ECN SYN-ACK packet."); |
| 2107 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
| 2108 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_IDLE"); |
| 2109 } |
| 2110 else |
| 2111 { |
| 2112 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
| 2113 } |
| 2114 |
1945 SendPendingData (m_connected); | 2115 SendPendingData (m_connected); |
1946 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); | 2116 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); |
1947 // Always respond to first data packet to speed up the connection. | 2117 // Always respond to first data packet to speed up the connection. |
1948 // Remove to get the behaviour of old NS-3 code. | 2118 // Remove to get the behaviour of old NS-3 code. |
1949 m_delAckCount = m_delAckMaxCount; | 2119 m_delAckCount = m_delAckMaxCount; |
1950 } | 2120 } |
1951 else | 2121 else |
1952 { // Other in-sequence input | 2122 { // Other in-sequence input |
1953 if (tcpflags != TcpHeader::RST) | 2123 if (tcpflags != TcpHeader::RST) |
1954 { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags | 2124 { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags |
1955 NS_LOG_LOGIC ("Illegal flag " << TcpHeader::FlagsToString (tcpflags) <
< | 2125 NS_LOG_LOGIC ("Illegal flag " << TcpHeader::FlagsToString (tcpflags) <
< |
1956 " received. Reset packet is sent."); | 2126 " received. Reset packet is sent."); |
1957 SendRST (); | 2127 SendRST (); |
1958 } | 2128 } |
1959 CloseAndNotify (); | 2129 CloseAndNotify (); |
1960 } | 2130 } |
1961 } | 2131 } |
1962 | 2132 |
1963 /* Received a packet upon SYN_RCVD */ | 2133 /* Received a packet upon SYN_RCVD */ |
1964 void | 2134 void |
1965 TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader, | 2135 TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader, |
1966 const Address& fromAddress, const Address& toAddr
ess) | 2136 const Address& fromAddress, const Address& toAddr
ess) |
1967 { | 2137 { |
1968 NS_LOG_FUNCTION (this << tcpHeader); | 2138 NS_LOG_FUNCTION (this << tcpHeader); |
1969 | 2139 |
1970 // Extract the flags. PSH and URG are not honoured. | 2140 // Extract the flags. PSH, URG, CWR and ECE are not honoured. |
1971 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 2141 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG |
TcpHeader::CWR | TcpHeader::ECE); |
1972 | 2142 |
1973 if (tcpflags == 0 | 2143 if (tcpflags == 0 |
1974 || (tcpflags == TcpHeader::ACK | 2144 || (tcpflags == TcpHeader::ACK |
1975 && m_tcb->m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckN
umber ())) | 2145 && m_tcb->m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckN
umber ())) |
1976 { // If it is bare data, accept it and move to ESTABLISHED state. This is | 2146 { // If it is bare data, accept it and move to ESTABLISHED state. This is |
1977 // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the | 2147 // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the |
1978 // handshake is completed nicely. | 2148 // handshake is completed nicely. |
1979 NS_LOG_DEBUG ("SYN_RCVD -> ESTABLISHED"); | 2149 NS_LOG_DEBUG ("SYN_RCVD -> ESTABLISHED"); |
1980 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); | 2150 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); |
1981 m_state = ESTABLISHED; | 2151 m_state = ESTABLISHED; |
(...skipping 18 matching lines...) Expand all Loading... |
2000 NotifyNewConnectionCreated (this, fromAddress); | 2170 NotifyNewConnectionCreated (this, fromAddress); |
2001 // As this connection is established, the socket is available to send data
now | 2171 // As this connection is established, the socket is available to send data
now |
2002 if (GetTxAvailable () > 0) | 2172 if (GetTxAvailable () > 0) |
2003 { | 2173 { |
2004 NotifySend (GetTxAvailable ()); | 2174 NotifySend (GetTxAvailable ()); |
2005 } | 2175 } |
2006 } | 2176 } |
2007 else if (tcpflags == TcpHeader::SYN) | 2177 else if (tcpflags == TcpHeader::SYN) |
2008 { // Probably the peer lost my SYN+ACK | 2178 { // Probably the peer lost my SYN+ACK |
2009 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); | 2179 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); |
2010 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 2180 |
| 2181 /* Check if we received an ECN SYN packet. Change the ECN state of receive
r to ECN_IDLE if sender has sent an ECN SYN· |
| 2182 * packet and the traffic is ECN Capable |
| 2183 */ |
| 2184 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::CWR | TcpHeader::ECE)) |
| 2185 { |
| 2186 NS_LOG_INFO ("Received ECN SYN packet"); |
| 2187 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK |TcpHeader::ECE); |
| 2188 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
| 2189 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_IDLE"); |
| 2190 } |
| 2191 else |
| 2192 { |
| 2193 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
| 2194 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); |
| 2195 } |
2011 } | 2196 } |
2012 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK)) | 2197 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK)) |
2013 { | 2198 { |
2014 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) | 2199 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) |
2015 { // In-sequence FIN before connection complete. Set up connection and c
lose. | 2200 { // In-sequence FIN before connection complete. Set up connection and c
lose. |
2016 m_connected = true; | 2201 m_connected = true; |
2017 m_retxEvent.Cancel (); | 2202 m_retxEvent.Cancel (); |
2018 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; | 2203 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; |
2019 m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence); | 2204 m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence); |
2020 if (m_endPoint) | 2205 if (m_endPoint) |
(...skipping 30 matching lines...) Expand all Loading... |
2051 CloseAndNotify (); | 2236 CloseAndNotify (); |
2052 } | 2237 } |
2053 } | 2238 } |
2054 | 2239 |
2055 /* Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */ | 2240 /* Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */ |
2056 void | 2241 void |
2057 TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 2242 TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
2058 { | 2243 { |
2059 NS_LOG_FUNCTION (this << tcpHeader); | 2244 NS_LOG_FUNCTION (this << tcpHeader); |
2060 | 2245 |
2061 // Extract the flags. PSH and URG are not honoured. | 2246 // Extract the flags. PSH, URG, CWR and ECE are not honoured. |
2062 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 2247 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG |
TcpHeader::CWR | TcpHeader::ECE); |
2063 | 2248 |
2064 if (packet->GetSize () > 0 && !(tcpflags & TcpHeader::ACK)) | 2249 if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK) |
2065 { // Bare data, accept it | 2250 { // Bare data, accept it |
2066 ReceivedData (packet, tcpHeader); | 2251 ReceivedData (packet, tcpHeader); |
2067 } | 2252 } |
2068 else if (tcpflags == TcpHeader::ACK) | 2253 else if (tcpflags == TcpHeader::ACK) |
2069 { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2 | 2254 { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2 |
2070 ReceivedAck (packet, tcpHeader); | 2255 ReceivedAck (packet, tcpHeader); |
2071 if (m_state == FIN_WAIT_1 && m_txBuffer->Size () == 0 | 2256 if (m_state == FIN_WAIT_1 && m_txBuffer->Size () == 0 |
2072 && tcpHeader.GetAckNumber () == m_tcb->m_highTxMark + SequenceNumber32
(1)) | 2257 && tcpHeader.GetAckNumber () == m_tcb->m_highTxMark + SequenceNumber32
(1)) |
2073 { // This ACK corresponds to the FIN sent | 2258 { // This ACK corresponds to the FIN sent |
2074 NS_LOG_DEBUG ("FIN_WAIT_1 -> FIN_WAIT_2"); | 2259 NS_LOG_DEBUG ("FIN_WAIT_1 -> FIN_WAIT_2"); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2123 } | 2308 } |
2124 } | 2309 } |
2125 } | 2310 } |
2126 | 2311 |
2127 /* Received a packet upon CLOSING */ | 2312 /* Received a packet upon CLOSING */ |
2128 void | 2313 void |
2129 TcpSocketBase::ProcessClosing (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 2314 TcpSocketBase::ProcessClosing (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
2130 { | 2315 { |
2131 NS_LOG_FUNCTION (this << tcpHeader); | 2316 NS_LOG_FUNCTION (this << tcpHeader); |
2132 | 2317 |
2133 // Extract the flags. PSH and URG are not honoured. | 2318 // Extract the flags. PSH, URG, CWR and ECE are not honoured. |
2134 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 2319 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG |
TcpHeader::CWR | TcpHeader::ECE); |
2135 | 2320 |
2136 if (tcpflags == TcpHeader::ACK) | 2321 if (tcpflags == TcpHeader::ACK) |
2137 { | 2322 { |
2138 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) | 2323 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) |
2139 { // This ACK corresponds to the FIN sent | 2324 { // This ACK corresponds to the FIN sent |
2140 TimeWait (); | 2325 TimeWait (); |
2141 } | 2326 } |
2142 } | 2327 } |
2143 else | 2328 else |
2144 { // CLOSING state means simultaneous close, i.e. no one is sending data to | 2329 { // CLOSING state means simultaneous close, i.e. no one is sending data to |
(...skipping 10 matching lines...) Expand all Loading... |
2155 CloseAndNotify (); | 2340 CloseAndNotify (); |
2156 } | 2341 } |
2157 } | 2342 } |
2158 | 2343 |
2159 /* Received a packet upon LAST_ACK */ | 2344 /* Received a packet upon LAST_ACK */ |
2160 void | 2345 void |
2161 TcpSocketBase::ProcessLastAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 2346 TcpSocketBase::ProcessLastAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
2162 { | 2347 { |
2163 NS_LOG_FUNCTION (this << tcpHeader); | 2348 NS_LOG_FUNCTION (this << tcpHeader); |
2164 | 2349 |
2165 // Extract the flags. PSH and URG are not honoured. | 2350 // Extract the flags. PSH, URG, CWR and ECE are not honoured. |
2166 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 2351 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG |
TcpHeader::CWR | TcpHeader::ECE); |
2167 | 2352 |
2168 if (tcpflags == 0) | 2353 if (tcpflags == 0) |
2169 { | 2354 { |
2170 ReceivedData (packet, tcpHeader); | 2355 ReceivedData (packet, tcpHeader); |
2171 } | 2356 } |
2172 else if (tcpflags == TcpHeader::ACK) | 2357 else if (tcpflags == TcpHeader::ACK) |
2173 { | 2358 { |
2174 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) | 2359 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) |
2175 { // This ACK corresponds to the FIN sent. This socket closed peacefully
. | 2360 { // This ACK corresponds to the FIN sent. This socket closed peacefully
. |
2176 CloseAndNotify (); | 2361 CloseAndNotify (); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2307 Ptr<Packet> p = Create<Packet> (); | 2492 Ptr<Packet> p = Create<Packet> (); |
2308 TcpHeader header; | 2493 TcpHeader header; |
2309 SequenceNumber32 s = m_tcb->m_nextTxSequence; | 2494 SequenceNumber32 s = m_tcb->m_nextTxSequence; |
2310 | 2495 |
2311 /* | 2496 /* |
2312 * Add tags for each socket option. | 2497 * Add tags for each socket option. |
2313 * Note that currently the socket adds both IPv4 tag and IPv6 tag | 2498 * Note that currently the socket adds both IPv4 tag and IPv6 tag |
2314 * if both options are set. Once the packet got to layer three, only | 2499 * if both options are set. Once the packet got to layer three, only |
2315 * the corresponding tags will be read. | 2500 * the corresponding tags will be read. |
2316 */ | 2501 */ |
2317 if (GetIpTos ()) | 2502 if (GetIpTos ()) |
2318 { | 2503 { |
2319 SocketIpTosTag ipTosTag; | 2504 SocketIpTosTag ipTosTag; |
2320 ipTosTag.SetTos (GetIpTos ()); | 2505 NS_LOG_LOGIC (" ECT bits should be set on pure ACK and SYN packets in DCTC
P"); |
| 2506 if (m_congestionControl->GetName () == "TcpDctcp" && (GetIpTos () & 0x3) =
= 0) |
| 2507 {· |
| 2508 ipTosTag.SetTos (GetIpTos () | 0x1); |
| 2509 } |
| 2510 else |
| 2511 {· |
| 2512 ipTosTag.SetTos (GetIpTos ()); |
| 2513 } |
2321 p->AddPacketTag (ipTosTag); | 2514 p->AddPacketTag (ipTosTag); |
2322 } | 2515 } |
| 2516 else |
| 2517 { |
| 2518 if (m_congestionControl->GetName () == "TcpDctcp") |
| 2519 { |
| 2520 SocketIpTosTag ipTosTag; |
| 2521 ipTosTag.SetTos (0x1); |
| 2522 p->AddPacketTag (ipTosTag); |
| 2523 } |
| 2524 } |
2323 | 2525 |
2324 if (IsManualIpv6Tclass ()) | 2526 if (IsManualIpv6Tclass ()) |
2325 { | 2527 { |
2326 SocketIpv6TclassTag ipTclassTag; | 2528 SocketIpv6TclassTag ipTclassTag; |
2327 ipTclassTag.SetTclass (GetIpv6Tclass ()); | 2529 if (m_congestionControl->GetName () == "TcpDctcp" && (GetIpv6Tclass () & 0
x3) == 0) |
| 2530 { |
| 2531 ipTclassTag.SetTclass (GetIpv6Tclass () | 0x1); |
| 2532 } |
| 2533 else |
| 2534 { |
| 2535 ipTclassTag.SetTclass (GetIpv6Tclass ()); |
| 2536 } |
2328 p->AddPacketTag (ipTclassTag); | 2537 p->AddPacketTag (ipTclassTag); |
2329 } | 2538 } |
| 2539 else |
| 2540 { |
| 2541 if (m_congestionControl->GetName () == "TcpDctcp") |
| 2542 { |
| 2543 SocketIpv6TclassTag ipTclassTag; |
| 2544 ipTclassTag.SetTclass (0x1); |
| 2545 p->AddPacketTag (ipTclassTag); |
| 2546 } |
| 2547 } |
2330 | 2548 |
2331 if (IsManualIpTtl ()) | 2549 if (IsManualIpTtl ()) |
2332 { | 2550 { |
2333 SocketIpTtlTag ipTtlTag; | 2551 SocketIpTtlTag ipTtlTag; |
2334 ipTtlTag.SetTtl (GetIpTtl ()); | 2552 ipTtlTag.SetTtl (GetIpTtl ()); |
2335 p->AddPacketTag (ipTtlTag); | 2553 p->AddPacketTag (ipTtlTag); |
2336 } | 2554 } |
2337 | 2555 |
2338 if (IsManualIpv6HopLimit ()) | 2556 if (IsManualIpv6HopLimit ()) |
2339 { | 2557 { |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2558 /* This function is called only if a SYN received in LISTEN state. After | 2776 /* This function is called only if a SYN received in LISTEN state. After |
2559 TcpSocketBase cloned, allocate a new end point to handle the incoming | 2777 TcpSocketBase cloned, allocate a new end point to handle the incoming |
2560 connection and send a SYN+ACK to complete the handshake. */ | 2778 connection and send a SYN+ACK to complete the handshake. */ |
2561 void | 2779 void |
2562 TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h, | 2780 TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h, |
2563 const Address& fromAddress, const Address& toAddres
s) | 2781 const Address& fromAddress, const Address& toAddres
s) |
2564 { | 2782 { |
2565 // Get port and address from peer (connecting host) | 2783 // Get port and address from peer (connecting host) |
2566 if (InetSocketAddress::IsMatchingType (toAddress)) | 2784 if (InetSocketAddress::IsMatchingType (toAddress)) |
2567 { | 2785 { |
2568 m_endPoint = m_tcp->Allocate (GetBoundNetDevice (), | 2786 m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).G
etIpv4 (), |
2569 InetSocketAddress::ConvertFrom (toAddress).G
etIpv4 (), | |
2570 InetSocketAddress::ConvertFrom (toAddress).G
etPort (), | 2787 InetSocketAddress::ConvertFrom (toAddress).G
etPort (), |
2571 InetSocketAddress::ConvertFrom (fromAddress)
.GetIpv4 (), | 2788 InetSocketAddress::ConvertFrom (fromAddress)
.GetIpv4 (), |
2572 InetSocketAddress::ConvertFrom (fromAddress)
.GetPort ()); | 2789 InetSocketAddress::ConvertFrom (fromAddress)
.GetPort ()); |
2573 m_endPoint6 = 0; | 2790 m_endPoint6 = 0; |
2574 } | 2791 } |
2575 else if (Inet6SocketAddress::IsMatchingType (toAddress)) | 2792 else if (Inet6SocketAddress::IsMatchingType (toAddress)) |
2576 { | 2793 { |
2577 m_endPoint6 = m_tcp->Allocate6 (GetBoundNetDevice (), | 2794 m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress
).GetIpv6 (), |
2578 Inet6SocketAddress::ConvertFrom (toAddress
).GetIpv6 (), | |
2579 Inet6SocketAddress::ConvertFrom (toAddress
).GetPort (), | 2795 Inet6SocketAddress::ConvertFrom (toAddress
).GetPort (), |
2580 Inet6SocketAddress::ConvertFrom (fromAddre
ss).GetIpv6 (), | 2796 Inet6SocketAddress::ConvertFrom (fromAddre
ss).GetIpv6 (), |
2581 Inet6SocketAddress::ConvertFrom (fromAddre
ss).GetPort ()); | 2797 Inet6SocketAddress::ConvertFrom (fromAddre
ss).GetPort ()); |
2582 m_endPoint = 0; | 2798 m_endPoint = 0; |
2583 } | 2799 } |
2584 m_tcp->AddSocket (this); | 2800 m_tcp->AddSocket (this); |
2585 | 2801 |
2586 // Change the cloned socket from LISTEN state to SYN_RCVD | 2802 // Change the cloned socket from LISTEN state to SYN_RCVD |
2587 NS_LOG_DEBUG ("LISTEN -> SYN_RCVD"); | 2803 NS_LOG_DEBUG ("LISTEN -> SYN_RCVD"); |
2588 m_state = SYN_RCVD; | 2804 m_state = SYN_RCVD; |
2589 m_synCount = m_synRetries; | 2805 m_synCount = m_synRetries; |
2590 m_dataRetrCount = m_dataRetries; | 2806 m_dataRetrCount = m_dataRetries; |
2591 SetupCallback (); | 2807 SetupCallback (); |
2592 // Set the sequence number and send SYN+ACK | 2808 // Set the sequence number and send SYN+ACK |
2593 m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1)); | 2809 m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1)); |
2594 | 2810 |
2595 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 2811 /* Check if we received an ECN SYN packet. Change the ECN state of receiver to
ECN_IDLE if sender has sent an ECN SYN· |
| 2812 * packet and the traffic is ECN Capable |
| 2813 */ |
| 2814 if (m_ecn && (h.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader
::CWR | TcpHeader::ECE)) |
| 2815 { |
| 2816 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK | TcpHeader::ECE); |
| 2817 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
| 2818 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
IDLE"); |
| 2819 } |
| 2820 else |
| 2821 { |
| 2822 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); |
| 2823 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
| 2824 }·· |
2596 } | 2825 } |
2597 | 2826 |
2598 void | 2827 void |
2599 TcpSocketBase::ConnectionSucceeded () | 2828 TcpSocketBase::ConnectionSucceeded () |
2600 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can | 2829 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can |
2601 // be called as a scheduled event | 2830 // be called as a scheduled event |
2602 NotifyConnectionSucceeded (); | 2831 NotifyConnectionSucceeded (); |
2603 // The if-block below was moved from ProcessSynSent() to here because we need | 2832 // The if-block below was moved from ProcessSynSent() to here because we need |
2604 // to invoke the NotifySend() only after NotifyConnectionSucceeded() to | 2833 // to invoke the NotifySend() only after NotifyConnectionSucceeded() to |
2605 // reflect the behaviour in the real world. | 2834 // reflect the behaviour in the real world. |
(...skipping 20 matching lines...) Expand all Loading... |
2626 uint32_t sz = p->GetSize (); // Size of packet | 2855 uint32_t sz = p->GetSize (); // Size of packet |
2627 uint8_t flags = withAck ? TcpHeader::ACK : 0; | 2856 uint8_t flags = withAck ? TcpHeader::ACK : 0; |
2628 uint32_t remainingData = m_txBuffer->SizeFromSequence (seq + SequenceNumber32
(sz)); | 2857 uint32_t remainingData = m_txBuffer->SizeFromSequence (seq + SequenceNumber32
(sz)); |
2629 | 2858 |
2630 if (withAck) | 2859 if (withAck) |
2631 { | 2860 { |
2632 m_delAckEvent.Cancel (); | 2861 m_delAckEvent.Cancel (); |
2633 m_delAckCount = 0; | 2862 m_delAckCount = 0; |
2634 } | 2863 } |
2635 | 2864 |
| 2865 // Sender should reduce the Congestion Window as a response to receiver's ECN
Echo notification only once per window· |
| 2866 if (m_tcb->m_ecnState == TcpSocketState::ECN_ECE_RCVD && m_ecnEchoSeq.Get() >
m_ecnCWRSeq.Get() && !isRetransmission )· |
| 2867 { |
| 2868 NS_LOG_INFO ("Backoff mechanism by reducing CWND by half because we've re
ceived ECN Echo"); |
| 2869 m_congestionControl->ReduceCwnd (m_tcb); |
| 2870 m_tcb->m_ssThresh = m_tcb->m_cWnd; |
| 2871 flags |= TcpHeader::CWR;· |
| 2872 m_ecnCWRSeq = seq; |
| 2873 m_tcb->m_ecnState = TcpSocketState::ECN_CWR_SENT; |
| 2874 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
CWR_SENT"); |
| 2875 NS_LOG_INFO ("CWR flags set"); |
| 2876 NS_LOG_DEBUG (TcpSocketState::TcpCongStateName[m_tcb->m_congState] << " ->
CA_CWR"); |
| 2877 if (m_tcb->m_congState == TcpSocketState::CA_OPEN) |
| 2878 { |
| 2879 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_CWR
); |
| 2880 m_tcb->m_congState = TcpSocketState::CA_CWR; |
| 2881 } |
| 2882 } |
| 2883 |
2636 /* | 2884 /* |
2637 * Add tags for each socket option. | 2885 * Add tags for each socket option. |
2638 * Note that currently the socket adds both IPv4 tag and IPv6 tag | 2886 * Note that currently the socket adds both IPv4 tag and IPv6 tag |
2639 * if both options are set. Once the packet got to layer three, only | 2887 * if both options are set. Once the packet got to layer three, only |
2640 * the corresponding tags will be read. | 2888 * the corresponding tags will be read. |
2641 */ | 2889 */ |
2642 if (GetIpTos ()) | 2890 if (GetIpTos ()) |
2643 { | 2891 { |
2644 SocketIpTosTag ipTosTag; | 2892 SocketIpTosTag ipTosTag; |
2645 ipTosTag.SetTos (GetIpTos ()); | 2893 NS_LOG_LOGIC (" ECT bits should not be set on retransmitted packets"); |
| 2894 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && (GetIpTos () & 0x
3) == 0 && !isRetransmission) |
| 2895 {· |
| 2896 //Classic traffic have ECT0 flags whereas L4S have ECT1 flags set |
| 2897 if (m_congestionControl->GetName () == "TcpDctcp") |
| 2898 { |
| 2899 ipTosTag.SetTos (GetIpTos () | 0x1); |
| 2900 } |
| 2901 else |
| 2902 { |
| 2903 ipTosTag.SetTos (GetIpTos () | 0x2); |
| 2904 } |
| 2905 } |
| 2906 else |
| 2907 { |
| 2908 ipTosTag.SetTos (GetIpTos ()); |
| 2909 } |
2646 p->AddPacketTag (ipTosTag); | 2910 p->AddPacketTag (ipTosTag); |
2647 } | 2911 } |
| 2912 else |
| 2913 { |
| 2914 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && !isRetransmission
) |
| 2915 { |
| 2916 SocketIpTosTag ipTosTag; |
| 2917 //Classic traffic have ECT0 flags whereas L4S have ECT1 flags set |
| 2918 if (m_congestionControl->GetName () == "TcpDctcp") |
| 2919 { |
| 2920 ipTosTag.SetTos (0x1); |
| 2921 } |
| 2922 else |
| 2923 { |
| 2924 ipTosTag.SetTos (0x2); |
| 2925 } |
| 2926 p->AddPacketTag (ipTosTag); |
| 2927 } |
| 2928 } |
2648 | 2929 |
2649 if (IsManualIpv6Tclass ()) | 2930 if (IsManualIpv6Tclass ()) |
2650 { | 2931 { |
2651 SocketIpv6TclassTag ipTclassTag; | 2932 SocketIpv6TclassTag ipTclassTag; |
2652 ipTclassTag.SetTclass (GetIpv6Tclass ()); | 2933 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && (GetIpv6Tclass ()
& 0x3) == 0 && !isRetransmission) |
| 2934 { |
| 2935 //Classic traffic have ECT0 flags whereas L4S have ECT1 flags set |
| 2936 if (m_congestionControl->GetName () == "TcpDctcp") |
| 2937 { |
| 2938 ipTclassTag.SetTclass (GetIpv6Tclass () | 0x1); |
| 2939 } |
| 2940 else |
| 2941 { |
| 2942 ipTclassTag.SetTclass (GetIpv6Tclass () | 0x2); |
| 2943 } |
| 2944 } |
| 2945 else |
| 2946 { |
| 2947 ipTclassTag.SetTclass (GetIpv6Tclass ()); |
| 2948 } |
2653 p->AddPacketTag (ipTclassTag); | 2949 p->AddPacketTag (ipTclassTag); |
2654 } | 2950 } |
| 2951 else |
| 2952 { |
| 2953 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && !isRetransmission
) |
| 2954 { |
| 2955 SocketIpv6TclassTag ipTclassTag; |
| 2956 //Classic traffic have ECT0 flags whereas L4S have ECT1 flags set |
| 2957 if (m_congestionControl->GetName () == "TcpDctcp") |
| 2958 { |
| 2959 ipTclassTag.SetTclass (0x1); |
| 2960 } |
| 2961 else |
| 2962 { |
| 2963 ipTclassTag.SetTclass (0x2); |
| 2964 } |
| 2965 p->AddPacketTag (ipTclassTag); |
| 2966 } |
| 2967 } |
2655 | 2968 |
2656 if (IsManualIpTtl ()) | 2969 if (IsManualIpTtl ()) |
2657 { | 2970 { |
2658 SocketIpTtlTag ipTtlTag; | 2971 SocketIpTtlTag ipTtlTag; |
2659 ipTtlTag.SetTtl (GetIpTtl ()); | 2972 ipTtlTag.SetTtl (GetIpTtl ()); |
2660 p->AddPacketTag (ipTtlTag); | 2973 p->AddPacketTag (ipTtlTag); |
2661 } | 2974 } |
2662 | 2975 |
2663 if (IsManualIpv6HopLimit ()) | 2976 if (IsManualIpv6HopLimit ()) |
2664 { | 2977 { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2845 // invoked for this retransmission. | 3158 // invoked for this retransmission. |
2846 // (C.3) If any of the data octets sent in (C.1) are above HighData, | 3159 // (C.3) If any of the data octets sent in (C.1) are above HighData, |
2847 // HighData must be updated to reflect the transmission of | 3160 // HighData must be updated to reflect the transmission of |
2848 // previously unsent data. | 3161 // previously unsent data. |
2849 // | 3162 // |
2850 // These steps are done in m_txBuffer with the tags. | 3163 // These steps are done in m_txBuffer with the tags. |
2851 if (m_tcb->m_nextTxSequence != next) | 3164 if (m_tcb->m_nextTxSequence != next) |
2852 { | 3165 { |
2853 m_tcb->m_nextTxSequence = next; | 3166 m_tcb->m_nextTxSequence = next; |
2854 } | 3167 } |
2855 | 3168 if (m_bytesInFlight.Get () == 0) |
| 3169 { |
| 3170 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_TX
_START); |
| 3171 } |
2856 uint32_t sz = SendDataPacket (m_tcb->m_nextTxSequence, s, withAck); | 3172 uint32_t sz = SendDataPacket (m_tcb->m_nextTxSequence, s, withAck); |
2857 m_tcb->m_nextTxSequence += sz; | 3173 m_tcb->m_nextTxSequence += sz; |
2858 | 3174 |
2859 NS_LOG_LOGIC (" rxwin " << m_rWnd << | 3175 NS_LOG_LOGIC (" rxwin " << m_rWnd << |
2860 " segsize " << m_tcb->m_segmentSize << | 3176 " segsize " << m_tcb->m_segmentSize << |
2861 " highestRxAck " << m_txBuffer->HeadSequence () << | 3177 " highestRxAck " << m_txBuffer->HeadSequence () << |
2862 " pd->Size " << m_txBuffer->Size () << | 3178 " pd->Size " << m_txBuffer->Size () << |
2863 " pd->SFS " << m_txBuffer->SizeFromSequence (m_tcb->m_ne
xtTxSequence)); | 3179 " pd->SFS " << m_txBuffer->SizeFromSequence (m_tcb->m_ne
xtTxSequence)); |
2864 | 3180 |
2865 NS_LOG_DEBUG ("cWnd: " << m_tcb->m_cWnd << | 3181 NS_LOG_DEBUG ("cWnd: " << m_tcb->m_cWnd << |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2981 TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader) | 3297 TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader) |
2982 { | 3298 { |
2983 NS_LOG_FUNCTION (this << tcpHeader); | 3299 NS_LOG_FUNCTION (this << tcpHeader); |
2984 NS_LOG_DEBUG ("Data segment, seq=" << tcpHeader.GetSequenceNumber () << | 3300 NS_LOG_DEBUG ("Data segment, seq=" << tcpHeader.GetSequenceNumber () << |
2985 " pkt size=" << p->GetSize () ); | 3301 " pkt size=" << p->GetSize () ); |
2986 | 3302 |
2987 // Put into Rx buffer | 3303 // Put into Rx buffer |
2988 SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence (); | 3304 SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence (); |
2989 if (!m_rxBuffer->Add (p, tcpHeader)) | 3305 if (!m_rxBuffer->Add (p, tcpHeader)) |
2990 { // Insert failed: No data or RX buffer full | 3306 { // Insert failed: No data or RX buffer full |
2991 SendEmptyPacket (TcpHeader::ACK); | 3307 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState
== TcpSocketState::ECN_ECE_SENT) |
| 3308 { |
| 3309 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
| 3310 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
| 3311 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_ECE_SENT"); |
| 3312 } |
| 3313 else |
| 3314 { |
| 3315 SendEmptyPacket (TcpHeader::ACK); |
| 3316 }· |
2992 return; | 3317 return; |
2993 } | 3318 } |
2994 // Notify app to receive if necessary | 3319 // Notify app to receive if necessary |
2995 if (expectedSeq < m_rxBuffer->NextRxSequence ()) | 3320 if (expectedSeq < m_rxBuffer->NextRxSequence ()) |
2996 { // NextRxSeq advanced, we have something to send to the app | 3321 { // NextRxSeq advanced, we have something to send to the app |
2997 if (!m_shutdownRecv) | 3322 if (!m_shutdownRecv) |
2998 { | 3323 { |
2999 NotifyDataRecv (); | 3324 NotifyDataRecv (); |
3000 } | 3325 } |
3001 // Handle exceptions | 3326 // Handle exceptions |
3002 if (m_closeNotified) | 3327 if (m_closeNotified) |
3003 { | 3328 { |
3004 NS_LOG_WARN ("Why TCP " << this << " got data after close notification
?"); | 3329 NS_LOG_WARN ("Why TCP " << this << " got data after close notification
?"); |
3005 } | 3330 } |
3006 // If we received FIN before and now completed all "holes" in rx buffer, | 3331 // If we received FIN before and now completed all "holes" in rx buffer, |
3007 // invoke peer close procedure | 3332 // invoke peer close procedure |
3008 if (m_rxBuffer->Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) ==
0) | 3333 if (m_rxBuffer->Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) ==
0) |
3009 { | 3334 { |
3010 DoPeerClose (); | 3335 DoPeerClose (); |
3011 return; | 3336 return; |
3012 } | 3337 } |
3013 } | 3338 } |
3014 // Now send a new ACK packet acknowledging all received and delivered data | 3339 // Now send a new ACK packet acknowledging all received and delivered data |
3015 if (m_rxBuffer->Size () > m_rxBuffer->Available () || m_rxBuffer->NextRxSequen
ce () > expectedSeq + p->GetSize ()) | 3340 if (m_rxBuffer->Size () > m_rxBuffer->Available () || m_rxBuffer->NextRxSequen
ce () > expectedSeq + p->GetSize ()) |
3016 { // A gap exists in the buffer, or we filled a gap: Always ACK | 3341 { // A gap exists in the buffer, or we filled a gap: Always ACK |
3017 SendEmptyPacket (TcpHeader::ACK); | 3342 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_NON_DELAY
ED_ACK); |
| 3343 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState
== TcpSocketState::ECN_ECE_SENT) |
| 3344 { |
| 3345 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
| 3346 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
| 3347 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_ECE_SENT"); |
| 3348 } |
| 3349 else |
| 3350 { |
| 3351 SendEmptyPacket (TcpHeader::ACK); |
| 3352 } |
3018 } | 3353 } |
3019 else | 3354 else |
3020 { // In-sequence packet: ACK if delayed ack count allows | 3355 { // In-sequence packet: ACK if delayed ack count allows |
3021 if (++m_delAckCount >= m_delAckMaxCount) | 3356 if (++m_delAckCount >= m_delAckMaxCount) |
3022 { | 3357 { |
3023 m_delAckEvent.Cancel (); | 3358 m_delAckEvent.Cancel (); |
3024 m_delAckCount = 0; | 3359 m_delAckCount = 0; |
3025 SendEmptyPacket (TcpHeader::ACK); | 3360 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_NON_DE
LAYED_ACK); |
| 3361 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnSt
ate == TcpSocketState::ECN_ECE_SENT) //problem |
| 3362 { |
| 3363 NS_LOG_DEBUG("Congestion algo "<<m_congestionControl->GetName ()); |
| 3364 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
| 3365 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
| 3366 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_SENT"); |
| 3367 } |
| 3368 else |
| 3369 { |
| 3370 SendEmptyPacket (TcpHeader::ACK); |
| 3371 } |
| 3372 } |
| 3373 else if (!m_delAckEvent.IsExpired ()) |
| 3374 { |
| 3375 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_DELAYE
D_ACK); |
3026 } | 3376 } |
3027 else if (m_delAckEvent.IsExpired ()) | 3377 else if (m_delAckEvent.IsExpired ()) |
3028 { | 3378 { |
| 3379 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_DELAYE
D_ACK); |
3029 m_delAckEvent = Simulator::Schedule (m_delAckTimeout, | 3380 m_delAckEvent = Simulator::Schedule (m_delAckTimeout, |
3030 &TcpSocketBase::DelAckTimeout, th
is); | 3381 &TcpSocketBase::DelAckTimeout, th
is); |
3031 NS_LOG_LOGIC (this << " scheduled delayed ACK at " << | 3382 NS_LOG_LOGIC (this << " scheduled delayed ACK at " << |
3032 (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEv
ent)).GetSeconds ()); | 3383 (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEv
ent)).GetSeconds ()); |
3033 } | 3384 } |
3034 } | 3385 } |
3035 } | 3386 } |
3036 | 3387 |
3037 /** | 3388 /** |
3038 * \brief Estimate the RTT | 3389 * \brief Estimate the RTT |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3202 // When a TCP sender detects segment loss using the retransmission timer | 3553 // When a TCP sender detects segment loss using the retransmission timer |
3203 // and the given segment has not yet been resent by way of the | 3554 // and the given segment has not yet been resent by way of the |
3204 // retransmission timer, decrease ssThresh | 3555 // retransmission timer, decrease ssThresh |
3205 if (m_tcb->m_congState != TcpSocketState::CA_LOSS || !m_txBuffer->IsHeadRetran
smitted ()) | 3556 if (m_tcb->m_congState != TcpSocketState::CA_LOSS || !m_txBuffer->IsHeadRetran
smitted ()) |
3206 { | 3557 { |
3207 m_tcb->m_ssThresh = m_congestionControl->GetSsThresh (m_tcb, BytesInFlight
()); | 3558 m_tcb->m_ssThresh = m_congestionControl->GetSsThresh (m_tcb, BytesInFlight
()); |
3208 } | 3559 } |
3209 | 3560 |
3210 // Cwnd set to 1 MSS | 3561 // Cwnd set to 1 MSS |
3211 m_tcb->m_cWnd = m_tcb->m_segmentSize; | 3562 m_tcb->m_cWnd = m_tcb->m_segmentSize; |
3212 | 3563 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_LOSS); |
3213 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_LOSS); | 3564 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_LOSS); |
3214 m_tcb->m_congState = TcpSocketState::CA_LOSS; | 3565 m_tcb->m_congState = TcpSocketState::CA_LOSS; |
3215 | 3566 |
3216 NS_LOG_DEBUG ("RTO. Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " << | 3567 NS_LOG_DEBUG ("RTO. Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " << |
3217 m_tcb->m_ssThresh << ", restart from seqnum " << | 3568 m_tcb->m_ssThresh << ", restart from seqnum " << |
3218 m_txBuffer->HeadSequence () << " doubled rto to " << | 3569 m_txBuffer->HeadSequence () << " doubled rto to " << |
3219 m_rto.Get ().GetSeconds () << " s"); | 3570 m_rto.Get ().GetSeconds () << " s"); |
3220 | 3571 |
3221 NS_ASSERT_MSG (BytesInFlight () == 0, "There are some bytes in flight after an
RTO: " << | 3572 NS_ASSERT_MSG (BytesInFlight () == 0, "There are some bytes in flight after an
RTO: " << |
3222 BytesInFlight ()); | 3573 BytesInFlight ()); |
3223 | 3574 |
3224 // Retransmit the packet | 3575 // Retransmit the packet |
3225 DoRetransmit (); | 3576 DoRetransmit (); |
3226 | 3577 |
3227 NS_ASSERT_MSG (BytesInFlight () <= m_tcb->m_segmentSize, | 3578 NS_ASSERT_MSG (BytesInFlight () <= m_tcb->m_segmentSize, |
3228 "In flight there is more than one segment"); | 3579 "In flight there is more than one segment"); |
3229 } | 3580 } |
3230 | 3581 |
3231 void | 3582 void |
3232 TcpSocketBase::DelAckTimeout (void) | 3583 TcpSocketBase::DelAckTimeout (void) |
3233 { | 3584 { |
3234 m_delAckCount = 0; | 3585 m_delAckCount = 0; |
3235 SendEmptyPacket (TcpHeader::ACK); | 3586 m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_DELAYED_ACK); |
| 3587 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState == T
cpSocketState::ECN_ECE_SENT) |
| 3588 { |
| 3589 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
| 3590 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
| 3591 } |
| 3592 else |
| 3593 { |
| 3594 SendEmptyPacket (TcpHeader::ACK); |
| 3595 } |
3236 } | 3596 } |
3237 | 3597 |
3238 void | 3598 void |
3239 TcpSocketBase::LastAckTimeout (void) | 3599 TcpSocketBase::LastAckTimeout (void) |
3240 { | 3600 { |
3241 NS_LOG_FUNCTION (this); | 3601 NS_LOG_FUNCTION (this); |
3242 | 3602 |
3243 m_lastAckEvent.Cancel (); | 3603 m_lastAckEvent.Cancel (); |
3244 if (m_state == LAST_ACK) | 3604 if (m_state == LAST_ACK) |
3245 { | 3605 { |
(...skipping 23 matching lines...) Expand all Loading... |
3269 { | 3629 { |
3270 tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ()); | 3630 tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ()); |
3271 tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ()); | 3631 tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ()); |
3272 } | 3632 } |
3273 else | 3633 else |
3274 { | 3634 { |
3275 tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ()); | 3635 tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ()); |
3276 tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ()); | 3636 tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ()); |
3277 } | 3637 } |
3278 AddOptions (tcpHeader); | 3638 AddOptions (tcpHeader); |
3279 | 3639 //Send a packet tag for setting ECT bits in IP header |
| 3640 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED) |
| 3641 { |
| 3642 SocketIpTosTag ipTosTag; |
| 3643 //Classic traffic have ECT0 flags whereas L4S have ECT1 flags set |
| 3644 if (m_congestionControl->GetName () == "TcpDctcp") |
| 3645 {·· |
| 3646 ipTosTag.SetTos (0x1); |
| 3647 } |
| 3648 else |
| 3649 {·· |
| 3650 ipTosTag.SetTos (0x2); |
| 3651 } |
| 3652 p->AddPacketTag (ipTosTag); |
| 3653 · |
| 3654 SocketIpv6TclassTag ipTclassTag; |
| 3655 //Classic traffic have ECT0 flags whereas L4S have ECT1 flags set |
| 3656 if (m_congestionControl->GetName () == "TcpDctcp") |
| 3657 { |
| 3658 ipTclassTag.SetTclass (0x1); |
| 3659 } |
| 3660 else |
| 3661 { |
| 3662 ipTclassTag.SetTclass (0x2); |
| 3663 } |
| 3664 p->AddPacketTag (ipTclassTag); |
| 3665 } |
3280 m_txTrace (p, tcpHeader, this); | 3666 m_txTrace (p, tcpHeader, this); |
3281 | 3667 |
3282 if (m_endPoint != 0) | 3668 if (m_endPoint != 0) |
3283 { | 3669 { |
3284 m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (), | 3670 m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (), |
3285 m_endPoint->GetPeerAddress (), m_boundnetdevice); | 3671 m_endPoint->GetPeerAddress (), m_boundnetdevice); |
3286 } | 3672 } |
3287 else | 3673 else |
3288 { | 3674 { |
3289 m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (), | 3675 m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (), |
3290 m_endPoint6->GetPeerAddress (), m_boundnetdevice); | 3676 m_endPoint6->GetPeerAddress (), m_boundnetdevice); |
3291 } | 3677 } |
3292 | 3678 |
3293 NS_LOG_LOGIC ("Schedule persist timeout at time " | 3679 NS_LOG_LOGIC ("Schedule persist timeout at time " |
3294 << Simulator::Now ().GetSeconds () << " to expire at time " | 3680 << Simulator::Now ().GetSeconds () << " to expire at time " |
3295 << (Simulator::Now () + m_persistTimeout).GetSeconds ()); | 3681 << (Simulator::Now () + m_persistTimeout).GetSeconds ()); |
3296 m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::Persis
tTimeout, this); | 3682 m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::Persis
tTimeout, this); |
3297 } | 3683 } |
3298 | 3684 |
3299 void | 3685 void |
3300 TcpSocketBase::DoRetransmit () | 3686 TcpSocketBase::DoRetransmit () |
3301 { | 3687 { |
3302 NS_LOG_FUNCTION (this); | 3688 NS_LOG_FUNCTION (this); |
3303 // Retransmit SYN packet | 3689 // Retransmit SYN packet |
3304 if (m_state == SYN_SENT) | 3690 if (m_state == SYN_SENT) |
3305 { | 3691 { |
3306 if (m_synCount > 0) | 3692 if (m_synCount > 0) |
3307 { | 3693 { |
3308 SendEmptyPacket (TcpHeader::SYN); | 3694 if (m_ecn) |
| 3695 { |
| 3696 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR)
; |
| 3697 } |
| 3698 else |
| 3699 { |
| 3700 SendEmptyPacket (TcpHeader::SYN); |
| 3701 } |
| 3702 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
3309 } | 3703 } |
3310 else | 3704 else |
3311 { | 3705 { |
3312 NotifyConnectionFailed (); | 3706 NotifyConnectionFailed (); |
3313 } | 3707 } |
3314 return; | 3708 return; |
3315 } | 3709 } |
3316 | 3710 |
3317 if (m_dataRetrCount == 0) | 3711 if (m_dataRetrCount == 0) |
3318 { | 3712 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3365 m_sendPendingDataEvent.Cancel (); | 3759 m_sendPendingDataEvent.Cancel (); |
3366 } | 3760 } |
3367 | 3761 |
3368 /* Move TCP to Time_Wait state and schedule a transition to Closed state */ | 3762 /* Move TCP to Time_Wait state and schedule a transition to Closed state */ |
3369 void | 3763 void |
3370 TcpSocketBase::TimeWait () | 3764 TcpSocketBase::TimeWait () |
3371 { | 3765 { |
3372 NS_LOG_DEBUG (TcpStateName[m_state] << " -> TIME_WAIT"); | 3766 NS_LOG_DEBUG (TcpStateName[m_state] << " -> TIME_WAIT"); |
3373 m_state = TIME_WAIT; | 3767 m_state = TIME_WAIT; |
3374 CancelAllTimers (); | 3768 CancelAllTimers (); |
3375 if (!m_closeNotified) | |
3376 { | |
3377 // Technically the connection is not fully closed, but we notify now· | |
3378 // because an implementation (real socket) would behave as if closed. | |
3379 // Notify normal close when entering TIME_WAIT or leaving LAST_ACK. | |
3380 NotifyNormalClose (); | |
3381 m_closeNotified = true; | |
3382 } | |
3383 // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min | 3769 // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min |
3384 // according to RFC793, p.28 | 3770 // according to RFC793, p.28 |
3385 m_timewaitEvent = Simulator::Schedule (Seconds (2 * m_msl), | 3771 m_timewaitEvent = Simulator::Schedule (Seconds (2 * m_msl), |
3386 &TcpSocketBase::CloseAndNotify, this); | 3772 &TcpSocketBase::CloseAndNotify, this); |
3387 } | 3773 } |
3388 | 3774 |
3389 /* Below are the attribute get/set functions */ | 3775 /* Below are the attribute get/set functions */ |
3390 | 3776 |
3391 void | 3777 void |
3392 TcpSocketBase::SetSndBufSize (uint32_t size) | 3778 TcpSocketBase::SetSndBufSize (uint32_t size) |
(...skipping 14 matching lines...) Expand all Loading... |
3407 NS_LOG_FUNCTION (this << size); | 3793 NS_LOG_FUNCTION (this << size); |
3408 uint32_t oldSize = GetRcvBufSize (); | 3794 uint32_t oldSize = GetRcvBufSize (); |
3409 | 3795 |
3410 m_rxBuffer->SetMaxBufferSize (size); | 3796 m_rxBuffer->SetMaxBufferSize (size); |
3411 | 3797 |
3412 /* The size has (manually) increased. Actively inform the other end to prevent | 3798 /* The size has (manually) increased. Actively inform the other end to prevent |
3413 * stale zero-window states. | 3799 * stale zero-window states. |
3414 */ | 3800 */ |
3415 if (oldSize < size && m_connected) | 3801 if (oldSize < size && m_connected) |
3416 { | 3802 { |
3417 SendEmptyPacket (TcpHeader::ACK); | 3803 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState
== TcpSocketState::ECN_ECE_SENT) |
| 3804 { |
| 3805 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
| 3806 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
| 3807 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_ECE_SENT"); |
| 3808 } |
| 3809 else |
| 3810 { |
| 3811 SendEmptyPacket (TcpHeader::ACK); |
| 3812 } |
3418 } | 3813 } |
3419 } | 3814 } |
3420 | 3815 |
3421 uint32_t | 3816 uint32_t |
3422 TcpSocketBase::GetRcvBufSize (void) const | 3817 TcpSocketBase::GetRcvBufSize (void) const |
3423 { | 3818 { |
3424 return m_rxBuffer->MaxBufferSize (); | 3819 return m_rxBuffer->MaxBufferSize (); |
3425 } | 3820 } |
3426 | 3821 |
3427 void | 3822 void |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3812 } | 4207 } |
3813 | 4208 |
3814 void | 4209 void |
3815 TcpSocketBase::UpdateCongState (TcpSocketState::TcpCongState_t oldValue, | 4210 TcpSocketBase::UpdateCongState (TcpSocketState::TcpCongState_t oldValue, |
3816 TcpSocketState::TcpCongState_t newValue) | 4211 TcpSocketState::TcpCongState_t newValue) |
3817 { | 4212 { |
3818 m_congStateTrace (oldValue, newValue); | 4213 m_congStateTrace (oldValue, newValue); |
3819 } | 4214 } |
3820 | 4215 |
3821 void | 4216 void |
| 4217 TcpSocketBase::UpdateEcnState (TcpSocketState::EcnState_t oldValue, |
| 4218 TcpSocketState::EcnState_t newValue) |
| 4219 { |
| 4220 m_ecnStateTrace (oldValue, newValue); |
| 4221 } |
| 4222 |
| 4223 void |
3822 TcpSocketBase::UpdateNextTxSequence (SequenceNumber32 oldValue, | 4224 TcpSocketBase::UpdateNextTxSequence (SequenceNumber32 oldValue, |
3823 SequenceNumber32 newValue) | 4225 SequenceNumber32 newValue) |
3824 | 4226 |
3825 { | 4227 { |
3826 m_nextTxSequenceTrace (oldValue, newValue); | 4228 m_nextTxSequenceTrace (oldValue, newValue); |
3827 } | 4229 } |
3828 | 4230 |
3829 void | 4231 void |
3830 TcpSocketBase::UpdateHighTxMark (SequenceNumber32 oldValue, SequenceNumber32 new
Value) | 4232 TcpSocketBase::UpdateHighTxMark (SequenceNumber32 oldValue, SequenceNumber32 new
Value) |
3831 { | 4233 { |
3832 m_highTxMarkTrace (oldValue, newValue); | 4234 m_highTxMarkTrace (oldValue, newValue); |
3833 } | 4235 } |
3834 | 4236 |
3835 void | 4237 void |
3836 TcpSocketBase::SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo) | 4238 TcpSocketBase::SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo) |
3837 { | 4239 { |
3838 NS_LOG_FUNCTION (this << algo); | 4240 NS_LOG_FUNCTION (this << algo); |
| 4241 NS_LOG_DEBUG ("Congestion control algo is" << algo); |
3839 m_congestionControl = algo; | 4242 m_congestionControl = algo; |
| 4243 m_congestionControl->SetSocketBase(this); |
3840 } | 4244 } |
3841 | 4245 |
3842 Ptr<TcpSocketBase> | 4246 Ptr<TcpSocketBase> |
3843 TcpSocketBase::Fork (void) | 4247 TcpSocketBase::Fork (void) |
3844 { | 4248 { |
3845 return CopyObject<TcpSocketBase> (this); | 4249 return CopyObject<TcpSocketBase> (this); |
3846 } | 4250 } |
3847 | 4251 |
3848 uint32_t | 4252 uint32_t |
3849 TcpSocketBase::SafeSubtraction (uint32_t a, uint32_t b) | 4253 TcpSocketBase::SafeSubtraction (uint32_t a, uint32_t b) |
3850 { | 4254 { |
3851 if (a > b) | 4255 if (a > b) |
3852 { | 4256 { |
3853 return a-b; | 4257 return a-b; |
3854 } | 4258 } |
3855 | 4259 |
3856 return 0; | 4260 return 0; |
3857 } | 4261 } |
3858 | 4262 |
| 4263 void |
| 4264 TcpSocketBase::SetEcn() |
| 4265 { |
| 4266 m_ecn = true; |
| 4267 } |
| 4268 |
3859 //RttHistory methods | 4269 //RttHistory methods |
3860 RttHistory::RttHistory (SequenceNumber32 s, uint32_t c, Time t) | 4270 RttHistory::RttHistory (SequenceNumber32 s, uint32_t c, Time t) |
3861 : seq (s), | 4271 : seq (s), |
3862 count (c), | 4272 count (c), |
3863 time (t), | 4273 time (t), |
3864 retx (false) | 4274 retx (false) |
3865 { | 4275 { |
3866 } | 4276 } |
3867 | 4277 |
3868 RttHistory::RttHistory (const RttHistory& h) | 4278 RttHistory::RttHistory (const RttHistory& h) |
3869 : seq (h.seq), | 4279 : seq (h.seq), |
3870 count (h.count), | 4280 count (h.count), |
3871 time (h.time), | 4281 time (h.time), |
3872 retx (h.retx) | 4282 retx (h.retx) |
3873 { | 4283 { |
3874 } | 4284 } |
3875 | 4285 |
3876 } // namespace ns3 | 4286 } // namespace ns3 |
OLD | NEW |