LEFT | RIGHT |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 MakeTraceSourceAccessor (&TcpSocketBase::m_highTxMarkTrace)
, | 156 MakeTraceSourceAccessor (&TcpSocketBase::m_highTxMarkTrace)
, |
157 "ns3::SequenceNumber32TracedValueCallback") | 157 "ns3::SequenceNumber32TracedValueCallback") |
158 .AddTraceSource ("State", | 158 .AddTraceSource ("State", |
159 "TCP state", | 159 "TCP state", |
160 MakeTraceSourceAccessor (&TcpSocketBase::m_state), | 160 MakeTraceSourceAccessor (&TcpSocketBase::m_state), |
161 "ns3::TcpStatesTracedValueCallback") | 161 "ns3::TcpStatesTracedValueCallback") |
162 .AddTraceSource ("CongState", | 162 .AddTraceSource ("CongState", |
163 "TCP Congestion machine state", | 163 "TCP Congestion machine state", |
164 MakeTraceSourceAccessor (&TcpSocketBase::m_congStateTrace), | 164 MakeTraceSourceAccessor (&TcpSocketBase::m_congStateTrace), |
165 "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") |
| 170 .AddTraceSource ("AdvWND", |
| 171 "Advertised Window Size", |
| 172 MakeTraceSourceAccessor (&TcpSocketBase::m_advWnd), |
| 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", |
172 MakeTraceSourceAccessor (&TcpSocketBase::m_bytesInFlight), | 180 MakeTraceSourceAccessor (&TcpSocketBase::m_bytesInFlight), |
173 "ns3::TracedValueCallback::Uint32") | 181 "ns3::TracedValueCallback::Uint32") |
174 .AddTraceSource ("HighestRxSequence", | 182 .AddTraceSource ("HighestRxSequence", |
175 "Highest sequence number received from peer", | 183 "Highest sequence number received from peer", |
(...skipping 12 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") |
198 .AddTraceSource ("ECNState", | 206 .AddTraceSource ("EcnEchoSeq", |
199 "Current ECN State of TCP Socket", | |
200 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnState), | |
201 "ns3::EcnStatesTracedValueCallback") | |
202 .AddTraceSource ("ECNEchoSeq", | |
203 "Sequence of last received ECN Echo", | 207 "Sequence of last received ECN Echo", |
204 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnEchoSeq), | 208 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnEchoSeq), |
205 "ns3::SequenceNumber32TracedValueCallback") | 209 "ns3::SequenceNumber32TracedValueCallback") |
206 .AddTraceSource ("ECNCESeq", | 210 .AddTraceSource ("EcnCESeq", |
207 "Sequence of last received CE ", | 211 "Sequence of last received CE ", |
208 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnCESeq), | 212 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnCESeq), |
209 "ns3::SequenceNumber32TracedValueCallback") | 213 "ns3::SequenceNumber32TracedValueCallback") |
210 .AddTraceSource ("ECNCWRSeq", | 214 .AddTraceSource ("EcnCWRSeq", |
211 "Sequence of last received CWR", | 215 "Sequence of last received CWR", |
212 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnCWRSeq), | 216 MakeTraceSourceAccessor (&TcpSocketBase::m_ecnCWRSeq), |
213 "ns3::SequenceNumber32TracedValueCallback") | 217 "ns3::SequenceNumber32TracedValueCallback") |
214 ; | 218 ; |
215 return tid; | 219 return tid; |
216 } | 220 } |
217 | 221 |
218 TypeId | 222 TypeId |
219 TcpSocketBase::GetInstanceTypeId () const | 223 TcpSocketBase::GetInstanceTypeId () const |
220 { | 224 { |
(...skipping 13 matching lines...) Expand all Loading... |
234 MakeTraceSourceAccessor (&TcpSocketState::m_cWnd), | 238 MakeTraceSourceAccessor (&TcpSocketState::m_cWnd), |
235 "ns3::TracedValue::Uint32Callback") | 239 "ns3::TracedValue::Uint32Callback") |
236 .AddTraceSource ("SlowStartThreshold", | 240 .AddTraceSource ("SlowStartThreshold", |
237 "TCP slow start threshold (bytes)", | 241 "TCP slow start threshold (bytes)", |
238 MakeTraceSourceAccessor (&TcpSocketState::m_ssThresh), | 242 MakeTraceSourceAccessor (&TcpSocketState::m_ssThresh), |
239 "ns3::TracedValue::Uint32Callback") | 243 "ns3::TracedValue::Uint32Callback") |
240 .AddTraceSource ("CongState", | 244 .AddTraceSource ("CongState", |
241 "TCP Congestion machine state", | 245 "TCP Congestion machine state", |
242 MakeTraceSourceAccessor (&TcpSocketState::m_congState), | 246 MakeTraceSourceAccessor (&TcpSocketState::m_congState), |
243 "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") |
244 .AddTraceSource ("HighestSequence", | 252 .AddTraceSource ("HighestSequence", |
245 "Highest sequence number received from peer", | 253 "Highest sequence number received from peer", |
246 MakeTraceSourceAccessor (&TcpSocketState::m_highTxMark), | 254 MakeTraceSourceAccessor (&TcpSocketState::m_highTxMark), |
247 "ns3::SequenceNumber32TracedValueCallback") | 255 "ns3::SequenceNumber32TracedValueCallback") |
248 .AddTraceSource ("NextTxSequence", | 256 .AddTraceSource ("NextTxSequence", |
249 "Next sequence number to send (SND.NXT)", | 257 "Next sequence number to send (SND.NXT)", |
250 MakeTraceSourceAccessor (&TcpSocketState::m_nextTxSequence)
, | 258 MakeTraceSourceAccessor (&TcpSocketState::m_nextTxSequence)
, |
251 "ns3::SequenceNumber32TracedValueCallback") | 259 "ns3::SequenceNumber32TracedValueCallback") |
252 ; | 260 ; |
253 return tid; | 261 return tid; |
254 } | 262 } |
255 | 263 |
256 TcpSocketState::TcpSocketState (void) | 264 TcpSocketState::TcpSocketState (void) |
257 : Object (), | 265 : Object (), |
258 m_cWnd (0), | 266 m_cWnd (0), |
259 m_ssThresh (0), | 267 m_ssThresh (0), |
260 m_initialCWnd (0), | 268 m_initialCWnd (0), |
261 m_initialSsThresh (0), | 269 m_initialSsThresh (0), |
262 m_segmentSize (0), | 270 m_segmentSize (0), |
263 m_lastAckedSeq (0), | 271 m_lastAckedSeq (0), |
264 m_congState (CA_OPEN), | 272 m_congState (CA_OPEN), |
| 273 m_ecnState (ECN_DISABLED), |
265 m_highTxMark (0), | 274 m_highTxMark (0), |
266 // Change m_nextTxSequence for non-zero initial sequence number | 275 // Change m_nextTxSequence for non-zero initial sequence number |
267 m_nextTxSequence (0) | 276 m_nextTxSequence (0), |
| 277 m_rcvTimestampValue (0), |
| 278 m_rcvTimestampEchoReply (0) |
268 { | 279 { |
269 } | 280 } |
270 | 281 |
271 TcpSocketState::TcpSocketState (const TcpSocketState &other) | 282 TcpSocketState::TcpSocketState (const TcpSocketState &other) |
272 : Object (other), | 283 : Object (other), |
273 m_cWnd (other.m_cWnd), | 284 m_cWnd (other.m_cWnd), |
274 m_ssThresh (other.m_ssThresh), | 285 m_ssThresh (other.m_ssThresh), |
275 m_initialCWnd (other.m_initialCWnd), | 286 m_initialCWnd (other.m_initialCWnd), |
276 m_initialSsThresh (other.m_initialSsThresh), | 287 m_initialSsThresh (other.m_initialSsThresh), |
277 m_segmentSize (other.m_segmentSize), | 288 m_segmentSize (other.m_segmentSize), |
278 m_lastAckedSeq (other.m_lastAckedSeq), | 289 m_lastAckedSeq (other.m_lastAckedSeq), |
279 m_congState (other.m_congState), | 290 m_congState (other.m_congState), |
| 291 m_ecnState (other.m_ecnState), |
280 m_highTxMark (other.m_highTxMark), | 292 m_highTxMark (other.m_highTxMark), |
281 m_nextTxSequence (other.m_nextTxSequence) | 293 m_nextTxSequence (other.m_nextTxSequence), |
| 294 m_rcvTimestampValue (other.m_rcvTimestampValue), |
| 295 m_rcvTimestampEchoReply (other.m_rcvTimestampEchoReply) |
282 { | 296 { |
283 } | 297 } |
284 | 298 |
285 const char* const | 299 const char* const |
286 TcpSocketState::TcpCongStateName[TcpSocketState::CA_LAST_STATE] = | 300 TcpSocketState::TcpCongStateName[TcpSocketState::CA_LAST_STATE] = |
287 { | 301 { |
288 "CA_OPEN", "CA_DISORDER", "CA_CWR", "CA_RECOVERY", "CA_LOSS" | 302 "CA_OPEN", "CA_DISORDER", "CA_CWR", "CA_RECOVERY", "CA_LOSS" |
289 }; | 303 }; |
| 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 |
290 | 311 |
291 TcpSocketBase::TcpSocketBase (void) | 312 TcpSocketBase::TcpSocketBase (void) |
292 : TcpSocket (), | 313 : TcpSocket (), |
293 m_retxEvent (), | 314 m_retxEvent (), |
294 m_lastAckEvent (), | 315 m_lastAckEvent (), |
295 m_delAckEvent (), | 316 m_delAckEvent (), |
296 m_persistEvent (), | 317 m_persistEvent (), |
297 m_timewaitEvent (), | 318 m_timewaitEvent (), |
298 m_dupAckCount (0), | 319 m_dupAckCount (0), |
299 m_delAckCount (0), | 320 m_delAckCount (0), |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 m_sndWindShift (0), | 359 m_sndWindShift (0), |
339 m_timestampEnabled (true), | 360 m_timestampEnabled (true), |
340 m_timestampToEcho (0), | 361 m_timestampToEcho (0), |
341 m_sendPendingDataEvent (), | 362 m_sendPendingDataEvent (), |
342 // Set m_recover to the initial sequence number | 363 // Set m_recover to the initial sequence number |
343 m_recover (0), | 364 m_recover (0), |
344 m_retxThresh (3), | 365 m_retxThresh (3), |
345 m_limitedTx (false), | 366 m_limitedTx (false), |
346 m_congestionControl (0), | 367 m_congestionControl (0), |
347 m_isFirstPartialAck (true), | 368 m_isFirstPartialAck (true), |
348 m_ecn (false), | 369 m_ecn(false), |
349 m_ecnState (ECN_DISABLED), | |
350 m_ecnEchoSeq (0), | 370 m_ecnEchoSeq (0), |
351 m_ecnCESeq (0), | 371 m_ecnCESeq (0), |
352 m_ecnCWRSeq (0) | 372 m_ecnCWRSeq (0) |
353 { | 373 { |
354 NS_LOG_FUNCTION (this); | 374 NS_LOG_FUNCTION (this); |
355 m_rxBuffer = CreateObject<TcpRxBuffer> (); | 375 m_rxBuffer = CreateObject<TcpRxBuffer> (); |
356 m_txBuffer = CreateObject<TcpTxBuffer> (); | 376 m_txBuffer = CreateObject<TcpTxBuffer> (); |
357 m_tcb = CreateObject<TcpSocketState> (); | 377 m_tcb = CreateObject<TcpSocketState> (); |
358 | 378 |
359 bool ok; | 379 bool ok; |
360 | 380 |
361 ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow", | 381 ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow", |
362 MakeCallback (&TcpSocketBase::UpdateCw
nd, this)); | 382 MakeCallback (&TcpSocketBase::UpdateCw
nd, this)); |
363 NS_ASSERT (ok == true); | 383 NS_ASSERT (ok == true); |
364 | 384 |
365 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", | 385 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", |
366 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); | 386 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); |
367 NS_ASSERT (ok == true); | 387 NS_ASSERT (ok == true); |
368 | 388 |
369 ok = m_tcb->TraceConnectWithoutContext ("CongState", | 389 ok = m_tcb->TraceConnectWithoutContext ("CongState", |
370 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); | 390 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); |
| 391 NS_ASSERT (ok == true); |
| 392 |
| 393 ok = m_tcb->TraceConnectWithoutContext ("EcnState", |
| 394 MakeCallback (&TcpSocketBase::UpdateEc
nState, this)); |
371 NS_ASSERT (ok == true); | 395 NS_ASSERT (ok == true); |
372 | 396 |
373 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", | 397 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", |
374 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); | 398 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); |
375 NS_ASSERT (ok == true); | 399 NS_ASSERT (ok == true); |
376 | 400 |
377 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", | 401 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", |
378 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); | 402 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); |
379 NS_ASSERT (ok == true); | 403 NS_ASSERT (ok == true); |
380 } | 404 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 m_sndWindShift (sock.m_sndWindShift), | 445 m_sndWindShift (sock.m_sndWindShift), |
422 m_timestampEnabled (sock.m_timestampEnabled), | 446 m_timestampEnabled (sock.m_timestampEnabled), |
423 m_timestampToEcho (sock.m_timestampToEcho), | 447 m_timestampToEcho (sock.m_timestampToEcho), |
424 m_recover (sock.m_recover), | 448 m_recover (sock.m_recover), |
425 m_retxThresh (sock.m_retxThresh), | 449 m_retxThresh (sock.m_retxThresh), |
426 m_limitedTx (sock.m_limitedTx), | 450 m_limitedTx (sock.m_limitedTx), |
427 m_isFirstPartialAck (sock.m_isFirstPartialAck), | 451 m_isFirstPartialAck (sock.m_isFirstPartialAck), |
428 m_txTrace (sock.m_txTrace), | 452 m_txTrace (sock.m_txTrace), |
429 m_rxTrace (sock.m_rxTrace), | 453 m_rxTrace (sock.m_rxTrace), |
430 m_ecn (sock.m_ecn), | 454 m_ecn (sock.m_ecn), |
431 m_ecnState (sock.m_ecnState), | |
432 m_ecnEchoSeq (sock.m_ecnEchoSeq), | 455 m_ecnEchoSeq (sock.m_ecnEchoSeq), |
433 m_ecnCWRSeq (sock.m_ecnCWRSeq)···· | 456 m_ecnCWRSeq (sock.m_ecnCWRSeq)···· |
434 { | 457 { |
435 NS_LOG_FUNCTION (this); | 458 NS_LOG_FUNCTION (this); |
436 NS_LOG_LOGIC ("Invoked the copy constructor"); | 459 NS_LOG_LOGIC ("Invoked the copy constructor"); |
437 // Copy the rtt estimator if it is set | 460 // Copy the rtt estimator if it is set |
438 if (sock.m_rtt) | 461 if (sock.m_rtt) |
439 { | 462 { |
440 m_rtt = sock.m_rtt->Copy (); | 463 m_rtt = sock.m_rtt->Copy (); |
441 } | 464 } |
(...skipping 20 matching lines...) Expand all Loading... |
462 NS_ASSERT (ok == true); | 485 NS_ASSERT (ok == true); |
463 | 486 |
464 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", | 487 ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", |
465 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); | 488 MakeCallback (&TcpSocketBase::UpdateSs
Thresh, this)); |
466 NS_ASSERT (ok == true); | 489 NS_ASSERT (ok == true); |
467 | 490 |
468 ok = m_tcb->TraceConnectWithoutContext ("CongState", | 491 ok = m_tcb->TraceConnectWithoutContext ("CongState", |
469 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); | 492 MakeCallback (&TcpSocketBase::UpdateCo
ngState, this)); |
470 NS_ASSERT (ok == true); | 493 NS_ASSERT (ok == true); |
471 | 494 |
| 495 ok = m_tcb->TraceConnectWithoutContext ("EcnState", |
| 496 MakeCallback (&TcpSocketBase::UpdateEc
nState, this)); |
| 497 NS_ASSERT (ok == true); |
| 498 |
472 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", | 499 ok = m_tcb->TraceConnectWithoutContext ("NextTxSequence", |
473 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); | 500 MakeCallback (&TcpSocketBase::UpdateNe
xtTxSequence, this)); |
474 NS_ASSERT (ok == true); | 501 NS_ASSERT (ok == true); |
475 | 502 |
476 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", | 503 ok = m_tcb->TraceConnectWithoutContext ("HighestSequence", |
477 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); | 504 MakeCallback (&TcpSocketBase::UpdateHi
ghTxMark, this)); |
478 NS_ASSERT (ok == true); | 505 NS_ASSERT (ok == true); |
479 } | 506 } |
480 | 507 |
481 TcpSocketBase::~TcpSocketBase (void) | 508 TcpSocketBase::~TcpSocketBase (void) |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 if (m_ecn) | 1103 if (m_ecn) |
1077 { | 1104 { |
1078 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR); | 1105 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR); |
1079 } | 1106 } |
1080 else | 1107 else |
1081 { | 1108 { |
1082 SendEmptyPacket (TcpHeader::SYN); | 1109 SendEmptyPacket (TcpHeader::SYN); |
1083 } | 1110 } |
1084 NS_LOG_DEBUG (TcpStateName[m_state] << " -> SYN_SENT"); | 1111 NS_LOG_DEBUG (TcpStateName[m_state] << " -> SYN_SENT"); |
1085 m_state = SYN_SENT; | 1112 m_state = SYN_SENT; |
1086 m_ecnState = ECN_DISABLED; // because sender is not yet aware about rec
eiver's ECN capability· | 1113 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; // because sender is
not yet aware about receiver's ECN capability· |
1087 } | 1114 } |
1088 else if (m_state != TIME_WAIT) | 1115 else if (m_state != TIME_WAIT) |
1089 { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, a
n connection | 1116 { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, a
n connection |
1090 // exists. We send RST, tear down everything, and close this socket. | 1117 // exists. We send RST, tear down everything, and close this socket. |
1091 SendRST (); | 1118 SendRST (); |
1092 CloseAndNotify (); | 1119 CloseAndNotify (); |
1093 } | 1120 } |
1094 return 0; | 1121 return 0; |
1095 } | 1122 } |
1096 | 1123 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 ":" << m_endPoint->GetLocalPort ()); | 1215 ":" << m_endPoint->GetLocalPort ()); |
1189 | 1216 |
1190 Address fromAddress = InetSocketAddress (header.GetSource (), port); | 1217 Address fromAddress = InetSocketAddress (header.GetSource (), port); |
1191 Address toAddress = InetSocketAddress (header.GetDestination (), | 1218 Address toAddress = InetSocketAddress (header.GetDestination (), |
1192 m_endPoint->GetLocalPort ()); | 1219 m_endPoint->GetLocalPort ()); |
1193 TcpHeader tcpHeader; | 1220 TcpHeader tcpHeader; |
1194 packet->PeekHeader (tcpHeader); | 1221 packet->PeekHeader (tcpHeader); |
1195 if (header.GetEcn() == Ipv4Header::ECN_CE && m_ecnCESeq < tcpHeader.GetAckNumb
er ()) | 1222 if (header.GetEcn() == Ipv4Header::ECN_CE && m_ecnCESeq < tcpHeader.GetAckNumb
er ()) |
1196 { | 1223 { |
1197 NS_LOG_INFO ("Received CE flag is valid"); | 1224 NS_LOG_INFO ("Received CE flag is valid"); |
1198 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_CE_RCVD"); | 1225 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
CE_RCVD"); |
1199 m_ecnCESeq = tcpHeader.GetAckNumber (); | 1226 m_ecnCESeq = tcpHeader.GetAckNumber (); |
1200 m_ecnState = ECN_CE_RCVD;· | 1227 m_tcb->m_ecnState = TcpSocketState::ECN_CE_RCVD;· |
1201 } | 1228 } |
1202 DoForwardUp (packet, fromAddress, toAddress); | 1229 DoForwardUp (packet, fromAddress, toAddress); |
1203 } | 1230 } |
1204 | 1231 |
1205 void | 1232 void |
1206 TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, | 1233 TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, |
1207 Ptr<Ipv6Interface> incomingInterface) | 1234 Ptr<Ipv6Interface> incomingInterface) |
1208 { | 1235 { |
1209 NS_LOG_LOGIC ("Socket " << this << " forward up " << | 1236 NS_LOG_LOGIC ("Socket " << this << " forward up " << |
1210 m_endPoint6->GetPeerAddress () << | 1237 m_endPoint6->GetPeerAddress () << |
1211 ":" << m_endPoint6->GetPeerPort () << | 1238 ":" << m_endPoint6->GetPeerPort () << |
1212 " to " << m_endPoint6->GetLocalAddress () << | 1239 " to " << m_endPoint6->GetLocalAddress () << |
1213 ":" << m_endPoint6->GetLocalPort ()); | 1240 ":" << m_endPoint6->GetLocalPort ()); |
1214 | 1241 |
1215 Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port); | 1242 Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port); |
1216 Address toAddress = Inet6SocketAddress (header.GetDestinationAddress (), | 1243 Address toAddress = Inet6SocketAddress (header.GetDestinationAddress (), |
1217 m_endPoint6->GetLocalPort ()); | 1244 m_endPoint6->GetLocalPort ()); |
1218 | 1245 |
1219 TcpHeader tcpHeader; | 1246 TcpHeader tcpHeader; |
1220 packet->PeekHeader (tcpHeader); | 1247 packet->PeekHeader (tcpHeader); |
1221 if (header.GetEcn() == Ipv6Header::ECN_CE && m_ecnCESeq < tcpHeader.GetAckNumb
er ()) | 1248 if (header.GetEcn() == Ipv6Header::ECN_CE && m_ecnCESeq < tcpHeader.GetAckNumb
er ()) |
1222 { | 1249 { |
1223 NS_LOG_INFO ("Received CE flag is valid"); | 1250 NS_LOG_INFO ("Received CE flag is valid"); |
1224 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_CE_RCVD"); | 1251 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
CE_RCVD"); |
1225 m_ecnCESeq = tcpHeader.GetAckNumber (); | 1252 m_ecnCESeq = tcpHeader.GetAckNumber (); |
1226 m_ecnState = ECN_CE_RCVD;·· | 1253 m_tcb->m_ecnState = TcpSocketState::ECN_CE_RCVD;·· |
1227 } | 1254 } |
1228 DoForwardUp (packet, fromAddress, toAddress); | 1255 DoForwardUp (packet, fromAddress, toAddress); |
1229 } | 1256 } |
1230 | 1257 |
1231 void | 1258 void |
1232 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, | 1259 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, |
1233 uint8_t icmpType, uint8_t icmpCode, | 1260 uint8_t icmpType, uint8_t icmpCode, |
1234 uint32_t icmpInfo) | 1261 uint32_t icmpInfo) |
1235 { | 1262 { |
1236 NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType
<< | 1263 NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType
<< |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 m_rxBuffer->MaxRxSequence () << ")"); | 1308 m_rxBuffer->MaxRxSequence () << ")"); |
1282 // Acknowledgement should be sent for all unacceptable packets (RFC793, p.
69) | 1309 // Acknowledgement should be sent for all unacceptable packets (RFC793, p.
69) |
1283 if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST)) | 1310 if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST)) |
1284 { | 1311 { |
1285 // Check if the sender has responded to ECN echo by reducing the Conge
stion Window | 1312 // Check if the sender has responded to ECN echo by reducing the Conge
stion Window |
1286 if (tcpHeader.GetFlags () & TcpHeader::CWR ) | 1313 if (tcpHeader.GetFlags () & TcpHeader::CWR ) |
1287 { | 1314 { |
1288 // 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· | 1315 // 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· |
1289 // stop sending ECN Echo messages. If there is CE bit set, the pac
ket should continue sending ECN Echo messages | 1316 // stop sending ECN Echo messages. If there is CE bit set, the pac
ket should continue sending ECN Echo messages |
1290 // | 1317 // |
1291 if (m_ecnState != ECN_CE_RCVD)· | 1318 if (m_tcb->m_ecnState != TcpSocketState::ECN_CE_RCVD)· |
1292 { | 1319 { |
1293 m_ecnState = ECN_IDLE; | 1320 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
1294 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_IDLE"); | 1321 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState]
<< " -> ECN_IDLE"); |
1295 } | 1322 } |
1296 } | 1323 } |
1297 if (m_ecnState == ECN_CE_RCVD || m_ecnState == ECN_ECE_SENT) | 1324 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnSt
ate == TcpSocketState::ECN_ECE_SENT) |
1298 { | 1325 { |
1299 // 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 | 1326 // 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 |
1300 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | 1327 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
1301 m_ecnState = ECN_ECE_SENT;·· | 1328 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT;·· |
1302 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_ECE_SENT"); | 1329 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_SENT"); |
1303 } | 1330 } |
1304 else | 1331 else |
1305 { | 1332 { |
1306 SendEmptyPacket (TcpHeader::ACK); | 1333 SendEmptyPacket (TcpHeader::ACK); |
1307 } | 1334 } |
1308 } | 1335 } |
1309 return; | 1336 return; |
1310 } | 1337 } |
1311 | 1338 |
1312 m_rxTrace (packet, tcpHeader, this); | 1339 m_rxTrace (packet, tcpHeader, this); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1429 break; | 1456 break; |
1430 case TIME_WAIT: | 1457 case TIME_WAIT: |
1431 // Do nothing | 1458 // Do nothing |
1432 break; | 1459 break; |
1433 case CLOSED: | 1460 case CLOSED: |
1434 // Send RST if the incoming packet is not a RST | 1461 // Send RST if the incoming packet is not a RST |
1435 if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHea
der::RST) | 1462 if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHea
der::RST) |
1436 { // Since m_endPoint is not configured yet, we cannot use SendRST here | 1463 { // Since m_endPoint is not configured yet, we cannot use SendRST here |
1437 TcpHeader h; | 1464 TcpHeader h; |
1438 Ptr<Packet> p = Create<Packet> (); | 1465 Ptr<Packet> p = Create<Packet> (); |
1439 // Send a packet tag for setting ECT bits in IP header | |
1440 if (m_ecnState != ECN_DISABLED ) | |
1441 { | |
1442 SocketIpTosTag ipTosTag; | |
1443 ipTosTag.SetTos (0x02); | |
1444 p->AddPacketTag (ipTosTag); | |
1445 SocketIpv6TclassTag ipTclassTag; | |
1446 ipTclassTag.SetTclass (0x02); | |
1447 p->AddPacketTag (ipTclassTag); | |
1448 } | |
1449 h.SetFlags (TcpHeader::RST); | 1466 h.SetFlags (TcpHeader::RST); |
1450 h.SetSequenceNumber (m_tcb->m_nextTxSequence); | 1467 h.SetSequenceNumber (m_tcb->m_nextTxSequence); |
1451 h.SetAckNumber (m_rxBuffer->NextRxSequence ()); | 1468 h.SetAckNumber (m_rxBuffer->NextRxSequence ()); |
1452 h.SetSourcePort (tcpHeader.GetDestinationPort ()); | 1469 h.SetSourcePort (tcpHeader.GetDestinationPort ()); |
1453 h.SetDestinationPort (tcpHeader.GetSourcePort ()); | 1470 h.SetDestinationPort (tcpHeader.GetSourcePort ()); |
1454 h.SetWindowSize (AdvertisedWindowSize ()); | 1471 h.SetWindowSize (AdvertisedWindowSize ()); |
1455 AddOptions (h); | 1472 AddOptions (h); |
1456 m_txTrace (p, h, this); | 1473 m_txTrace (p, h, this); |
1457 m_tcp->SendPacket (p, h, toAddress, fromAddress, m_boundnetdevice); | 1474 m_tcp->SendPacket (p, h, toAddress, fromAddress, m_boundnetdevice); |
1458 } | 1475 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 } | 1529 } |
1513 else if (tcpHeader.GetAckNumber () > m_tcb->m_highTxMark) | 1530 else if (tcpHeader.GetAckNumber () > m_tcb->m_highTxMark) |
1514 { | 1531 { |
1515 // If the ACK acks something not yet sent (SEG.ACK > HighTxMark) then | 1532 // If the ACK acks something not yet sent (SEG.ACK > HighTxMark) then |
1516 // send an ACK, drop the segment, and return. | 1533 // send an ACK, drop the segment, and return. |
1517 // Pag. 72 RFC 793 | 1534 // Pag. 72 RFC 793 |
1518 NS_LOG_WARN ("Ignored ack of " << tcpHeader.GetAckNumber () << | 1535 NS_LOG_WARN ("Ignored ack of " << tcpHeader.GetAckNumber () << |
1519 " HighTxMark = " << m_tcb->m_highTxMark); | 1536 " HighTxMark = " << m_tcb->m_highTxMark); |
1520 | 1537 |
1521 // Receiver sets ECE flags when it receives a packet with CE bit on or
sender hasn’t responded to ECN echo sent by receiver | 1538 // Receiver sets ECE flags when it receives a packet with CE bit on or
sender hasn’t responded to ECN echo sent by receiver |
1522 if (m_ecnState == ECN_CE_RCVD || m_ecnState == ECN_ECE_SENT) | 1539 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnSt
ate == TcpSocketState::ECN_ECE_SENT) |
1523 { | 1540 { |
1524 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | 1541 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
1525 m_ecnState = ECN_ECE_SENT; | 1542 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
1526 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_ECE_SENT"); | 1543 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_SENT"); |
1527 } | 1544 } |
1528 else | 1545 else |
1529 { | 1546 { |
1530 SendEmptyPacket (TcpHeader::ACK); | 1547 SendEmptyPacket (TcpHeader::ACK); |
1531 } | 1548 } |
1532 } | 1549 } |
1533 else | 1550 else |
1534 { | 1551 { |
1535 // SND.UNA < SEG.ACK =< HighTxMark | 1552 // SND.UNA < SEG.ACK =< HighTxMark |
1536 // Pag. 72 RFC 793 | 1553 // Pag. 72 RFC 793 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 NS_ASSERT (m_tcb->m_segmentSize > 0); | 1755 NS_ASSERT (m_tcb->m_segmentSize > 0); |
1739 | 1756 |
1740 // RFC 6675, Section 5, 1st paragraph: | 1757 // RFC 6675, Section 5, 1st paragraph: |
1741 // Upon the receipt of any ACK containing SACK information, the | 1758 // Upon the receipt of any ACK containing SACK information, the |
1742 // scoreboard MUST be updated via the Update () routine (done in ReadOptions) | 1759 // scoreboard MUST be updated via the Update () routine (done in ReadOptions) |
1743 bool scoreboardUpdated = false; | 1760 bool scoreboardUpdated = false; |
1744 ReadOptions (tcpHeader, scoreboardUpdated); | 1761 ReadOptions (tcpHeader, scoreboardUpdated); |
1745 | 1762 |
1746 SequenceNumber32 ackNumber = tcpHeader.GetAckNumber (); | 1763 SequenceNumber32 ackNumber = tcpHeader.GetAckNumber (); |
1747 | 1764 |
1748 if (ackNumber > m_txBuffer->HeadSequence () && (m_ecnState != ECN_DISABLED) &&
(tcpHeader.GetFlags () & TcpHeader::ECE)) | 1765 if (ackNumber > m_txBuffer->HeadSequence () && (m_tcb->m_ecnState != TcpSocket
State::ECN_DISABLED) && (tcpHeader.GetFlags () & TcpHeader::ECE)) |
1749 { | 1766 { |
1750 if (m_ecnEchoSeq < tcpHeader.GetAckNumber ()) | 1767 if (m_ecnEchoSeq < tcpHeader.GetAckNumber ()) |
1751 { | 1768 { |
1752 NS_LOG_INFO ("Received ECN Echo is valid"); | 1769 NS_LOG_INFO ("Received ECN Echo is valid"); |
1753 m_ecnEchoSeq = tcpHeader.GetAckNumber (); | 1770 m_ecnEchoSeq = tcpHeader.GetAckNumber (); |
1754 m_ecnState = ECN_ECE_RCVD; | 1771 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_RCVD; |
1755 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_ECE_RCVD"); | 1772 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_RCVD"); |
1756 } | 1773 } |
1757 } | 1774 } |
1758 | 1775 |
1759 // RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation | 1776 // RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation |
1760 // are inside the function ProcessAck | 1777 // are inside the function ProcessAck |
1761 ProcessAck (ackNumber, scoreboardUpdated); | 1778 ProcessAck (ackNumber, scoreboardUpdated); |
1762 | 1779 |
1763 // RFC 6675, Section 5, point (C), try to send more data. NB: (C) is implement
ed | 1780 // RFC 6675, Section 5, point (C), try to send more data. NB: (C) is implement
ed |
1764 // inside SendPendingData | 1781 // inside SendPendingData |
1765 SendPendingData (m_connected); | 1782 SendPendingData (m_connected); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1842 else if (ackNumber > m_txBuffer->HeadSequence ()) | 1859 else if (ackNumber > m_txBuffer->HeadSequence ()) |
1843 { | 1860 { |
1844 uint32_t bytesAcked = ackNumber - m_txBuffer->HeadSequence (); | 1861 uint32_t bytesAcked = ackNumber - m_txBuffer->HeadSequence (); |
1845 uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; | 1862 uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; |
1846 m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; | 1863 m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; |
1847 | 1864 |
1848 if (m_bytesAckedNotProcessed >= m_tcb->m_segmentSize) | 1865 if (m_bytesAckedNotProcessed >= m_tcb->m_segmentSize) |
1849 { | 1866 { |
1850 segsAcked += 1; | 1867 segsAcked += 1; |
1851 m_bytesAckedNotProcessed -= m_tcb->m_segmentSize; | 1868 m_bytesAckedNotProcessed -= m_tcb->m_segmentSize; |
1852 } | 1869 } |
1853 | 1870 |
1854 // RFC 6675, Section 5, part (B) | 1871 // RFC 6675, Section 5, part (B) |
1855 // (B) Upon receipt of an ACK that does not cover RecoveryPoint, the | 1872 // (B) Upon receipt of an ACK that does not cover RecoveryPoint, the |
1856 // following actions MUST be taken: | 1873 // following actions MUST be taken: |
1857 // | 1874 // |
1858 // (B.1) Use Update () to record the new SACK information conveyed | 1875 // (B.1) Use Update () to record the new SACK information conveyed |
1859 // by the incoming ACK. | 1876 // by the incoming ACK. |
1860 // (B.2) Use SetPipe () to re-calculate the number of octets still | 1877 // (B.2) Use SetPipe () to re-calculate the number of octets still |
1861 // in the network. | 1878 // in the network. |
1862 // | 1879 // |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2041 m_synCount = m_synRetries; | 2058 m_synCount = m_synRetries; |
2042 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); | 2059 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); |
2043 | 2060 |
2044 /* 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· | 2061 /* 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· |
2045 * sender has sent ECN SYN packet | 2062 * sender has sent ECN SYN packet |
2046 */ | 2063 */ |
2047 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::CWR | TcpHeader::ECE)) | 2064 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::CWR | TcpHeader::ECE)) |
2048 { | 2065 { |
2049 NS_LOG_INFO ("Received ECN SYN packet"); | 2066 NS_LOG_INFO ("Received ECN SYN packet"); |
2050 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK | TcpHeader::ECE); | 2067 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK | TcpHeader::ECE); |
2051 m_ecnState = ECN_IDLE; | 2068 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
2052 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_IDLE"); | 2069 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_IDLE"); |
2053 } | 2070 } |
2054 else | 2071 else |
2055 { | 2072 { |
2056 m_ecnState = ECN_DISABLED; | 2073 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
2057 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);···· | 2074 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);···· |
2058 } | 2075 } |
2059 } | 2076 } |
2060 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK) | 2077 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK) |
2061 && m_tcb->m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAck
Number ()) | 2078 && m_tcb->m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAck
Number ()) |
2062 { // Handshake completed | 2079 { // Handshake completed |
2063 NS_LOG_DEBUG ("SYN_SENT -> ESTABLISHED"); | 2080 NS_LOG_DEBUG ("SYN_SENT -> ESTABLISHED"); |
2064 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); | 2081 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN); |
2065 m_state = ESTABLISHED; | 2082 m_state = ESTABLISHED; |
2066 m_connected = true; | 2083 m_connected = true; |
2067 m_retxEvent.Cancel (); | 2084 m_retxEvent.Cancel (); |
2068 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); | 2085 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); |
2069 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; | 2086 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; |
2070 m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence); | 2087 m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence); |
2071 SendEmptyPacket (TcpHeader::ACK); | 2088 SendEmptyPacket (TcpHeader::ACK); |
2072 | 2089 |
2073 /* 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· | 2090 /* 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· |
2074 * packet and the traffic is ECN Capable | 2091 * packet and the traffic is ECN Capable |
2075 */ | 2092 */ |
2076 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::ECE)) | 2093 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::ECE)) |
2077 { | 2094 { |
2078 NS_LOG_INFO ("Received ECN SYN-ACK packet."); | 2095 NS_LOG_INFO ("Received ECN SYN-ACK packet."); |
2079 m_ecnState = ECN_IDLE; | 2096 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
2080 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_IDLE"); | 2097 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_IDLE"); |
2081 } | 2098 } |
2082 else | 2099 else |
2083 { | 2100 { |
2084 m_ecnState = ECN_DISABLED; | 2101 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
2085 } | 2102 } |
2086 | 2103 |
2087 SendPendingData (m_connected); | 2104 SendPendingData (m_connected); |
2088 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); | 2105 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); |
2089 // Always respond to first data packet to speed up the connection. | 2106 // Always respond to first data packet to speed up the connection. |
2090 // Remove to get the behaviour of old NS-3 code. | 2107 // Remove to get the behaviour of old NS-3 code. |
2091 m_delAckCount = m_delAckMaxCount; | 2108 m_delAckCount = m_delAckMaxCount; |
2092 } | 2109 } |
2093 else | 2110 else |
2094 { // Other in-sequence input | 2111 { // Other in-sequence input |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2150 { // Probably the peer lost my SYN+ACK | 2167 { // Probably the peer lost my SYN+ACK |
2151 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); | 2168 m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNu
mber32 (1)); |
2152 | 2169 |
2153 /* 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· | 2170 /* 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· |
2154 * packet and the traffic is ECN Capable | 2171 * packet and the traffic is ECN Capable |
2155 */ | 2172 */ |
2156 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::CWR | TcpHeader::ECE)) | 2173 if (m_ecn && (tcpHeader.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) =
= (TcpHeader::CWR | TcpHeader::ECE)) |
2157 { | 2174 { |
2158 NS_LOG_INFO ("Received ECN SYN packet"); | 2175 NS_LOG_INFO ("Received ECN SYN packet"); |
2159 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK |TcpHeader::ECE); | 2176 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK |TcpHeader::ECE); |
2160 m_ecnState = ECN_IDLE; | 2177 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
2161 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_IDLE"); | 2178 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_IDLE"); |
2162 } | 2179 } |
2163 else | 2180 else |
2164 { | 2181 { |
2165 m_ecnState = ECN_DISABLED; | 2182 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
2166 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 2183 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); |
2167 } | 2184 } |
2168 } | 2185 } |
2169 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK)) | 2186 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK)) |
2170 { | 2187 { |
2171 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) | 2188 if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ()) |
2172 { // In-sequence FIN before connection complete. Set up connection and c
lose. | 2189 { // In-sequence FIN before connection complete. Set up connection and c
lose. |
2173 m_connected = true; | 2190 m_connected = true; |
2174 m_retxEvent.Cancel (); | 2191 m_retxEvent.Cancel (); |
2175 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; | 2192 m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence; |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2746 SetupCallback (); | 2763 SetupCallback (); |
2747 // Set the sequence number and send SYN+ACK | 2764 // Set the sequence number and send SYN+ACK |
2748 m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1)); | 2765 m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1)); |
2749 | 2766 |
2750 /* Check if we received an ECN SYN packet. Change the ECN state of receiver to
ECN_IDLE if sender has sent an ECN SYN· | 2767 /* Check if we received an ECN SYN packet. Change the ECN state of receiver to
ECN_IDLE if sender has sent an ECN SYN· |
2751 * packet and the traffic is ECN Capable | 2768 * packet and the traffic is ECN Capable |
2752 */ | 2769 */ |
2753 if (m_ecn && (h.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader
::CWR | TcpHeader::ECE)) | 2770 if (m_ecn && (h.GetFlags () & (TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader
::CWR | TcpHeader::ECE)) |
2754 { | 2771 { |
2755 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK | TcpHeader::ECE); | 2772 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK | TcpHeader::ECE); |
2756 m_ecnState = ECN_IDLE; | 2773 m_tcb->m_ecnState = TcpSocketState::ECN_IDLE; |
2757 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_IDLE"); | 2774 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
IDLE"); |
2758 } | 2775 } |
2759 else | 2776 else |
2760 { | 2777 { |
2761 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 2778 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); |
2762 m_ecnState = ECN_DISABLED; | 2779 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
2763 }·· | 2780 }·· |
2764 } | 2781 } |
2765 | 2782 |
2766 void | 2783 void |
2767 TcpSocketBase::ConnectionSucceeded () | 2784 TcpSocketBase::ConnectionSucceeded () |
2768 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can | 2785 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can |
2769 // be called as a scheduled event | 2786 // be called as a scheduled event |
2770 NotifyConnectionSucceeded (); | 2787 NotifyConnectionSucceeded (); |
2771 // The if-block below was moved from ProcessSynSent() to here because we need | 2788 // The if-block below was moved from ProcessSynSent() to here because we need |
2772 // to invoke the NotifySend() only after NotifyConnectionSucceeded() to | 2789 // to invoke the NotifySend() only after NotifyConnectionSucceeded() to |
(...skipping 22 matching lines...) Expand all Loading... |
2795 uint8_t flags = withAck ? TcpHeader::ACK : 0; | 2812 uint8_t flags = withAck ? TcpHeader::ACK : 0; |
2796 uint32_t remainingData = m_txBuffer->SizeFromSequence (seq + SequenceNumber32
(sz)); | 2813 uint32_t remainingData = m_txBuffer->SizeFromSequence (seq + SequenceNumber32
(sz)); |
2797 | 2814 |
2798 if (withAck) | 2815 if (withAck) |
2799 { | 2816 { |
2800 m_delAckEvent.Cancel (); | 2817 m_delAckEvent.Cancel (); |
2801 m_delAckCount = 0; | 2818 m_delAckCount = 0; |
2802 } | 2819 } |
2803 | 2820 |
2804 // Sender should reduce the Congestion Window as a response to receiver's ECN
Echo notification only once per window· | 2821 // Sender should reduce the Congestion Window as a response to receiver's ECN
Echo notification only once per window· |
2805 if (m_ecnState == ECN_ECE_RCVD && m_ecnEchoSeq.Get() > m_ecnCWRSeq.Get())· | 2822 if (m_tcb->m_ecnState == TcpSocketState::ECN_ECE_RCVD && m_ecnEchoSeq.Get() >
m_ecnCWRSeq.Get() && !isRetransmission )· |
2806 { | 2823 { |
2807 NS_LOG_INFO ("Backoff mechanism by reducing CWND by half because we've re
ceived ECN Echo"); | 2824 NS_LOG_INFO ("Backoff mechanism by reducing CWND by half because we've re
ceived ECN Echo"); |
2808 m_tcb->m_ssThresh = m_congestionControl->GetSsThresh (m_tcb, BytesInFlight
());·· | 2825 m_tcb->m_ssThresh = m_congestionControl->GetSsThresh (m_tcb, BytesInFlight
());·· |
2809 m_tcb->m_cWnd = std::max ((uint32_t)m_tcb->m_cWnd/2, m_tcb->m_segmentSize)
; | 2826 m_tcb->m_cWnd = std::max ((uint32_t)m_tcb->m_cWnd/2, m_tcb->m_segmentSize)
; |
2810 flags |= TcpHeader::CWR;· | 2827 flags |= TcpHeader::CWR;· |
2811 m_ecnCWRSeq = seq; | 2828 m_ecnCWRSeq = seq; |
2812 m_ecnState = ECN_CWR_SENT; | 2829 m_tcb->m_ecnState = TcpSocketState::ECN_CWR_SENT; |
2813 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_CWR_SENT"); | 2830 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " -> ECN_
CWR_SENT"); |
2814 NS_LOG_INFO ("CWR flags set"); | 2831 NS_LOG_INFO ("CWR flags set"); |
2815 NS_LOG_DEBUG (TcpSocketState::TcpCongStateName[m_tcb->m_congState] << " ->
CA_CWR"); | 2832 NS_LOG_DEBUG (TcpSocketState::TcpCongStateName[m_tcb->m_congState] << " ->
CA_CWR"); |
2816 if (m_tcb->m_congState == TcpSocketState::CA_OPEN) | 2833 if (m_tcb->m_congState == TcpSocketState::CA_OPEN) |
2817 { | 2834 { |
2818 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_CWR
); | 2835 m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_CWR
); |
2819 m_tcb->m_congState = TcpSocketState::CA_CWR; | 2836 m_tcb->m_congState = TcpSocketState::CA_CWR; |
2820 } | 2837 } |
2821 } | 2838 } |
2822 | 2839 |
2823 /* | 2840 /* |
2824 * Add tags for each socket option. | 2841 * Add tags for each socket option. |
2825 * Note that currently the socket adds both IPv4 tag and IPv6 tag | 2842 * Note that currently the socket adds both IPv4 tag and IPv6 tag |
2826 * if both options are set. Once the packet got to layer three, only | 2843 * if both options are set. Once the packet got to layer three, only |
2827 * the corresponding tags will be read. | 2844 * the corresponding tags will be read. |
2828 */ | 2845 */ |
2829 if (GetIpTos ()) | 2846 if (GetIpTos ()) |
2830 { | 2847 { |
2831 SocketIpTosTag ipTosTag; | 2848 SocketIpTosTag ipTosTag; |
2832 NS_LOG_LOGIC (" ECT bits should not be set on retransmitted packets "); | 2849 NS_LOG_LOGIC (" ECT bits should not be set on retransmitted packets "); |
2833 if (m_ecnState != ECN_DISABLED && (GetIpTos () & 0x3) == 0 && !isRetransmi
ssion) | 2850 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && (GetIpTos () & 0x
3) == 0 && !isRetransmission) |
2834 {· | 2851 {· |
2835 ipTosTag.SetTos (GetIpTos () | 0x2); | 2852 ipTosTag.SetTos (GetIpTos () | 0x2); |
2836 } | 2853 } |
2837 else | 2854 else |
2838 { | 2855 { |
2839 ipTosTag.SetTos (GetIpTos ()); | 2856 ipTosTag.SetTos (GetIpTos ()); |
2840 } | 2857 } |
2841 p->AddPacketTag (ipTosTag); | 2858 p->AddPacketTag (ipTosTag); |
2842 } | 2859 } |
2843 else | 2860 else |
2844 { | 2861 { |
2845 if (m_ecnState != ECN_DISABLED && !isRetransmission) | 2862 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && !isRetransmission
) |
2846 { | 2863 { |
2847 SocketIpTosTag ipTosTag; | 2864 SocketIpTosTag ipTosTag; |
2848 ipTosTag.SetTos (0x02); | 2865 ipTosTag.SetTos (0x02); |
2849 p->AddPacketTag (ipTosTag); | 2866 p->AddPacketTag (ipTosTag); |
2850 } | 2867 } |
2851 } | 2868 } |
2852 | 2869 |
2853 if (IsManualIpv6Tclass ()) | 2870 if (IsManualIpv6Tclass ()) |
2854 { | 2871 { |
2855 SocketIpv6TclassTag ipTclassTag; | 2872 SocketIpv6TclassTag ipTclassTag; |
2856 if (m_ecnState != ECN_DISABLED && (GetIpv6Tclass () & 0x3) == 0 && !isRetr
ansmission) | 2873 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && (GetIpv6Tclass ()
& 0x3) == 0 && !isRetransmission) |
2857 { | 2874 { |
2858 ipTclassTag.SetTclass (GetIpv6Tclass () | 0x2); | 2875 ipTclassTag.SetTclass (GetIpv6Tclass () | 0x2); |
2859 } | 2876 } |
2860 else | 2877 else |
2861 { | 2878 { |
2862 ipTclassTag.SetTclass (GetIpv6Tclass ()); | 2879 ipTclassTag.SetTclass (GetIpv6Tclass ()); |
2863 } | 2880 } |
2864 p->AddPacketTag (ipTclassTag); | 2881 p->AddPacketTag (ipTclassTag); |
2865 } | 2882 } |
2866 else | 2883 else |
2867 { | 2884 { |
2868 if (m_ecnState != ECN_DISABLED && !isRetransmission) | 2885 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && !isRetransmission
) |
2869 { | 2886 { |
2870 SocketIpv6TclassTag ipTclassTag; | 2887 SocketIpv6TclassTag ipTclassTag; |
2871 ipTclassTag.SetTclass (0x02); | 2888 ipTclassTag.SetTclass (0x02); |
2872 p->AddPacketTag (ipTclassTag); | 2889 p->AddPacketTag (ipTclassTag); |
2873 } | 2890 } |
2874 } | 2891 } |
2875 | 2892 |
2876 if (IsManualIpTtl ()) | 2893 if (IsManualIpTtl ()) |
2877 { | 2894 { |
2878 SocketIpTtlTag ipTtlTag; | 2895 SocketIpTtlTag ipTtlTag; |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3160 } | 3177 } |
3161 | 3178 |
3162 NS_LOG_DEBUG ("InFlight=" << inflight << ", Win=" << win << " availWin=" << wi
n-inflight); | 3179 NS_LOG_DEBUG ("InFlight=" << inflight << ", Win=" << win << " availWin=" << wi
n-inflight); |
3163 return win - inflight; | 3180 return win - inflight; |
3164 } | 3181 } |
3165 | 3182 |
3166 uint16_t | 3183 uint16_t |
3167 TcpSocketBase::AdvertisedWindowSize (bool scale) const | 3184 TcpSocketBase::AdvertisedWindowSize (bool scale) const |
3168 { | 3185 { |
3169 NS_LOG_FUNCTION (this << scale); | 3186 NS_LOG_FUNCTION (this << scale); |
3170 uint32_t w = m_rxBuffer->MaxBufferSize (); | 3187 uint32_t w = (m_rxBuffer->MaxRxSequence () > m_rxBuffer->NextRxSequence ()) ? |
3171 | 3188 m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence () : 0; |
| 3189 |
| 3190 // We don't want to advertise 0 after a FIN is received. So, we just use |
| 3191 // the previous value of the advWnd. |
| 3192 if (m_rxBuffer->Finished ()) |
| 3193 { |
| 3194 w = m_advWnd; |
| 3195 } |
| 3196 |
| 3197 // Ugly, but we are not modifying the state, that variable |
| 3198 // is used only for tracing purpose. |
| 3199 if (w != m_advWnd) |
| 3200 { |
| 3201 const_cast<TcpSocketBase*> (this)->m_advWnd = w; |
| 3202 } |
3172 if (scale) | 3203 if (scale) |
3173 { | 3204 { |
3174 w >>= m_rcvWindShift; | 3205 w >>= m_rcvWindShift; |
3175 } | 3206 } |
3176 if (w > m_maxWinSize) | 3207 if (w > m_maxWinSize) |
3177 { | 3208 { |
3178 w = m_maxWinSize; | 3209 w = m_maxWinSize; |
3179 NS_LOG_WARN ("Adv window size truncated to " << m_maxWinSize << "; possibl
y to avoid overflow of the 16-bit integer"); | 3210 NS_LOG_WARN ("Adv window size truncated to " << m_maxWinSize << "; possibl
y to avoid overflow of the 16-bit integer"); |
3180 } | 3211 } |
3181 NS_LOG_INFO ("Returning AdvertisedWindowSize of " << static_cast<uint16_t> (w)
); | 3212 NS_LOG_INFO ("Returning AdvertisedWindowSize of " << static_cast<uint16_t> (w)
); |
3182 return static_cast<uint16_t> (w); | 3213 return static_cast<uint16_t> (w); |
3183 } | 3214 } |
3184 | 3215 |
3185 // Receipt of new packet, put into Rx buffer | 3216 // Receipt of new packet, put into Rx buffer |
3186 void | 3217 void |
3187 TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader) | 3218 TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader) |
3188 { | 3219 { |
3189 NS_LOG_FUNCTION (this << tcpHeader); | 3220 NS_LOG_FUNCTION (this << tcpHeader); |
3190 NS_LOG_DEBUG ("Data segment, seq=" << tcpHeader.GetSequenceNumber () << | 3221 NS_LOG_DEBUG ("Data segment, seq=" << tcpHeader.GetSequenceNumber () << |
3191 " pkt size=" << p->GetSize () ); | 3222 " pkt size=" << p->GetSize () ); |
3192 | 3223 |
3193 // Put into Rx buffer | 3224 // Put into Rx buffer |
3194 SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence (); | 3225 SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence (); |
3195 if (!m_rxBuffer->Add (p, tcpHeader)) | 3226 if (!m_rxBuffer->Add (p, tcpHeader)) |
3196 { // Insert failed: No data or RX buffer full | 3227 { // Insert failed: No data or RX buffer full |
3197 if (m_ecnState == ECN_CE_RCVD || m_ecnState == ECN_ECE_SENT) | 3228 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState
== TcpSocketState::ECN_ECE_SENT) |
3198 { | 3229 { |
3199 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | 3230 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
3200 m_ecnState = ECN_ECE_SENT; | 3231 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
3201 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_ECE_SENT"); | 3232 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_ECE_SENT"); |
3202 } | 3233 } |
3203 else | 3234 else |
3204 { | 3235 { |
3205 SendEmptyPacket (TcpHeader::ACK); | 3236 SendEmptyPacket (TcpHeader::ACK); |
3206 }· | 3237 }· |
3207 return; | 3238 return; |
3208 } | 3239 } |
| 3240 // Notify app to receive if necessary |
| 3241 if (expectedSeq < m_rxBuffer->NextRxSequence ()) |
| 3242 { // NextRxSeq advanced, we have something to send to the app |
| 3243 if (!m_shutdownRecv) |
| 3244 { |
| 3245 NotifyDataRecv (); |
| 3246 } |
| 3247 // Handle exceptions |
| 3248 if (m_closeNotified) |
| 3249 { |
| 3250 NS_LOG_WARN ("Why TCP " << this << " got data after close notification
?"); |
| 3251 } |
| 3252 // If we received FIN before and now completed all "holes" in rx buffer, |
| 3253 // invoke peer close procedure |
| 3254 if (m_rxBuffer->Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) ==
0) |
| 3255 { |
| 3256 DoPeerClose (); |
| 3257 return; |
| 3258 } |
| 3259 } |
3209 // Now send a new ACK packet acknowledging all received and delivered data | 3260 // Now send a new ACK packet acknowledging all received and delivered data |
3210 if (m_rxBuffer->Size () > m_rxBuffer->Available () || m_rxBuffer->NextRxSequen
ce () > expectedSeq + p->GetSize ()) | 3261 if (m_rxBuffer->Size () > m_rxBuffer->Available () || m_rxBuffer->NextRxSequen
ce () > expectedSeq + p->GetSize ()) |
3211 { // A gap exists in the buffer, or we filled a gap: Always ACK | 3262 { // A gap exists in the buffer, or we filled a gap: Always ACK |
3212 if (m_ecnState == ECN_CE_RCVD || m_ecnState == ECN_ECE_SENT) | 3263 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState
== TcpSocketState::ECN_ECE_SENT) |
3213 { | 3264 { |
3214 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | 3265 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
3215 m_ecnState = ECN_ECE_SENT; | 3266 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
3216 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_ECE_SENT"); | 3267 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_ECE_SENT"); |
3217 } | 3268 } |
3218 else | 3269 else |
3219 { | 3270 { |
3220 SendEmptyPacket (TcpHeader::ACK); | 3271 SendEmptyPacket (TcpHeader::ACK); |
3221 } | 3272 } |
3222 } | 3273 } |
3223 else | 3274 else |
3224 { // In-sequence packet: ACK if delayed ack count allows | 3275 { // In-sequence packet: ACK if delayed ack count allows |
3225 if (++m_delAckCount >= m_delAckMaxCount) | 3276 if (++m_delAckCount >= m_delAckMaxCount) |
3226 { | 3277 { |
3227 m_delAckEvent.Cancel (); | 3278 m_delAckEvent.Cancel (); |
3228 m_delAckCount = 0; | 3279 m_delAckCount = 0; |
3229 if (m_ecnState == ECN_CE_RCVD || m_ecnState == ECN_ECE_SENT) | 3280 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnSt
ate == TcpSocketState::ECN_ECE_SENT) |
3230 { | 3281 { |
3231 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | 3282 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
3232 m_ecnState = ECN_ECE_SENT; | 3283 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
3233 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_ECE_SENT"); | 3284 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << "
-> ECN_ECE_SENT"); |
3234 } | 3285 } |
3235 else | 3286 else |
3236 { | 3287 { |
3237 SendEmptyPacket (TcpHeader::ACK); | 3288 SendEmptyPacket (TcpHeader::ACK); |
3238 } | 3289 } |
3239 } | 3290 } |
3240 else if (m_delAckEvent.IsExpired ()) | 3291 else if (m_delAckEvent.IsExpired ()) |
3241 { | 3292 { |
3242 m_delAckEvent = Simulator::Schedule (m_delAckTimeout, | 3293 m_delAckEvent = Simulator::Schedule (m_delAckTimeout, |
3243 &TcpSocketBase::DelAckTimeout, th
is); | 3294 &TcpSocketBase::DelAckTimeout, th
is); |
3244 NS_LOG_LOGIC (this << " scheduled delayed ACK at " << | 3295 NS_LOG_LOGIC (this << " scheduled delayed ACK at " << |
3245 (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEv
ent)).GetSeconds ()); | 3296 (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEv
ent)).GetSeconds ()); |
3246 } | |
3247 } | |
3248 // Notify app to receive if necessary | |
3249 if (expectedSeq < m_rxBuffer->NextRxSequence ()) | |
3250 { // NextRxSeq advanced, we have something to send to the app | |
3251 if (!m_shutdownRecv) | |
3252 { | |
3253 NotifyDataRecv (); | |
3254 } | |
3255 // Handle exceptions | |
3256 if (m_closeNotified) | |
3257 { | |
3258 NS_LOG_WARN ("Why TCP " << this << " got data after close notification
?"); | |
3259 } | |
3260 // If we received FIN before and now completed all "holes" in rx buffer, | |
3261 // invoke peer close procedure | |
3262 if (m_rxBuffer->Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) ==
0) | |
3263 { | |
3264 DoPeerClose (); | |
3265 } | 3297 } |
3266 } | 3298 } |
3267 } | 3299 } |
3268 | 3300 |
3269 /** | 3301 /** |
3270 * \brief Estimate the RTT | 3302 * \brief Estimate the RTT |
3271 * | 3303 * |
3272 * Called by ForwardUp() to estimate RTT. | 3304 * Called by ForwardUp() to estimate RTT. |
3273 * | 3305 * |
3274 * \param tcpHeader TCP header for the incoming packet | 3306 * \param tcpHeader TCP header for the incoming packet |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3457 DoRetransmit (); | 3489 DoRetransmit (); |
3458 | 3490 |
3459 NS_ASSERT_MSG (BytesInFlight () <= m_tcb->m_segmentSize, | 3491 NS_ASSERT_MSG (BytesInFlight () <= m_tcb->m_segmentSize, |
3460 "In flight there is more than one segment"); | 3492 "In flight there is more than one segment"); |
3461 } | 3493 } |
3462 | 3494 |
3463 void | 3495 void |
3464 TcpSocketBase::DelAckTimeout (void) | 3496 TcpSocketBase::DelAckTimeout (void) |
3465 { | 3497 { |
3466 m_delAckCount = 0; | 3498 m_delAckCount = 0; |
3467 if (m_ecnState == ECN_CE_RCVD || m_ecnState == ECN_ECE_SENT) | 3499 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState == T
cpSocketState::ECN_ECE_SENT) |
3468 { | 3500 { |
3469 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | 3501 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
3470 m_ecnState = ECN_ECE_SENT; | 3502 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
3471 } | 3503 } |
3472 else | 3504 else |
3473 { | 3505 { |
3474 SendEmptyPacket (TcpHeader::ACK); | 3506 SendEmptyPacket (TcpHeader::ACK); |
3475 } | 3507 } |
3476 } | 3508 } |
3477 | 3509 |
3478 void | 3510 void |
3479 TcpSocketBase::LastAckTimeout (void) | 3511 TcpSocketBase::LastAckTimeout (void) |
3480 { | 3512 { |
(...skipping 29 matching lines...) Expand all Loading... |
3510 tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ()); | 3542 tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ()); |
3511 tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ()); | 3543 tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ()); |
3512 } | 3544 } |
3513 else | 3545 else |
3514 { | 3546 { |
3515 tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ()); | 3547 tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ()); |
3516 tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ()); | 3548 tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ()); |
3517 } | 3549 } |
3518 AddOptions (tcpHeader); | 3550 AddOptions (tcpHeader); |
3519 //Send a packet tag for setting ECT bits in IP header | 3551 //Send a packet tag for setting ECT bits in IP header |
3520 if (m_ecnState != ECN_DISABLED) | 3552 if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED) |
3521 { | 3553 { |
3522 SocketIpTosTag ipTosTag; | 3554 SocketIpTosTag ipTosTag; |
3523 ipTosTag.SetTos (0x02); | 3555 ipTosTag.SetTos (0x02); |
3524 p->AddPacketTag (ipTosTag); | 3556 p->AddPacketTag (ipTosTag); |
3525 · | 3557 · |
3526 SocketIpv6TclassTag ipTclassTag; | 3558 SocketIpv6TclassTag ipTclassTag; |
3527 ipTclassTag.SetTclass (0x02); | 3559 ipTclassTag.SetTclass (0x02); |
3528 p->AddPacketTag (ipTclassTag); | 3560 p->AddPacketTag (ipTclassTag); |
3529 } | 3561 } |
3530 m_txTrace (p, tcpHeader, this); | 3562 m_txTrace (p, tcpHeader, this); |
(...skipping 25 matching lines...) Expand all Loading... |
3556 if (m_synCount > 0) | 3588 if (m_synCount > 0) |
3557 { | 3589 { |
3558 if (m_ecn) | 3590 if (m_ecn) |
3559 { | 3591 { |
3560 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR)
; | 3592 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ECE | TcpHeader::CWR)
; |
3561 } | 3593 } |
3562 else | 3594 else |
3563 { | 3595 { |
3564 SendEmptyPacket (TcpHeader::SYN); | 3596 SendEmptyPacket (TcpHeader::SYN); |
3565 } | 3597 } |
3566 m_ecnState = ECN_DISABLED; | 3598 m_tcb->m_ecnState = TcpSocketState::ECN_DISABLED; |
3567 } | 3599 } |
3568 else | 3600 else |
3569 { | 3601 { |
3570 NotifyConnectionFailed (); | 3602 NotifyConnectionFailed (); |
3571 } | 3603 } |
3572 return; | 3604 return; |
3573 } | 3605 } |
3574 | 3606 |
3575 if (m_dataRetrCount == 0) | 3607 if (m_dataRetrCount == 0) |
3576 { | 3608 { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3657 NS_LOG_FUNCTION (this << size); | 3689 NS_LOG_FUNCTION (this << size); |
3658 uint32_t oldSize = GetRcvBufSize (); | 3690 uint32_t oldSize = GetRcvBufSize (); |
3659 | 3691 |
3660 m_rxBuffer->SetMaxBufferSize (size); | 3692 m_rxBuffer->SetMaxBufferSize (size); |
3661 | 3693 |
3662 /* The size has (manually) increased. Actively inform the other end to prevent | 3694 /* The size has (manually) increased. Actively inform the other end to prevent |
3663 * stale zero-window states. | 3695 * stale zero-window states. |
3664 */ | 3696 */ |
3665 if (oldSize < size && m_connected) | 3697 if (oldSize < size && m_connected) |
3666 { | 3698 { |
3667 if (m_ecnState == ECN_CE_RCVD || m_ecnState == ECN_ECE_SENT) | 3699 if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState
== TcpSocketState::ECN_ECE_SENT) |
3668 { | 3700 { |
3669 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); | 3701 SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE); |
3670 m_ecnState = ECN_ECE_SENT; | 3702 m_tcb->m_ecnState = TcpSocketState::ECN_ECE_SENT; |
3671 NS_LOG_DEBUG (EcnStateName[m_ecnState] << " -> ECN_ECE_SENT"); | 3703 NS_LOG_DEBUG (TcpSocketState::EcnStateName[m_tcb->m_ecnState] << " ->
ECN_ECE_SENT"); |
3672 } | 3704 } |
3673 else | 3705 else |
3674 { | 3706 { |
3675 SendEmptyPacket (TcpHeader::ACK); | 3707 SendEmptyPacket (TcpHeader::ACK); |
3676 } | 3708 } |
3677 } | 3709 } |
3678 } | 3710 } |
3679 | 3711 |
3680 uint32_t | 3712 uint32_t |
3681 TcpSocketBase::GetRcvBufSize (void) const | 3713 TcpSocketBase::GetRcvBufSize (void) const |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3941 NS_LOG_INFO (m_node->GetId () << " Add option SACK"); | 3973 NS_LOG_INFO (m_node->GetId () << " Add option SACK"); |
3942 } | 3974 } |
3943 | 3975 |
3944 void | 3976 void |
3945 TcpSocketBase::ProcessOptionTimestamp (const Ptr<const TcpOption> option, | 3977 TcpSocketBase::ProcessOptionTimestamp (const Ptr<const TcpOption> option, |
3946 const SequenceNumber32 &seq) | 3978 const SequenceNumber32 &seq) |
3947 { | 3979 { |
3948 NS_LOG_FUNCTION (this << option); | 3980 NS_LOG_FUNCTION (this << option); |
3949 | 3981 |
3950 Ptr<const TcpOptionTS> ts = DynamicCast<const TcpOptionTS> (option); | 3982 Ptr<const TcpOptionTS> ts = DynamicCast<const TcpOptionTS> (option); |
| 3983 |
| 3984 m_tcb->m_rcvTimestampValue = ts->GetTimestamp (); |
| 3985 m_tcb->m_rcvTimestampEchoReply = ts->GetEcho(); |
3951 | 3986 |
3952 if (seq == m_rxBuffer->NextRxSequence () && seq <= m_highTxAck) | 3987 if (seq == m_rxBuffer->NextRxSequence () && seq <= m_highTxAck) |
3953 { | 3988 { |
3954 m_timestampToEcho = ts->GetTimestamp (); | 3989 m_timestampToEcho = ts->GetTimestamp (); |
3955 } | 3990 } |
3956 | 3991 |
3957 NS_LOG_INFO (m_node->GetId () << " Got timestamp=" << | 3992 NS_LOG_INFO (m_node->GetId () << " Got timestamp=" << |
3958 m_timestampToEcho << " and Echo=" << ts->GetEcho ()); | 3993 m_timestampToEcho << " and Echo=" << ts->GetEcho ()); |
3959 } | 3994 } |
3960 | 3995 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4068 } | 4103 } |
4069 | 4104 |
4070 void | 4105 void |
4071 TcpSocketBase::UpdateCongState (TcpSocketState::TcpCongState_t oldValue, | 4106 TcpSocketBase::UpdateCongState (TcpSocketState::TcpCongState_t oldValue, |
4072 TcpSocketState::TcpCongState_t newValue) | 4107 TcpSocketState::TcpCongState_t newValue) |
4073 { | 4108 { |
4074 m_congStateTrace (oldValue, newValue); | 4109 m_congStateTrace (oldValue, newValue); |
4075 } | 4110 } |
4076 | 4111 |
4077 void | 4112 void |
| 4113 TcpSocketBase::UpdateEcnState (TcpSocketState::EcnState_t oldValue, |
| 4114 TcpSocketState::EcnState_t newValue) |
| 4115 { |
| 4116 m_ecnStateTrace (oldValue, newValue); |
| 4117 } |
| 4118 |
| 4119 void |
4078 TcpSocketBase::UpdateNextTxSequence (SequenceNumber32 oldValue, | 4120 TcpSocketBase::UpdateNextTxSequence (SequenceNumber32 oldValue, |
4079 SequenceNumber32 newValue) | 4121 SequenceNumber32 newValue) |
4080 | 4122 |
4081 { | 4123 { |
4082 m_nextTxSequenceTrace (oldValue, newValue); | 4124 m_nextTxSequenceTrace (oldValue, newValue); |
4083 } | 4125 } |
4084 | 4126 |
4085 void | 4127 void |
4086 TcpSocketBase::UpdateHighTxMark (SequenceNumber32 oldValue, SequenceNumber32 new
Value) | 4128 TcpSocketBase::UpdateHighTxMark (SequenceNumber32 oldValue, SequenceNumber32 new
Value) |
4087 { | 4129 { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4129 | 4171 |
4130 RttHistory::RttHistory (const RttHistory& h) | 4172 RttHistory::RttHistory (const RttHistory& h) |
4131 : seq (h.seq), | 4173 : seq (h.seq), |
4132 count (h.count), | 4174 count (h.count), |
4133 time (h.time), | 4175 time (h.time), |
4134 retx (h.retx) | 4176 retx (h.retx) |
4135 { | 4177 { |
4136 } | 4178 } |
4137 | 4179 |
4138 } // namespace ns3 | 4180 } // namespace ns3 |
LEFT | RIGHT |