Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2010 Adrian Sai-wah Tam | 3 * Copyright (c) 2010 Adrian Sai-wah Tam |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 2 as | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 | 46 |
47 namespace ns3 { | 47 namespace ns3 { |
48 | 48 |
49 NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase); | 49 NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase); |
50 | 50 |
51 TypeId | 51 TypeId |
52 TcpSocketBase::GetTypeId (void) | 52 TcpSocketBase::GetTypeId (void) |
53 { | 53 { |
54 static TypeId tid = TypeId ("ns3::TcpSocketBase") | 54 static TypeId tid = TypeId ("ns3::TcpSocketBase") |
55 .SetParent<TcpSocket> () | 55 .SetParent<TcpSocket> () |
56 // .AddAttribute ("TcpState", "State in TCP state machine", | |
57 // TypeId::ATTR_GET, | |
58 // EnumValue (CLOSED), | |
59 // MakeEnumAccessor (&TcpSocketBase::m_state), | |
60 // MakeEnumChecker (CLOSED, "Closed")) | |
61 .AddTraceSource ("RTO", | |
62 "Retransmission timeout", | |
63 MakeTraceSourceAccessor (&TcpSocketBase::m_rto)) | |
64 .AddTraceSource ("RTT", | |
65 "Last RTT sample", | |
66 MakeTraceSourceAccessor (&TcpSocketBase::m_lastRtt)) | |
67 .AddTraceSource ("NextTxSequence", | |
68 "Next sequence number to send (SND.NXT)", | |
69 MakeTraceSourceAccessor (&TcpSocketBase::m_nextTxSequence)) | |
70 .AddTraceSource ("HighestSequence", | |
71 "Highest sequence number ever sent in socket's life time", | |
72 MakeTraceSourceAccessor (&TcpSocketBase::m_highTxMark)) | |
73 .AddTraceSource ("State", | |
74 "TCP state", | |
75 MakeTraceSourceAccessor (&TcpSocketBase::m_state)) | |
76 .AddTraceSource ("RWND", | |
77 "Remote side's flow control window", | |
78 MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd)) | |
56 ; | 79 ; |
57 return tid; | 80 return tid; |
58 } | 81 } |
59 | 82 |
60 TcpSocketBase::TcpSocketBase (void) | 83 TcpSocketBase::TcpSocketBase (void) |
61 : m_dupAckCount (0), | 84 : m_dupAckCount (0), |
62 m_delAckCount (0), | 85 m_delAckCount (0), |
63 m_endPoint (0), | 86 m_endPoint (0), |
64 m_node (0), | 87 m_node (0), |
65 m_tcp (0), | 88 m_tcp (0), |
66 m_rtt (0), | 89 m_rtt (0), |
67 m_nextTxSequence (0), // Change this for non-zero initial sequence num ber | 90 m_nextTxSequence (0), // Change this for non-zero initial sequence num ber |
68 m_highTxMark (0), | 91 m_highTxMark (0), |
69 m_rxBuffer (0), | 92 m_rxBuffer (0), |
70 m_txBuffer (0), | 93 m_txBuffer (0), |
71 m_state (CLOSED), | 94 m_state (CLOSED), |
72 m_errno (ERROR_NOTERROR), | 95 m_errno (ERROR_NOTERROR), |
73 m_closeNotified (false), | 96 m_closeNotified (false), |
74 m_closeOnEmpty (false), | 97 m_closeOnEmpty (false), |
75 m_shutdownSend (false), | 98 m_shutdownSend (false), |
76 m_shutdownRecv (false), | 99 m_shutdownRecv (false), |
77 m_connected (false), | 100 m_connected (false), |
78 m_segmentSize (0), // For attribute initialization consistency (qui et valgrind) | 101 m_segmentSize (0), // For attribute initialization consistency (qui et valgrind) |
79 m_rxWindowSize (0) | 102 m_rWnd (0) |
80 { | 103 { |
81 NS_LOG_FUNCTION (this); | 104 NS_LOG_FUNCTION (this); |
82 } | 105 } |
83 | 106 |
84 TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) | 107 TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) |
85 : TcpSocket (sock), //copy object::m_tid and socket::callbacks | 108 : TcpSocket (sock), //copy object::m_tid and socket::callbacks |
86 m_dupAckCount (sock.m_dupAckCount), | 109 m_dupAckCount (sock.m_dupAckCount), |
87 m_delAckCount (0), | 110 m_delAckCount (0), |
88 m_delAckMaxCount (sock.m_delAckMaxCount), | 111 m_delAckMaxCount (sock.m_delAckMaxCount), |
89 m_cnCount (sock.m_cnCount), | 112 m_cnCount (sock.m_cnCount), |
90 m_delAckTimeout (sock.m_delAckTimeout), | 113 m_delAckTimeout (sock.m_delAckTimeout), |
91 m_persistTimeout (sock.m_persistTimeout), | 114 m_persistTimeout (sock.m_persistTimeout), |
92 m_cnTimeout (sock.m_cnTimeout), | 115 m_cnTimeout (sock.m_cnTimeout), |
93 m_endPoint (0), | 116 m_endPoint (0), |
94 m_node (sock.m_node), | 117 m_node (sock.m_node), |
95 m_tcp (sock.m_tcp), | 118 m_tcp (sock.m_tcp), |
96 m_rtt (0), | 119 m_rtt (0), |
97 m_nextTxSequence (sock.m_nextTxSequence), | 120 m_nextTxSequence (sock.m_nextTxSequence), |
98 m_highTxMark (sock.m_highTxMark), | 121 m_highTxMark (sock.m_highTxMark), |
99 m_rxBuffer (sock.m_rxBuffer), | 122 m_rxBuffer (sock.m_rxBuffer), |
100 m_txBuffer (sock.m_txBuffer), | 123 m_txBuffer (sock.m_txBuffer), |
101 m_state (sock.m_state), | 124 m_state (sock.m_state), |
102 m_errno (sock.m_errno), | 125 m_errno (sock.m_errno), |
103 m_closeNotified (sock.m_closeNotified), | 126 m_closeNotified (sock.m_closeNotified), |
104 m_closeOnEmpty (sock.m_closeOnEmpty), | 127 m_closeOnEmpty (sock.m_closeOnEmpty), |
105 m_shutdownSend (sock.m_shutdownSend), | 128 m_shutdownSend (sock.m_shutdownSend), |
106 m_shutdownRecv (sock.m_shutdownRecv), | 129 m_shutdownRecv (sock.m_shutdownRecv), |
107 m_connected (sock.m_connected), | 130 m_connected (sock.m_connected), |
108 m_segmentSize (sock.m_segmentSize), | 131 m_segmentSize (sock.m_segmentSize), |
109 m_rxWindowSize (sock.m_rxWindowSize) | 132 m_rWnd (sock.m_rWnd) |
110 { | 133 { |
111 NS_LOG_FUNCTION (this); | 134 NS_LOG_FUNCTION (this); |
112 NS_LOG_LOGIC ("Invoked the copy constructor"); | 135 NS_LOG_LOGIC ("Invoked the copy constructor"); |
113 // Copy the rtt estimator if it is set | 136 // Copy the rtt estimator if it is set |
114 if (sock.m_rtt) | 137 if (sock.m_rtt) |
115 { | 138 { |
116 m_rtt = sock.m_rtt->Copy (); | 139 m_rtt = sock.m_rtt->Copy (); |
117 } | 140 } |
118 // Reset all callbacks to null | 141 // Reset all callbacks to null |
119 Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > (); | 142 Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > (); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint); | 248 NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint); |
226 | 249 |
227 return SetupCallback (); | 250 return SetupCallback (); |
228 } | 251 } |
229 | 252 |
230 /** Inherit from Socket class: Initiate connection to a remote address:port */ | 253 /** Inherit from Socket class: Initiate connection to a remote address:port */ |
231 int | 254 int |
232 TcpSocketBase::Connect (const Address & address) | 255 TcpSocketBase::Connect (const Address & address) |
233 { | 256 { |
234 NS_LOG_FUNCTION (this << address); | 257 NS_LOG_FUNCTION (this << address); |
235 | 258 |
joao.taveira
2010/10/24 18:11:49
A socket may be reused after CLOSED, so really we
| |
236 // If haven't do so, Bind() this socket first | 259 // If haven't do so, Bind() this socket first |
237 if (m_endPoint == 0) | 260 if (m_endPoint == 0) |
238 { | 261 { |
239 if (Bind () == -1) | 262 if (Bind () == -1) |
240 { | 263 { |
241 NS_ASSERT (m_endPoint == 0); | 264 NS_ASSERT (m_endPoint == 0); |
242 return -1; // Bind() failed | 265 return -1; // Bind() failed |
243 } | 266 } |
244 NS_ASSERT (m_endPoint != 0); | 267 NS_ASSERT (m_endPoint != 0); |
245 } | 268 } |
(...skipping 16 matching lines...) Expand all Loading... | |
262 TcpSocketBase::Listen (void) | 285 TcpSocketBase::Listen (void) |
263 { | 286 { |
264 NS_LOG_FUNCTION (this); | 287 NS_LOG_FUNCTION (this); |
265 // Linux quits EINVAL if we're not in CLOSED state, so match what they do | 288 // Linux quits EINVAL if we're not in CLOSED state, so match what they do |
266 if (m_state != CLOSED) | 289 if (m_state != CLOSED) |
267 { | 290 { |
268 m_errno = ERROR_INVAL; | 291 m_errno = ERROR_INVAL; |
269 return -1; | 292 return -1; |
270 } | 293 } |
271 // In other cases, set the state to LISTEN and done | 294 // In other cases, set the state to LISTEN and done |
295 NS_LOG_INFO ("CLOSED -> LISTEN"); | |
272 m_state = LISTEN; | 296 m_state = LISTEN; |
273 NS_LOG_LOGIC ("CLOSED -> LISTEN"); | |
274 return 0; | 297 return 0; |
275 } | 298 } |
276 | 299 |
277 /** Inherit from Socket class: Kill this socket and signal the peer (if any) */ | 300 /** Inherit from Socket class: Kill this socket and signal the peer (if any) */ |
278 int | 301 int |
279 TcpSocketBase::Close (void) | 302 TcpSocketBase::Close (void) |
280 { | 303 { |
281 NS_LOG_FUNCTION (this); | 304 NS_LOG_FUNCTION (this); |
282 // First we check to see if there is any unread rx data | 305 // First we check to see if there is any unread rx data |
283 // Bug number 426 claims we should send reset in this case. | 306 // Bug number 426 claims we should send reset in this case. |
284 if (m_rxBuffer.Size () != 0) | 307 if (m_rxBuffer.Size () != 0) |
285 { | 308 { |
286 SendRST (); | 309 SendRST (); |
287 return 0; | 310 return 0; |
288 } | 311 } |
289 if (m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0) | 312 if (m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0) |
290 { // App close with pending data must wait until all data transmitted | 313 { // App close with pending data must wait until all data transmitted |
291 m_closeOnEmpty = true; | 314 if (m_closeOnEmpty == false) |
292 NS_LOG_LOGIC ("Socket " << this << " deferring close, state " << m_state); | 315 { |
316 m_closeOnEmpty = true; | |
317 NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpSta teName[m_state]); | |
318 } | |
293 return 0; | 319 return 0; |
294 } | 320 } |
295 return DoClose (); | 321 return DoClose (); |
296 } | 322 } |
297 | 323 |
298 /** Inherit from Socket class: Signal a termination of send */ | 324 /** Inherit from Socket class: Signal a termination of send */ |
299 int | 325 int |
300 TcpSocketBase::ShutdownSend (void) | 326 TcpSocketBase::ShutdownSend (void) |
301 { | 327 { |
302 NS_LOG_FUNCTION (this); | 328 NS_LOG_FUNCTION (this); |
(...skipping 19 matching lines...) Expand all Loading... | |
322 NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send( )"); | 348 NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send( )"); |
323 if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT) | 349 if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT) |
324 { | 350 { |
325 // Store the packet into Tx buffer | 351 // Store the packet into Tx buffer |
326 if (!m_txBuffer.Add (p)) | 352 if (!m_txBuffer.Add (p)) |
327 { // TxBuffer overflow, send failed | 353 { // TxBuffer overflow, send failed |
328 m_errno = ERROR_MSGSIZE; | 354 m_errno = ERROR_MSGSIZE; |
329 return -1; | 355 return -1; |
330 } | 356 } |
331 // Submit the data to lower layers | 357 // Submit the data to lower layers |
332 NS_LOG_DEBUG ("txBufSize=" << m_txBuffer.Size () << " state " << m_state); | 358 NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateN ame[m_state]); |
333 if (m_state == ESTABLISHED || m_state == CLOSE_WAIT) | 359 if (m_state == ESTABLISHED || m_state == CLOSE_WAIT) |
334 { // Try to send the data out | 360 { // Try to send the data out |
335 SendPendingData (m_connected); | 361 SendPendingData (m_connected); |
336 } | 362 } |
337 return p->GetSize (); | 363 return p->GetSize (); |
338 } | 364 } |
339 else | 365 else |
340 { // Connection not established yet | 366 { // Connection not established yet |
341 m_errno = ERROR_NOTCONN; | 367 m_errno = ERROR_NOTCONN; |
342 return -1; // Send failure | 368 return -1; // Send failure |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
401 return m_rxBuffer.Available (); | 427 return m_rxBuffer.Available (); |
402 } | 428 } |
403 | 429 |
404 /** Inherit from Socket class: Return local address:port */ | 430 /** Inherit from Socket class: Return local address:port */ |
405 int | 431 int |
406 TcpSocketBase::GetSockName (Address &address) const | 432 TcpSocketBase::GetSockName (Address &address) const |
407 { | 433 { |
408 NS_LOG_FUNCTION (this); | 434 NS_LOG_FUNCTION (this); |
409 if (m_endPoint != 0) | 435 if (m_endPoint != 0) |
410 { | 436 { |
411 address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->G etLocalPort ()); | 437 address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->G etLocalPort ()); |
Josh Pelkey
2010/12/15 18:07:39
RecvFrom calls this method which is supposed to re
| |
412 } | 438 } |
413 else | 439 else |
414 { // It is possible to call this method on a socket without a name | 440 { // It is possible to call this method on a socket without a name |
415 // in which case, behavior is unspecified | 441 // in which case, behavior is unspecified |
416 address = InetSocketAddress (Ipv4Address::GetZero (), 0); | 442 address = InetSocketAddress (Ipv4Address::GetZero (), 0); |
417 } | 443 } |
418 return 0; | 444 return 0; |
419 } | 445 } |
420 | 446 |
421 /** Inherit from Socket class: Bind this socket to the specified NetDevice */ | 447 /** Inherit from Socket class: Bind this socket to the specified NetDevice */ |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 /** Perform the real connection tasks: Send SYN if allowed, RST if invalid */ | 480 /** Perform the real connection tasks: Send SYN if allowed, RST if invalid */ |
455 int | 481 int |
456 TcpSocketBase::DoConnect (void) | 482 TcpSocketBase::DoConnect (void) |
457 { | 483 { |
458 NS_LOG_FUNCTION (this); | 484 NS_LOG_FUNCTION (this); |
459 | 485 |
460 // A new connection is allowed only if this socket does not have a connection | 486 // A new connection is allowed only if this socket does not have a connection |
461 if (m_state == CLOSED || m_state == LISTEN || m_state == SYN_SENT || m_state = = LAST_ACK || m_state == CLOSE_WAIT) | 487 if (m_state == CLOSED || m_state == LISTEN || m_state == SYN_SENT || m_state = = LAST_ACK || m_state == CLOSE_WAIT) |
462 { // send a SYN packet and change state into SYN_SENT | 488 { // send a SYN packet and change state into SYN_SENT |
463 SendEmptyPacket (TcpHeader::SYN); | 489 SendEmptyPacket (TcpHeader::SYN); |
490 NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT"); | |
464 m_state = SYN_SENT; | 491 m_state = SYN_SENT; |
465 NS_LOG_LOGIC ("moved to SYN_SENT state"); | |
466 } | 492 } |
467 else if (m_state != TIME_WAIT) | 493 else if (m_state != TIME_WAIT) |
468 { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, a n connection | 494 { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, a n connection |
469 // exists. We send RST, tear down everything, and close this socket. | 495 // exists. We send RST, tear down everything, and close this socket. |
470 CloseAndNotify (); | 496 CloseAndNotify (); |
471 SendRST (); | 497 SendRST (); |
472 } | 498 } |
473 return 0; | 499 return 0; |
474 } | 500 } |
475 | 501 |
476 /** Do the action to close the socket. Usually send a packet with appropriate | 502 /** Do the action to close the socket. Usually send a packet with appropriate |
477 flags depended on the current m_state. */ | 503 flags depended on the current m_state. */ |
478 int | 504 int |
479 TcpSocketBase::DoClose (void) | 505 TcpSocketBase::DoClose (void) |
480 { | 506 { |
481 NS_LOG_FUNCTION (this); | 507 NS_LOG_FUNCTION (this); |
482 switch (m_state) | 508 switch (m_state) |
483 { | 509 { |
484 case SYN_RCVD: | 510 case SYN_RCVD: |
485 case ESTABLISHED: | 511 case ESTABLISHED: |
486 // send FIN to close the peer | 512 // send FIN to close the peer |
487 SendEmptyPacket (TcpHeader::FIN); | 513 SendEmptyPacket (TcpHeader::FIN); |
514 NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1"); | |
488 m_state = FIN_WAIT_1; | 515 m_state = FIN_WAIT_1; |
489 NS_LOG_LOGIC ("ESTABLISHED -> FIN_WAIT_1"); | |
490 break; | 516 break; |
491 case CLOSE_WAIT: | 517 case CLOSE_WAIT: |
492 // send FIN+ACK to close the peer | 518 // send FIN+ACK to close the peer |
493 SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK); | 519 SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK); |
520 NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK"); | |
494 m_state = LAST_ACK; | 521 m_state = LAST_ACK; |
495 NS_LOG_LOGIC ("CLOSE_WAIT -> LAST_ACK"); | |
496 break; | 522 break; |
497 case SYN_SENT: | 523 case SYN_SENT: |
498 case CLOSING: | 524 case CLOSING: |
499 // Send RST if application closes in SYN_SENT and CLOSING | 525 // Send RST if application closes in SYN_SENT and CLOSING |
500 CloseAndNotify (); | 526 CloseAndNotify (); |
501 SendRST (); | 527 SendRST (); |
502 break; | 528 break; |
503 case LISTEN: | 529 case LISTEN: |
504 case LAST_ACK: | 530 case LAST_ACK: |
505 // In these three states, move to CLOSED and tear down the end point | 531 // In these three states, move to CLOSED and tear down the end point |
(...skipping 11 matching lines...) Expand all Loading... | |
517 } | 543 } |
518 | 544 |
519 /** Peacefully close the socket by notifying the upper layer and deallocate end point */ | 545 /** Peacefully close the socket by notifying the upper layer and deallocate end point */ |
520 void | 546 void |
521 TcpSocketBase::CloseAndNotify (void) | 547 TcpSocketBase::CloseAndNotify (void) |
522 { | 548 { |
523 NS_LOG_FUNCTION (this); | 549 NS_LOG_FUNCTION (this); |
524 | 550 |
525 if (!m_closeNotified) NotifyNormalClose (); | 551 if (!m_closeNotified) NotifyNormalClose (); |
526 m_closeNotified = true; | 552 m_closeNotified = true; |
553 NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED"); | |
527 m_state = CLOSED; | 554 m_state = CLOSED; |
528 DeallocateEndPoint (); | 555 DeallocateEndPoint (); |
529 NS_LOG_LOGIC ("moved to CLOSED state"); | 556 } |
557 | |
558 | |
559 /** Tell if a sequence number is out side the range that my rx buffer can | |
560 accpet */ | |
561 bool | |
562 TcpSocketBase::OutOfRange (SequenceNumber32 s) const | |
563 { | |
564 if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD) | |
565 { // Rx buffer in these states are not initialized. | |
566 return false; | |
567 } | |
568 if (m_state == LAST_ACK || m_state == CLOSING) | |
569 { // In LAST_ACK and CLOSING states, it only wait for an ACK and the | |
570 // sequence number must equals to m_rxBuffer.NextRxSequence () | |
571 return (m_rxBuffer.NextRxSequence () != s); | |
572 }; | |
573 ·· | |
574 // In all other cases, check if the sequence number is in range | |
575 return (m_rxBuffer.MaxRxSequence () < s || m_rxBuffer.NextRxSequence () > s); | |
530 } | 576 } |
531 | 577 |
532 /** Function called by the L3 protocol when it received a packet to pass on to | 578 /** Function called by the L3 protocol when it received a packet to pass on to |
533 the TCP. This function is registered as the "RxCallback" function in | 579 the TCP. This function is registered as the "RxCallback" function in |
534 SetupCallback(), which invoked by Bind(), and CompleteFork() */ | 580 SetupCallback(), which invoked by Bind(), and CompleteFork() */ |
535 void | 581 void |
536 TcpSocketBase::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, | 582 TcpSocketBase::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, |
537 Ptr<Ipv4Interface> incomingInterface) | 583 Ptr<Ipv4Interface> incomingInterface) |
538 { | 584 { |
539 NS_LOG_DEBUG ("Socket " << this << " got forward up" << | 585 NS_LOG_LOGIC ("Socket " << this << " forward up " << |
540 " saddr " << m_endPoint->GetPeerAddress () << | 586 m_endPoint->GetPeerAddress () << |
541 " sport " << m_endPoint->GetPeerPort () << | 587 ":" << m_endPoint->GetPeerPort () << |
542 " daddr " << m_endPoint->GetLocalAddress () << | 588 " to " << m_endPoint->GetLocalAddress () << |
543 " dport " << m_endPoint->GetLocalPort ()); | 589 ":" << m_endPoint->GetLocalPort ()); |
544 Address fromAddress = InetSocketAddress (header.GetSource (), port); | 590 Address fromAddress = InetSocketAddress (header.GetSource (), port); |
545 Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->G etLocalPort ()); | 591 Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->G etLocalPort ()); |
546 | 592 |
547 // Peel off TCP header and do validity checking | 593 // Peel off TCP header and do validity checking |
548 TcpHeader tcpHeader; | 594 TcpHeader tcpHeader; |
549 packet->RemoveHeader (tcpHeader); | 595 packet->RemoveHeader (tcpHeader); |
550 if (tcpHeader.GetFlags () & TcpHeader::ACK) | 596 if (tcpHeader.GetFlags () & TcpHeader::ACK) |
551 { // TODO: This RTT function shall be changed to handle timestamp options | 597 {· |
552 // One solution is to pass the whole header instead of just the number | 598 EstimateRtt (tcpHeader); |
553 m_rtt->AckSeq (tcpHeader.GetAckNumber () ); | |
554 } | 599 } |
555 | 600 |
556 // Update Rx window size, i.e. the flow control window | 601 // Update Rx window size, i.e. the flow control window |
557 if (m_rxWindowSize == 0 && tcpHeader.GetWindowSize () != 0) | 602 if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0) |
558 { // persist probes end | 603 { // persist probes end |
559 NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); | 604 NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); |
560 m_persistEvent.Cancel (); | 605 m_persistEvent.Cancel (); |
561 } | 606 } |
562 m_rxWindowSize = tcpHeader.GetWindowSize (); | 607 m_rWnd = tcpHeader.GetWindowSize (); |
608 | |
609 // Discard out of range packets | |
610 if (OutOfRange (tcpHeader.GetSequenceNumber ())) | |
611 { | |
612 NS_LOG_LOGIC ("At state " << TcpStateName[m_state] << | |
613 " received packet of seq " << tcpHeader.GetSequenceNumber () << | |
614 " out of range [" << m_rxBuffer.NextRxSequence () << ":" << | |
615 m_rxBuffer.MaxRxSequence () << "]"); | |
616 return; | |
617 } | |
563 | 618 |
564 // TCP state machine code in different process functions | 619 // TCP state machine code in different process functions |
565 // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel | 620 // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel |
566 switch (m_state) | 621 switch (m_state) |
567 { | 622 { |
568 case ESTABLISHED: | 623 case ESTABLISHED: |
569 ProcessEstablished (packet, tcpHeader); | 624 ProcessEstablished (packet, tcpHeader); |
570 break; | 625 break; |
571 case LISTEN: | 626 case LISTEN: |
572 ProcessListen (packet, tcpHeader, fromAddress, toAddress); | 627 ProcessListen (packet, tcpHeader, fromAddress, toAddress); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
622 { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and | 677 { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and |
623 // respond with a SYN+ACK. But it is not a legal state transition as of | 678 // respond with a SYN+ACK. But it is not a legal state transition as of |
624 // RFC793. Thus this is ignored. | 679 // RFC793. Thus this is ignored. |
625 } | 680 } |
626 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)) | 681 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)) |
627 { // No action for received SYN+ACK, it is probably a duplicated packet | 682 { // No action for received SYN+ACK, it is probably a duplicated packet |
628 } | 683 } |
629 else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader ::ACK)) | 684 else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader ::ACK)) |
630 { // Received FIN or FIN+ACK, bring down this socket nicely | 685 { // Received FIN or FIN+ACK, bring down this socket nicely |
631 PeerClose (packet, tcpHeader); | 686 PeerClose (packet, tcpHeader); |
632 if (m_rxBuffer.Finished ()) | |
633 { | |
634 m_state = CLOSE_WAIT; | |
635 NS_LOG_LOGIC ("ESTABLISHED -> CLOSE_WAIT"); | |
636 } | |
637 } | 687 } |
638 else if (tcpflags == 0) | 688 else if (tcpflags == 0) |
639 { // No flags means there is only data | 689 { // No flags means there is only data |
640 ReceivedData (packet, tcpHeader); | 690 ReceivedData (packet, tcpHeader); |
641 if (m_rxBuffer.Finished ()) | 691 if (m_rxBuffer.Finished ()) |
642 { | 692 { |
643 m_state = CLOSE_WAIT; | |
644 NS_LOG_LOGIC ("ESTABLISHED -> CLOSE_WAIT"); | |
645 PeerClose (packet, tcpHeader); | 693 PeerClose (packet, tcpHeader); |
646 } | 694 } |
647 } | 695 } |
648 else if (m_rxBuffer.MaxRxSequence () >= tcpHeader.GetSequenceNumber ()) | 696 else |
649 { // Received RST or the TCP flags is invalid, in either case, terminate thi s socket | 697 { // Received RST or the TCP flags is invalid, in either case, terminate thi s socket |
650 CloseAndNotify (); | 698 CloseAndNotify (); |
651 if (tcpflags != TcpHeader::RST) | 699 if (tcpflags != TcpHeader::RST) |
652 { // this must be an invalid flag, send reset | 700 { // this must be an invalid flag, send reset |
653 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); | 701 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); |
654 SendRST (); | 702 SendRST (); |
655 } | 703 } |
656 } | 704 } |
657 } | 705 } |
658 | 706 |
659 /** Process the newly received ACK */ | 707 /** Process the newly received ACK */ |
660 void | 708 void |
661 TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 709 TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
662 { | 710 { |
663 NS_LOG_FUNCTION (this << tcpHeader); | 711 NS_LOG_FUNCTION (this << tcpHeader); |
664 | 712 |
665 // Received ACK. Compare the ACK number against highest unacked seqno | 713 // Received ACK. Compare the ACK number against highest unacked seqno |
666 if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ()) | 714 if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK)) |
715 { // Ignore if no ACK flag | |
716 } | |
717 else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ()) | |
667 { // Case 1: Old ACK, ignored. | 718 { // Case 1: Old ACK, ignored. |
668 NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ()); | 719 NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ()); |
669 } | 720 } |
670 else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ()) | 721 else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ()) |
671 { // Case 2: Potentially a duplicated ACK | 722 { // Case 2: Potentially a duplicated ACK |
672 if (tcpHeader.GetAckNumber () < m_nextTxSequence) | 723 if (tcpHeader.GetAckNumber () < m_nextTxSequence) |
673 { | 724 { |
674 NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ()); | 725 NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ()); |
675 DupAck (tcpHeader, ++m_dupAckCount); | 726 DupAck (tcpHeader, ++m_dupAckCount); |
676 } | 727 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
718 void | 769 void |
719 TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 770 TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
720 { | 771 { |
721 NS_LOG_FUNCTION (this << tcpHeader); | 772 NS_LOG_FUNCTION (this << tcpHeader); |
722 | 773 |
723 // Extract the flags. PSH and URG are not honoured. | 774 // Extract the flags. PSH and URG are not honoured. |
724 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 775 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); |
725 | 776 |
726 if (tcpflags == 0) | 777 if (tcpflags == 0) |
727 { // Bare data, accept it and move to ESTABLISHED state. This is not a norma l behaviour. Remove this? | 778 { // Bare data, accept it and move to ESTABLISHED state. This is not a norma l behaviour. Remove this? |
779 NS_LOG_INFO ("SYN_SENT -> ESTABLISHED"); | |
728 m_state = ESTABLISHED; | 780 m_state = ESTABLISHED; |
729 m_connected = true; | 781 m_connected = true; |
782 m_retxEvent.Cancel (); | |
730 ReceivedData (packet, tcpHeader); | 783 ReceivedData (packet, tcpHeader); |
731 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); | 784 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); |
732 NS_LOG_LOGIC ("SYN_SENT -> ESTABLISHED"); | |
733 } | 785 } |
734 else if (tcpflags == TcpHeader::ACK) | 786 else if (tcpflags == TcpHeader::ACK) |
735 { // Ignore ACK in SYN_SENT | 787 { // Ignore ACK in SYN_SENT |
736 } | 788 } |
737 else if (tcpflags == TcpHeader::SYN) | 789 else if (tcpflags == TcpHeader::SYN) |
738 { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK | 790 { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK |
791 NS_LOG_INFO ("SYN_SENT -> SYN_RCVD"); | |
739 m_state = SYN_RCVD; | 792 m_state = SYN_RCVD; |
740 m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNum ber32 (1)); | 793 m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNum ber32 (1)); |
741 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 794 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); |
742 NS_LOG_LOGIC ("SYN_SENT -> SYN_RCVD"); | |
743 } | 795 } |
744 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK) | 796 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK) |
745 && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()) | 797 && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()) |
746 { // Handshake completed | 798 { // Handshake completed |
799 NS_LOG_INFO ("SYN_SENT -> ESTABLISHED"); | |
747 m_state = ESTABLISHED; | 800 m_state = ESTABLISHED; |
748 m_connected = true; | 801 m_connected = true; |
802 m_retxEvent.Cancel (); | |
749 m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNum ber32 (1)); | 803 m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNum ber32 (1)); |
750 ++m_nextTxSequence; | 804 m_highTxMark = ++m_nextTxSequence; |
751 m_txBuffer.SetHeadSequence (m_nextTxSequence); | 805 m_txBuffer.SetHeadSequence (m_nextTxSequence); |
752 SendEmptyPacket (TcpHeader::ACK); | 806 SendEmptyPacket (TcpHeader::ACK); |
753 if (GetTxAvailable () > 0) | 807 if (GetTxAvailable () > 0) |
754 { | 808 { |
755 NotifySend (GetTxAvailable ()); | 809 NotifySend (GetTxAvailable ()); |
756 } | 810 } |
757 SendPendingData (m_connected); | 811 SendPendingData (m_connected); |
758 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); | 812 Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); |
759 NS_LOG_LOGIC ("SYN_SENT -> ESTABLISHED"); | 813 } |
760 } | 814 else |
761 else if (m_rxBuffer.MaxRxSequence () >= tcpHeader.GetSequenceNumber ()) | |
762 { // Other in-sequence input | 815 { // Other in-sequence input |
763 CloseAndNotify (); | 816 CloseAndNotify (); |
764 if (tcpflags != TcpHeader::RST) | 817 if (tcpflags != TcpHeader::RST) |
765 { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags | 818 { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags |
766 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); | 819 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); |
767 SendRST (); | 820 SendRST (); |
768 } | 821 } |
769 } | 822 } |
770 } | 823 } |
771 | 824 |
772 /** Received a packet upon SYN_RCVD */ | 825 /** Received a packet upon SYN_RCVD */ |
773 void | 826 void |
774 TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader, | 827 TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader, |
775 const Address& fromAddress, const Address& toAddr ess) | 828 const Address& fromAddress, const Address& toAddr ess) |
776 { | 829 { |
777 NS_LOG_FUNCTION (this << tcpHeader); | 830 NS_LOG_FUNCTION (this << tcpHeader); |
778 | 831 |
779 // Extract the flags. PSH and URG are not honoured. | 832 // Extract the flags. PSH and URG are not honoured. |
780 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 833 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); |
781 | 834 |
782 if (tcpflags == 0) | 835 if (tcpflags == 0 || |
783 { // Bare data, accept it and move to ESTABLISHED state. This is not a norma l behaviour. | 836 (tcpflags == TcpHeader::ACK |
784 m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPor t ()); | 837 && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())) |
785 NotifyNewConnectionCreated (this, fromAddress); | 838 { // If it is bare data, accept it and move to ESTABLISHED state. This is |
839 // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the | |
840 // handshake is completed nicely. | |
841 NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED"); | |
786 m_state = ESTABLISHED; | 842 m_state = ESTABLISHED; |
787 m_connected = true; | 843 m_connected = true; |
788 // Always respond to first data packet to speed up the connection. | 844 m_retxEvent.Cancel (); |
789 // Remove to get the behaviour of old NS-3 code. | 845 m_highTxMark = ++m_nextTxSequence; |
790 m_delAckCount = m_delAckMaxCount; | |
791 ReceivedData (packet, tcpHeader); | |
792 NS_LOG_LOGIC ("SYN_RCVD -> ESTABLISHED"); | |
793 } | |
794 else if (tcpflags == TcpHeader::ACK | |
795 && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()) | |
796 { // Handshake completed. | |
797 m_state = ESTABLISHED; | |
798 m_connected = true; | |
799 ++m_nextTxSequence; | |
800 m_txBuffer.SetHeadSequence (m_nextTxSequence); | 846 m_txBuffer.SetHeadSequence (m_nextTxSequence); |
801 m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPor t ()); | 847 m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPor t ()); |
802 // Always respond to first data packet to speed up the connection. | 848 // Always respond to first data packet to speed up the connection. |
803 // Remove to get the behaviour of old NS-3 code. | 849 // Remove to get the behaviour of old NS-3 code. |
804 m_delAckCount = m_delAckMaxCount; | 850 m_delAckCount = m_delAckMaxCount; |
805 ReceivedAck (packet, tcpHeader); | 851 ReceivedAck (packet, tcpHeader); |
806 NotifyNewConnectionCreated (this, fromAddress); | 852 NotifyNewConnectionCreated (this, fromAddress); |
807 NS_LOG_LOGIC ("SYN_RCVD -> ESTABLISHED"); | |
808 } | 853 } |
809 else if (tcpflags == TcpHeader::SYN) | 854 else if (tcpflags == TcpHeader::SYN) |
810 { // Probably the peer lost my SYN+ACK | 855 { // Probably the peer lost my SYN+ACK |
811 m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNum ber32 (1)); | 856 m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNum ber32 (1)); |
812 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 857 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); |
813 } | 858 } |
814 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK)) | 859 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK)) |
815 { | 860 { |
816 PeerClose (packet, tcpHeader); | 861 if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ()) |
817 if (m_rxBuffer.Finished ()) | 862 { // In-sequence FIN before connection complete. Set up connection and c lose. |
818 { | 863 m_connected = true; |
819 m_state = CLOSE_WAIT; | 864 m_retxEvent.Cancel (); |
820 NS_LOG_LOGIC ("SYN_RCVD -> CLOSE_WAIT"); | 865 m_highTxMark = ++m_nextTxSequence; |
821 } | 866 m_txBuffer.SetHeadSequence (m_nextTxSequence); |
822 } | 867 m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPee rPort ()); |
823 else if (m_rxBuffer.MaxRxSequence () >= tcpHeader.GetSequenceNumber ()) | 868 PeerClose (packet, tcpHeader); |
869 } | |
870 } | |
871 else | |
824 { // Other in-sequence input | 872 { // Other in-sequence input |
825 CloseAndNotify (); | 873 CloseAndNotify (); |
826 if (tcpflags != TcpHeader::RST) | 874 if (tcpflags != TcpHeader::RST) |
827 { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags | 875 { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags |
828 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); | 876 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); |
829 SendRST (); | 877 SendRST (); |
830 } | 878 } |
831 } | 879 } |
832 } | 880 } |
833 | 881 |
834 /** Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */ | 882 /** Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */ |
835 void | 883 void |
836 TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 884 TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
837 { | 885 { |
838 NS_LOG_FUNCTION (this << tcpHeader); | 886 NS_LOG_FUNCTION (this << tcpHeader); |
839 | 887 |
840 // Extract the flags. PSH and URG are not honoured. | 888 // Extract the flags. PSH and URG are not honoured. |
841 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 889 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); |
842 | 890 |
843 if (tcpflags == 0) | 891 if (packet->GetSize () > 0) |
844 { // Bare data, accept it | 892 { // Bare data, accept it |
845 ReceivedData (packet, tcpHeader); | 893 ReceivedData (packet, tcpHeader); |
846 } | 894 } |
847 else if (tcpflags == TcpHeader::ACK) | 895 else if (tcpflags == TcpHeader::ACK) |
848 { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2 | 896 { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2 |
849 ReceivedAck (packet, tcpHeader); | 897 ReceivedAck (packet, tcpHeader); |
850 if (m_state == FIN_WAIT_1 && tcpHeader.GetSequenceNumber () == m_rxBuffer. NextRxSequence ()) | 898 if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0 && |
899 tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1)) | |
851 { // This ACK corresponds to the FIN sent | 900 { // This ACK corresponds to the FIN sent |
901 NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2"); | |
852 m_state = FIN_WAIT_2; | 902 m_state = FIN_WAIT_2; |
853 NS_LOG_LOGIC ("FIN_WAIT_1 -> FIN_WAIT_2"); | |
854 } | 903 } |
855 } | 904 } |
856 else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader ::ACK)) | 905 else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader ::ACK)) |
857 { // Got FIN, respond with ACK and move to next state | 906 { // Got FIN, respond with ACK and move to next state |
907 if (tcpflags & TcpHeader::ACK) | |
908 { // Process the ACK first | |
909 ReceivedAck (packet, tcpHeader); | |
910 } | |
858 m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber ()); | 911 m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber ()); |
859 if (m_rxBuffer.Finished ()) | 912 } |
860 { // Action only if the FIN received is in-sequence | 913 else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader ::ACK)) |
861 SendEmptyPacket (TcpHeader::ACK); | 914 { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission |
862 if (m_state == FIN_WAIT_1 && tcpflags == TcpHeader::FIN) | 915 return; |
863 { | 916 } |
864 m_state = CLOSING; | 917 else |
865 if (!m_shutdownRecv) NotifyDataRecv (); | 918 { // This is a RST or bad flags |
866 NS_LOG_LOGIC ("FIN_WAIT_1 -> CLOSING"); | |
867 } | |
868 else if (m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) | |
869 { | |
870 m_state = TIME_WAIT; | |
871 if (!m_shutdownRecv) NotifyDataRecv (); | |
872 NS_LOG_LOGIC ("moved to TIME_WAIT state"); | |
873 // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL t ime | |
874 // but this move is not yet implemeneted. Is this necessary? | |
875 } | |
876 } | |
877 } | |
878 else if (m_rxBuffer.MaxRxSequence () >= tcpHeader.GetSequenceNumber ()) | |
879 { // This is a SYN or SYN+ACK or RST or bad flags | |
880 CloseAndNotify (); | 919 CloseAndNotify (); |
881 if (tcpflags != TcpHeader::RST) | 920 if (tcpflags != TcpHeader::RST) |
882 { | 921 { |
883 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); | 922 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); |
884 SendRST (); | 923 SendRST (); |
885 } | 924 } |
925 return; | |
926 } | |
927 | |
928 // Check if the close responder sent an in-sequence FIN, if so, respond ACK | |
929 if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished () ) | |
930 { | |
931 if (m_state == FIN_WAIT_1) | |
932 { | |
933 NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING"); | |
934 m_state = CLOSING; | |
935 if (m_txBuffer.Size () == 0 && | |
936 tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1)) | |
937 { // This ACK corresponds to the FIN sent | |
938 NS_LOG_INFO ("CLOSING -> TIME_WAIT"); | |
939 m_state = TIME_WAIT; | |
940 CancelAllTimers (); | |
941 } | |
942 } | |
943 else if (m_state == FIN_WAIT_2) | |
944 { | |
945 NS_LOG_INFO ("FIN_WAIT_2 -> TIME_WAIT"); | |
946 m_state = TIME_WAIT; | |
947 CancelAllTimers (); | |
948 // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL time | |
949 // but this move is not yet implemeneted. Is this necessary? | |
950 }; | |
951 SendEmptyPacket (TcpHeader::ACK); | |
952 if (!m_shutdownRecv) NotifyDataRecv (); | |
886 } | 953 } |
887 } | 954 } |
888 | 955 |
889 /** Received a packet upon CLOSING */ | 956 /** Received a packet upon CLOSING */ |
890 void | 957 void |
891 TcpSocketBase::ProcessClosing (Ptr<Packet> packet, const TcpHeader& tcpHeader) | 958 TcpSocketBase::ProcessClosing (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
892 { | 959 { |
893 NS_LOG_FUNCTION (this << tcpHeader); | 960 NS_LOG_FUNCTION (this << tcpHeader); |
894 | 961 |
895 // Extract the flags. PSH and URG are not honoured. | 962 // Extract the flags. PSH and URG are not honoured. |
896 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); | 963 uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG); |
897 | 964 |
898 if (tcpflags == TcpHeader::ACK) | 965 if (tcpflags == TcpHeader::ACK) |
899 { | 966 { |
900 if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ()) | 967 if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ()) |
901 { // This ACK corresponds to the FIN sent | 968 { // This ACK corresponds to the FIN sent |
969 NS_LOG_INFO ("CLOSING -> TIME_WAIT"); | |
902 m_state = TIME_WAIT; | 970 m_state = TIME_WAIT; |
903 NS_LOG_LOGIC ("CLOSING -> TIME_WAIT"); | 971 CancelAllTimers (); |
904 // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL time | 972 // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL time |
905 // but this move is not yet implemeneted. Is this necessary? | 973 // but this move is not yet implemeneted. Is this necessary? |
joao.taveira
2010/10/24 18:11:49
Yes, this is necessary otherwise the socket will n
| |
906 } | 974 } |
907 } | 975 } |
908 else if (m_rxBuffer.MaxRxSequence () >= tcpHeader.GetSequenceNumber ()) | 976 else |
909 { | 977 { // CLOSING state means simultaneous close, i.e. no one is sending data to |
978 // anyone. If anything other than ACK is received, respond with a reset. | |
910 CloseAndNotify (); | 979 CloseAndNotify (); |
911 if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader: :ACK)) | 980 if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader: :ACK)) |
912 { // FIN from the peer as well. We can close immediately. | 981 { // FIN from the peer as well. We can close immediately. |
913 SendEmptyPacket (TcpHeader::ACK); | 982 SendEmptyPacket (TcpHeader::ACK); |
914 } | 983 } |
915 else if (tcpflags != TcpHeader::RST) | 984 else if (tcpflags != TcpHeader::RST) |
916 { // Receive of SYN or SYN+ACK or bad flags or pure data | 985 { // Receive of SYN or SYN+ACK or bad flags or pure data |
917 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); | 986 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent."); |
918 SendRST (); | 987 SendRST (); |
919 } | 988 } |
(...skipping 29 matching lines...) Expand all Loading... | |
949 CloseAndNotify (); | 1018 CloseAndNotify (); |
950 } | 1019 } |
951 else | 1020 else |
952 { // Received a SYN or SYN+ACK or bad flags | 1021 { // Received a SYN or SYN+ACK or bad flags |
953 CloseAndNotify (); | 1022 CloseAndNotify (); |
954 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is s ent."); | 1023 NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is s ent."); |
955 SendRST (); | 1024 SendRST (); |
956 } | 1025 } |
957 } | 1026 } |
958 | 1027 |
959 /** Peer sent me a FIN. Close down this socket. */ | 1028 /** Peer sent me a FIN. Remember its sequence in rx buffer. */ |
960 void | 1029 void |
961 TcpSocketBase::PeerClose (Ptr<Packet> p, const TcpHeader& tcpHeader) | 1030 TcpSocketBase::PeerClose (Ptr<Packet> p, const TcpHeader& tcpHeader) |
962 { | 1031 { |
963 NS_LOG_FUNCTION (this << tcpHeader); | 1032 NS_LOG_FUNCTION (this << tcpHeader); |
964 | 1033 |
965 // If FIN is out of sequence, remember it and process new sequence rx | 1034 // Ignore all out of range packets |
966 if (tcpHeader.GetSequenceNumber () != m_rxBuffer.NextRxSequence ()) | 1035 if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence () || |
967 { | 1036 tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ()) |
968 if (tcpHeader.GetSequenceNumber () > m_rxBuffer.NextRxSequence () && | 1037 { |
969 tcpHeader.GetSequenceNumber () <= m_rxBuffer.MaxRxSequence ()) | |
970 { | |
971 m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNu mber32 (p->GetSize ())); | |
972 NS_LOG_LOGIC ("TcpSocketBase " << this << " accpeted FIN at rxseq" << | |
973 tcpHeader.GetSequenceNumber () << | |
974 " nextRxSeq " << m_rxBuffer.NextRxSequence ()); | |
975 ReceivedData (p, tcpHeader); | |
976 } | |
977 return; | 1038 return; |
978 } | 1039 }; |
979 // If FIN is in sequence with new data, call ReceivedData | 1040 // For any case, remember the FIN position in rx buffer first |
980 if (tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()) > m_rxBu ffer.NextRxSequence ()) | 1041 m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 ( p->GetSize ())); |
1042 NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + Seque nceNumber32 (p->GetSize ())); | |
1043 // If there is any piggybacked data, process it | |
1044 if (p->GetSize ()) | |
981 { | 1045 { |
982 ReceivedData (p, tcpHeader); | 1046 ReceivedData (p, tcpHeader); |
983 // Uncomment to get the old NS-3 behaviour that if a FIN is piggybacked wi th data, | 1047 } |
984 // the data and the FIN are ACKed separately. RFC didn't require this. | 1048 // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoP eerClose |
985 //SendEmptyPacket (TcpHeader::ACK); | 1049 if (! m_rxBuffer.Finished ()) |
986 } | 1050 { |
987 // For all in-sequence FIN, close the socket immediately | 1051 return; |
988 m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 ( p->GetSize ())); | 1052 }; |
989 States_t saveState = m_state; // Used to see if app responds | 1053 |
990 NS_LOG_LOGIC ("TcpSocketBase " << this << " peer close, state " << m_state); | 1054 // Simultaneous close: Application invoked Close() when we are processing this FIN packet |
1055 if (m_state == FIN_WAIT_1) | |
1056 { | |
1057 NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING"); | |
1058 m_state = CLOSING; | |
1059 return; | |
1060 } | |
1061 | |
1062 DoPeerClose (); // Change state, respond with ACK | |
1063 } | |
1064 | |
1065 /** Received a in-sequence FIN. Close down this socket. */ | |
1066 void | |
1067 TcpSocketBase::DoPeerClose (void) | |
1068 { | |
1069 NS_ASSERT (m_state == ESTABLISHED || m_state == SYN_RCVD); | |
1070 | |
1071 // Move the state to CLOSE_WAIT | |
1072 NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT"); | |
1073 m_state = CLOSE_WAIT; | |
1074 | |
991 if (!m_closeNotified) | 1075 if (!m_closeNotified) |
992 { | 1076 { |
993 NS_LOG_LOGIC ("TCP " << this << " calling AppCloseRequest"); | 1077 // The normal behaviour for an application is that, when the peer sent a i n-sequence |
1078 // FIN, the app should prepare to close. The app has two choices at this p oint: either | |
1079 // respond with ShutdownSend() call to declare that it has nothing more to send and | |
1080 // the socket can be closed immediately; or remember the peer's close requ est, wait | |
1081 // until all its existing data are pushed into the TCP socket, then call C lose() | |
1082 // explicitly. | |
1083 NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose"); | |
994 if (!m_closeNotified) NotifyNormalClose (); | 1084 if (!m_closeNotified) NotifyNormalClose (); |
995 m_closeNotified = true; | 1085 m_closeNotified = true; |
996 } | 1086 } |
997 NS_LOG_LOGIC ("TcpSocketBase " << this << " peer close, state after " << m_sta te); | 1087 if (m_shutdownSend) |
998 if (m_state == saveState) | 1088 { // The application declares that it would not sent any more, close this so cket |
1089 Close(); | |
1090 } | |
1091 else | |
999 { // Need to ack, the application will close later | 1092 { // Need to ack, the application will close later |
1000 SendEmptyPacket (TcpHeader::ACK); | 1093 SendEmptyPacket (TcpHeader::ACK); |
1001 } | 1094 } |
1002 if (m_state == LAST_ACK) | 1095 if (m_state == LAST_ACK) |
1003 { | 1096 { |
1004 NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1"); | 1097 NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1"); |
1005 m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (), | 1098 m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (), |
1006 &TcpSocketBase::LastAckTimeout, this ); | 1099 &TcpSocketBase::LastAckTimeout, this ); |
1007 } | 1100 } |
1008 } | 1101 } |
(...skipping 12 matching lines...) Expand all Loading... | |
1021 CancelAllTimers (); | 1114 CancelAllTimers (); |
1022 } | 1115 } |
1023 | 1116 |
1024 /** Send an empty packet with specified TCP flags */ | 1117 /** Send an empty packet with specified TCP flags */ |
1025 void | 1118 void |
1026 TcpSocketBase::SendEmptyPacket (uint8_t flags) | 1119 TcpSocketBase::SendEmptyPacket (uint8_t flags) |
1027 { | 1120 { |
1028 NS_LOG_FUNCTION (this << (uint32_t)flags); | 1121 NS_LOG_FUNCTION (this << (uint32_t)flags); |
1029 Ptr<Packet> p = Create<Packet> (); | 1122 Ptr<Packet> p = Create<Packet> (); |
1030 TcpHeader header; | 1123 TcpHeader header; |
1124 SequenceNumber32 s = m_nextTxSequence; | |
1031 | 1125 |
1032 if (m_endPoint == 0) | 1126 if (m_endPoint == 0) |
1033 { | 1127 { |
1034 NS_LOG_WARN ("Failed to send empty packet due to null endpoint"); | 1128 NS_LOG_WARN ("Failed to send empty packet due to null endpoint"); |
1035 return; | 1129 return; |
1036 } | 1130 } |
1037 if (flags & TcpHeader::FIN) | 1131 if (flags & TcpHeader::FIN) |
1038 { | 1132 { |
1039 flags |= TcpHeader::ACK; | 1133 flags |= TcpHeader::ACK; |
1040 } | 1134 } |
1135 else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING) | |
1136 { | |
1137 ++s; | |
1138 } | |
1041 | 1139 |
1042 header.SetFlags (flags); | 1140 header.SetFlags (flags); |
1043 header.SetSequenceNumber (m_nextTxSequence); | 1141 header.SetSequenceNumber (s); |
1044 header.SetAckNumber (m_rxBuffer.NextRxSequence ()); | 1142 header.SetAckNumber (m_rxBuffer.NextRxSequence ()); |
1045 header.SetSourcePort (m_endPoint->GetLocalPort ()); | 1143 header.SetSourcePort (m_endPoint->GetLocalPort ()); |
1046 header.SetDestinationPort (m_endPoint->GetPeerPort ()); | 1144 header.SetDestinationPort (m_endPoint->GetPeerPort ()); |
1047 header.SetWindowSize (AdvertisedWindowSize ()); | 1145 header.SetWindowSize (AdvertisedWindowSize ()); |
1048 m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), m_endPoint->GetP eerAddress (), m_boundnetdevice); | 1146 m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), m_endPoint->GetP eerAddress (), m_boundnetdevice); |
1049 Time rto = m_rtt->RetransmitTimeout (); | 1147 m_rto = m_rtt->RetransmitTimeout (); |
1050 bool hasSyn = flags & TcpHeader::SYN; | 1148 bool hasSyn = flags & TcpHeader::SYN; |
1051 bool hasFin = flags & TcpHeader::FIN; | 1149 bool hasFin = flags & TcpHeader::FIN; |
1052 bool isAck = flags == TcpHeader::ACK; | 1150 bool isAck = flags == TcpHeader::ACK; |
1053 if (hasSyn) | 1151 if (hasSyn) |
1054 { // Exponential backoff of connection time out | 1152 { // Exponential backoff of connection time out |
1055 rto = m_cnTimeout; | 1153 m_rto = m_cnTimeout; |
1056 m_cnTimeout = m_cnTimeout + m_cnTimeout; | 1154 m_cnTimeout = m_cnTimeout + m_cnTimeout; |
joao.taveira
2010/10/24 18:11:49
Since m_cnTimeout is set externally, some nicer wa
| |
1057 m_cnCount--; | 1155 m_cnCount--; |
1058 } | 1156 } |
1059 if (flags & TcpHeader::ACK) | 1157 if (flags & TcpHeader::ACK) |
1060 { // If sending an ACK, cancel the delay ACK as well | 1158 { // If sending an ACK, cancel the delay ACK as well |
1061 m_delAckEvent.Cancel (); | 1159 m_delAckEvent.Cancel (); |
1062 m_delAckCount = 0; | 1160 m_delAckCount = 0; |
1063 } | 1161 } |
1064 if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck ) | 1162 if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck ) |
1065 { // Setup ReTx timer if not have one at the moment | 1163 { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost |
1066 NS_LOG_LOGIC ("Schedule retransmission timeout at time " | 1164 NS_LOG_LOGIC ("Schedule retransmission timeout at time " |
1067 << Simulator::Now ().GetSeconds () << " to expire at time " | 1165 << Simulator::Now ().GetSeconds () << " to expire at time " |
1068 << (Simulator::Now () + rto).GetSeconds ()); | 1166 << (Simulator::Now () + m_rto.Get ()).GetSeconds ()); |
1069 m_retxEvent = Simulator::Schedule (rto, &TcpSocketBase::ReTxTimeout, this) ; | 1167 m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::SendEmptyPacket, this, flags); |
joao.taveira
2010/10/24 18:11:49
Not sure this works the way you think it should. Y
| |
1070 } | 1168 } |
1071 } | 1169 } |
1072 | 1170 |
1073 /** This function closes the endpoint completely. Called upon RST_TX action. */ | 1171 /** This function closes the endpoint completely. Called upon RST_TX action. */ |
1074 void | 1172 void |
1075 TcpSocketBase::SendRST (void) | 1173 TcpSocketBase::SendRST (void) |
1076 { | 1174 { |
1077 NS_LOG_FUNCTION (this); | 1175 NS_LOG_FUNCTION (this); |
1078 SendEmptyPacket (TcpHeader::RST); | 1176 SendEmptyPacket (TcpHeader::RST); |
1079 NotifyErrorClose (); | 1177 NotifyErrorClose (); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1131 TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h, | 1229 TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h, |
1132 const Address& fromAddress, const Address& toAddres s) | 1230 const Address& fromAddress, const Address& toAddres s) |
1133 { | 1231 { |
1134 // Get port and address from peer (connecting host) | 1232 // Get port and address from peer (connecting host) |
1135 m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIp v4 (), | 1233 m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIp v4 (), |
1136 InetSocketAddress::ConvertFrom (toAddress).GetPo rt (), | 1234 InetSocketAddress::ConvertFrom (toAddress).GetPo rt (), |
1137 InetSocketAddress::ConvertFrom (fromAddress).Get Ipv4 (), | 1235 InetSocketAddress::ConvertFrom (fromAddress).Get Ipv4 (), |
1138 InetSocketAddress::ConvertFrom (fromAddress).Get Port ()); | 1236 InetSocketAddress::ConvertFrom (fromAddress).Get Port ()); |
1139 | 1237 |
1140 // Change the cloned socket from LISTEN state to SYN_RCVD | 1238 // Change the cloned socket from LISTEN state to SYN_RCVD |
1239 NS_LOG_INFO ("LISTEN -> SYN_RCVD"); | |
1141 m_state = SYN_RCVD; | 1240 m_state = SYN_RCVD; |
1142 NS_LOG_LOGIC ("LISTEN -> SYN_RCVD"); | |
1143 SetupCallback (); | 1241 SetupCallback (); |
1144 // Set the sequence number and send SYN+ACK | 1242 // Set the sequence number and send SYN+ACK |
1145 m_rxBuffer.SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1)); | 1243 m_rxBuffer.SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1)); |
1146 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); | 1244 SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK); |
1147 } | 1245 } |
1148 | 1246 |
1149 void | 1247 void |
1150 TcpSocketBase::ConnectionSucceeded () | 1248 TcpSocketBase::ConnectionSucceeded () |
1151 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can | 1249 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can |
1152 // be called as a scheduled event | 1250 // be called as a scheduled event |
(...skipping 11 matching lines...) Expand all Loading... | |
1164 { | 1262 { |
1165 NS_LOG_INFO ("TcpSocketImpl::SendPendingData: No endpoint; m_shutdownSend= " << m_shutdownSend); | 1263 NS_LOG_INFO ("TcpSocketImpl::SendPendingData: No endpoint; m_shutdownSend= " << m_shutdownSend); |
1166 return false; // Is this the right way to handle this condition? | 1264 return false; // Is this the right way to handle this condition? |
1167 } | 1265 } |
1168 uint32_t nPacketsSent = 0; | 1266 uint32_t nPacketsSent = 0; |
1169 while (m_txBuffer.SizeFromSequence (m_nextTxSequence)) | 1267 while (m_txBuffer.SizeFromSequence (m_nextTxSequence)) |
1170 { | 1268 { |
1171 uint32_t w = AvailableWindow (); // Get available window size | 1269 uint32_t w = AvailableWindow (); // Get available window size |
1172 NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" << | 1270 NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" << |
1173 " w " << w << | 1271 " w " << w << |
1174 " rxwin " << m_rxWindowSize << | 1272 " rxwin " << m_rWnd << |
1175 " segsize " << m_segmentSize << | 1273 " segsize " << m_segmentSize << |
1176 " nextTxSeq " << m_nextTxSequence << | 1274 " nextTxSeq " << m_nextTxSequence << |
1177 " highestRxAck " << m_txBuffer.HeadSequence () << | 1275 " highestRxAck " << m_txBuffer.HeadSequence () << |
1178 " pd->Size " << m_txBuffer.Size () << | 1276 " pd->Size " << m_txBuffer.Size () << |
1179 " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence )); | 1277 " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence )); |
1180 // Quit if send disallowed | 1278 // Quit if send disallowed |
1181 if (m_shutdownSend) | 1279 if (m_shutdownSend) |
1182 { | 1280 { |
1183 m_errno = ERROR_SHUTDOWN; | 1281 m_errno = ERROR_SHUTDOWN; |
1184 return false; | 1282 return false; |
1185 } | 1283 } |
1186 // Stop sending if we need to wait for a larger Tx window | 1284 // Stop sending if we need to wait for a larger Tx window |
1187 if (w < m_segmentSize && m_txBuffer.SizeFromSequence (m_nextTxSequence) > w) | 1285 if (w < m_segmentSize && m_txBuffer.SizeFromSequence (m_nextTxSequence) > w) |
1188 { | 1286 { |
1189 break; // No more | 1287 break; // No more |
1190 } | 1288 } |
1191 uint32_t s = std::min (w, m_segmentSize); // Send no more than window | 1289 uint32_t s = std::min (w, m_segmentSize); // Send no more than window |
1192 Ptr<Packet> p = m_txBuffer.CopyFromSequence (s, m_nextTxSequence); | 1290 Ptr<Packet> p = m_txBuffer.CopyFromSequence (s, m_nextTxSequence); |
1193 NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" << | 1291 NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" << |
1194 " txseq " << m_nextTxSequence << | 1292 " txseq " << m_nextTxSequence << |
1195 " s " << s << " datasize " << p->GetSize ()); | 1293 " s " << s << " datasize " << p->GetSize ()); |
1196 uint8_t flags = 0; | 1294 uint8_t flags = 0; |
1197 uint32_t sz = p->GetSize (); // Size of packet | 1295 uint32_t sz = p->GetSize (); // Size of packet |
1198 uint32_t remainingData = m_txBuffer.SizeFromSequence (m_nextTxSequence + S equenceNumber32 (sz)); | 1296 uint32_t remainingData = m_txBuffer.SizeFromSequence (m_nextTxSequence + S equenceNumber32 (sz)); |
1199 if (m_closeOnEmpty && (remainingData == 0)) | 1297 if (m_closeOnEmpty && (remainingData == 0)) |
1200 { | 1298 { |
1201 flags = TcpHeader::FIN; | 1299 flags = TcpHeader::FIN; |
1202 m_state = FIN_WAIT_1; | 1300 if (m_state == ESTABLISHED) |
1203 NS_LOG_LOGIC ("moved to FIN_WAIT_1 state"); | 1301 { // On active close: I am the first one to send FIN |
1302 NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1"); | |
1303 m_state = FIN_WAIT_1; | |
1304 } | |
1305 else | |
1306 { // On passive close: Peer sent me FIN already | |
1307 NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK"); | |
1308 m_state = LAST_ACK; | |
1309 } | |
1204 } | 1310 } |
1205 if (withAck) | 1311 if (withAck) |
1206 { | 1312 { |
1207 flags |= TcpHeader::ACK; | 1313 flags |= TcpHeader::ACK; |
1208 } | 1314 } |
1209 TcpHeader header; | 1315 TcpHeader header; |
1210 header.SetFlags (flags); | 1316 header.SetFlags (flags); |
1211 header.SetSequenceNumber (m_nextTxSequence); | 1317 header.SetSequenceNumber (m_nextTxSequence); |
1212 header.SetAckNumber (m_rxBuffer.NextRxSequence ()); | 1318 header.SetAckNumber (m_rxBuffer.NextRxSequence ()); |
1213 header.SetSourcePort (m_endPoint->GetLocalPort ()); | 1319 header.SetSourcePort (m_endPoint->GetLocalPort ()); |
1214 header.SetDestinationPort (m_endPoint->GetPeerPort ()); | 1320 header.SetDestinationPort (m_endPoint->GetPeerPort ()); |
1215 header.SetWindowSize (AdvertisedWindowSize ()); | 1321 header.SetWindowSize (AdvertisedWindowSize ()); |
1216 if (m_retxEvent.IsExpired () ) | 1322 if (m_retxEvent.IsExpired () ) |
1217 { // Schedule retransmit | 1323 { // Schedule retransmit |
1218 Time rto = m_rtt->RetransmitTimeout (); | 1324 m_rto = m_rtt->RetransmitTimeout (); |
1219 NS_LOG_LOGIC (this << " SendPendingData Schedule ReTxTimeout at time " << | 1325 NS_LOG_LOGIC (this << " SendPendingData Schedule ReTxTimeout at time " << |
1220 Simulator::Now ().GetSeconds () << " to expire at time " << | 1326 Simulator::Now ().GetSeconds () << " to expire at time " << |
1221 (Simulator::Now () + rto).GetSeconds () ); | 1327 (Simulator::Now () + m_rto.Get ()).GetSeconds () ); |
1222 m_retxEvent = Simulator::Schedule (rto, &TcpSocketBase::ReTxTimeout, t his); | 1328 m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this); |
1223 } | 1329 } |
1224 NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec); | 1330 NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec); |
1225 m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), | 1331 m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), |
1226 m_endPoint->GetPeerAddress (), m_boundnetdevice); | 1332 m_endPoint->GetPeerAddress (), m_boundnetdevice); |
1227 m_rtt->SentSeq (m_nextTxSequence, sz); // notify the RTT | 1333 m_rtt->SentSeq (m_nextTxSequence, sz); // notify the RTT |
1228 // Notify the application of the data being sent | 1334 // Notify the application of the data being sent |
1229 Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz); | 1335 Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz); |
1230 nPacketsSent++; // Count sent this loop | 1336 nPacketsSent++; // Count sent this loop |
1231 m_nextTxSequence += sz; // Advance next tx sequence | 1337 m_nextTxSequence += sz; // Advance next tx sequence |
1232 // Update highTxMark | 1338 // Update highTxMark |
1233 m_highTxMark = std::max (m_nextTxSequence, m_highTxMark); | 1339 m_highTxMark = std::max (m_nextTxSequence, m_highTxMark); |
1234 } | 1340 } |
1235 NS_LOG_LOGIC ("SendPendingData Sent " << nPacketsSent << " packets"); | 1341 NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets"); |
1236 NS_LOG_LOGIC ("RETURN SendPendingData"); | |
1237 return (nPacketsSent > 0); | 1342 return (nPacketsSent > 0); |
1238 } | 1343 } |
1239 | 1344 |
1240 uint32_t | 1345 uint32_t |
1241 TcpSocketBase::UnAckDataCount () | 1346 TcpSocketBase::UnAckDataCount () |
1242 { | 1347 { |
1243 NS_LOG_FUNCTION (this); | 1348 NS_LOG_FUNCTION (this); |
1244 return m_nextTxSequence - m_txBuffer.HeadSequence (); | 1349 return m_nextTxSequence.Get () - m_txBuffer.HeadSequence (); |
1245 } | 1350 } |
1246 | 1351 |
1247 uint32_t | 1352 uint32_t |
1248 TcpSocketBase::BytesInFlight () | 1353 TcpSocketBase::BytesInFlight () |
1249 { | 1354 { |
1250 NS_LOG_FUNCTION (this); | 1355 NS_LOG_FUNCTION (this); |
1251 return m_highTxMark - m_txBuffer.HeadSequence (); | 1356 return m_highTxMark.Get () - m_txBuffer.HeadSequence (); |
1252 } | 1357 } |
1253 | 1358 |
1254 uint32_t | 1359 uint32_t |
1255 TcpSocketBase::Window () | 1360 TcpSocketBase::Window () |
1256 { | 1361 { |
1257 NS_LOG_FUNCTION (this); | 1362 NS_LOG_FUNCTION (this); |
1258 return m_rxWindowSize; | 1363 return m_rWnd; |
1259 } | 1364 } |
1260 | 1365 |
1261 uint32_t | 1366 uint32_t |
1262 TcpSocketBase::AvailableWindow () | 1367 TcpSocketBase::AvailableWindow () |
1263 { | 1368 { |
1264 NS_LOG_FUNCTION_NOARGS (); | 1369 NS_LOG_FUNCTION_NOARGS (); |
1265 uint32_t unack = UnAckDataCount (); // Number of outstanding bytes | 1370 uint32_t unack = UnAckDataCount (); // Number of outstanding bytes |
1266 uint32_t win = Window (); // Number of bytes allowed to be outstanding | 1371 uint32_t win = Window (); // Number of bytes allowed to be outstanding |
1267 NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win); | 1372 NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win); |
1268 return (win < unack) ? 0 : (win - unack); | 1373 return (win < unack) ? 0 : (win - unack); |
1269 } | 1374 } |
1270 | 1375 |
1271 uint16_t | 1376 uint16_t |
1272 TcpSocketBase::AdvertisedWindowSize () | 1377 TcpSocketBase::AdvertisedWindowSize () |
1273 { | 1378 { |
1274 uint32_t max = 0xffff; | 1379 uint32_t max = 0xffff; |
1275 return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), max); | 1380 return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), max); |
1276 } | 1381 } |
1277 | 1382 |
1278 // Receipt of new packet, put into Rx buffer | 1383 // Receipt of new packet, put into Rx buffer |
1279 void | 1384 void |
1280 TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader) | 1385 TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader) |
1281 { | 1386 { |
1282 NS_LOG_FUNCTION (this << tcpHeader); | 1387 NS_LOG_FUNCTION (this << tcpHeader); |
1283 NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () << | 1388 NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () << |
1284 " ack " << tcpHeader.GetAckNumber () << | 1389 " ack " << tcpHeader.GetAckNumber () << |
1285 " pkt size " << p->GetSize () ); | 1390 " pkt size " << p->GetSize () ); |
1286 | 1391 |
1287 // Put into Rx buffer | 1392 // Put into Rx buffer |
1288 States_t origState = m_state; | 1393 SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence (); |
1289 SequenceNumber32 origSeq = m_rxBuffer.NextRxSequence (); | |
1290 if (!m_rxBuffer.Add (p, tcpHeader)) | 1394 if (!m_rxBuffer.Add (p, tcpHeader)) |
1291 { // Insert failed: No data or RX buffer full | 1395 { // Insert failed: No data or RX buffer full |
1292 SendEmptyPacket (TcpHeader::ACK); | 1396 SendEmptyPacket (TcpHeader::ACK); |
1293 return; | 1397 return; |
1294 } | 1398 } |
1295 // Now send a new ACK packet acknowledging all received and delivered data | 1399 // Now send a new ACK packet acknowledging all received and delivered data |
1296 if (++m_delAckCount >= m_delAckMaxCount) | 1400 if (tcpHeader.GetSequenceNumber () > expectedSeq) |
1297 { | 1401 { // Out of sequence packet: Always ACK |
1298 SendEmptyPacket (TcpHeader::ACK); | 1402 SendEmptyPacket (TcpHeader::ACK); |
1299 } | 1403 } |
1300 else if (m_delAckEvent.IsExpired ()) | 1404 else |
1301 { | 1405 { // In-sequence packet: ACK if delayed ack count allows |
1302 m_delAckEvent = Simulator::Schedule (m_delAckTimeout, &TcpSocketBase::DelA ckTimeout, this); | 1406 if (++m_delAckCount >= m_delAckMaxCount) |
1407 { | |
1408 m_delAckEvent.Cancel (); | |
1409 m_delAckCount = 0; | |
1410 SendEmptyPacket (TcpHeader::ACK); | |
1411 } | |
1412 else if (m_delAckEvent.IsExpired ()) | |
1413 { | |
1414 m_delAckEvent = Simulator::Schedule (m_delAckTimeout, | |
1415 &TcpSocketBase::DelAckTimeout, this); | |
1416 } | |
1303 } | 1417 } |
1304 // Notify app to receive if necessary | 1418 // Notify app to receive if necessary |
1305 if (origSeq < m_rxBuffer.NextRxSequence ()) | 1419 if (expectedSeq < m_rxBuffer.NextRxSequence ()) |
1306 { // NextRxSeq advanced, we have something to send to the app | 1420 { // NextRxSeq advanced, we have something to send to the app |
1307 if (!m_shutdownRecv) NotifyDataRecv (); | 1421 if (!m_shutdownRecv) NotifyDataRecv (); |
1308 // Handle exceptions | 1422 // Handle exceptions |
1309 if (m_closeNotified) | 1423 if (m_closeNotified) |
1310 { | 1424 { |
1311 NS_LOG_LOGIC ("Why TCP " << this << " got data after close notificatio n?"); | 1425 NS_LOG_WARN ("Why TCP " << this << " got data after close notification ?"); |
1312 } | 1426 } |
1313 if ((m_rxBuffer.Finished () || (origState > ESTABLISHED)) && (m_rxBuffer.S ize () == 0)) | 1427 // If we received FIN before and now completed all "holes" in rx buffer, |
1314 { // No more data to forward to app, we can close now | 1428 // invoke peer close procedure |
1315 PeerClose (p, tcpHeader); | 1429 if (m_rxBuffer.Finished () && (tcpHeader.GetFlags() & TcpHeader::FIN) == 0 ) |
1316 } | 1430 { |
1317 } | 1431 DoPeerClose (); |
1318 } | 1432 } |
1433 } | |
1434 } | |
1435 | |
1436 /** Called by ForwardUp() to estimate RTT */ | |
1437 void | |
1438 TcpSocketBase::EstimateRtt (const TcpHeader& tcpHeader) | |
1439 { | |
1440 // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement | |
1441 // (which should be ignored) is handled by m_rtt. Once timestamp option | |
1442 // is implemented, this function would be more elaborated. | |
1443 m_rtt->AckSeq (tcpHeader.GetAckNumber () ); | |
1444 }; | |
1319 | 1445 |
1320 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd() | 1446 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd() |
1321 // when the three-way handshake completed. This cancels retransmission timer | 1447 // when the three-way handshake completed. This cancels retransmission timer |
1322 // and advances Tx window | 1448 // and advances Tx window |
1323 void | 1449 void |
1324 TcpSocketBase::NewAck (SequenceNumber32 const& ack) | 1450 TcpSocketBase::NewAck (SequenceNumber32 const& ack) |
1325 { | 1451 { |
1326 NS_LOG_FUNCTION (this << ack); | 1452 NS_LOG_FUNCTION (this << ack); |
1327 | 1453 |
1328 if (m_state != SYN_RCVD) | 1454 if (m_state != SYN_RCVD) |
1329 { // Set RTO unless the ACK is received in SYN_RCVD state | 1455 { // Set RTO unless the ACK is received in SYN_RCVD state |
1330 NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expir e at " << | 1456 NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expir e at " << |
1331 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)). GetSeconds ()); | 1457 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)). GetSeconds ()); |
1332 m_retxEvent.Cancel (); | 1458 m_retxEvent.Cancel (); |
1333 // On recieving a "New" ack we restart retransmission timer .. RFC 2988 | 1459 // On recieving a "New" ack we restart retransmission timer .. RFC 2988 |
1334 Time rto = m_rtt->RetransmitTimeout (); | 1460 m_rto = m_rtt->RetransmitTimeout (); |
1335 NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " << | 1461 NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " << |
1336 Simulator::Now ().GetSeconds () << " to expire at time " << | 1462 Simulator::Now ().GetSeconds () << " to expire at time " << |
1337 (Simulator::Now () + rto).GetSeconds ()); | 1463 (Simulator::Now () + m_rto.Get ()).GetSeconds ()); |
1338 m_retxEvent = Simulator::Schedule (rto, &TcpSocketBase::ReTxTimeout, this) ; | 1464 m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, thi s); |
1339 } | 1465 } |
1340 if (m_rxWindowSize == 0 && m_persistEvent.IsExpired ()) | 1466 if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ()) |
1341 { // Zero window: Enter persist state to send 1 byte to probe | 1467 { // Zero window: Enter persist state to send 1 byte to probe |
1342 NS_LOG_LOGIC (this << "Enter zerowindow persist state"); | 1468 NS_LOG_LOGIC (this << "Enter zerowindow persist state"); |
1343 NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " << | 1469 NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " << |
1344 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)). GetSeconds ()); | 1470 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)). GetSeconds ()); |
1345 m_retxEvent.Cancel (); | 1471 m_retxEvent.Cancel (); |
1346 NS_LOG_LOGIC ("Schedule persist timeout at time " << | 1472 NS_LOG_LOGIC ("Schedule persist timeout at time " << |
1347 Simulator::Now ().GetSeconds () << " to expire at time " << | 1473 Simulator::Now ().GetSeconds () << " to expire at time " << |
1348 (Simulator::Now () + m_persistTimeout).GetSeconds ()); | 1474 (Simulator::Now () + m_persistTimeout).GetSeconds ()); |
1349 m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::Pe rsistTimeout, this); | 1475 m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::Pe rsistTimeout, this); |
1350 NS_ASSERT (m_persistTimeout == Simulator::GetDelayLeft (m_persistEvent)); | 1476 NS_ASSERT (m_persistTimeout == Simulator::GetDelayLeft (m_persistEvent)); |
1351 } | 1477 } |
1352 // Note the highest ACK and tell app to send more | 1478 // Note the highest ACK and tell app to send more |
1353 NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << | 1479 NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
1354 " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed | 1480 " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed |
1355 m_txBuffer.DiscardUpTo (ack); | 1481 m_txBuffer.DiscardUpTo (ack); |
1356 if (GetTxAvailable () > 0) | 1482 if (GetTxAvailable () > 0) |
1357 { | 1483 { |
1358 NotifySend (GetTxAvailable ()); | 1484 NotifySend (GetTxAvailable ()); |
1359 } | 1485 } |
1360 if (ack > m_nextTxSequence) | 1486 if (ack > m_nextTxSequence) |
1361 { | 1487 { |
1362 m_nextTxSequence = ack; // If advanced | 1488 m_nextTxSequence = ack; // If advanced |
1363 } | 1489 } |
1364 if (m_txBuffer.Size () == 0) | 1490 if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING) |
1365 { // No retransmit timer if no data to retransmit | 1491 { // No retransmit timer if no data to retransmit |
1366 NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expir e at " << | 1492 NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expir e at " << |
1367 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)). GetSeconds ()); | 1493 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)). GetSeconds ()); |
1368 m_retxEvent.Cancel (); | 1494 m_retxEvent.Cancel (); |
1369 } | 1495 } |
1370 // Try to send more data | 1496 // Try to send more data |
1371 SendPendingData (m_connected); | 1497 SendPendingData (m_connected); |
1372 } | 1498 } |
1373 | 1499 |
1374 // Retransmit timeout | 1500 // Retransmit timeout |
1375 void | 1501 void |
1376 TcpSocketBase::ReTxTimeout () | 1502 TcpSocketBase::ReTxTimeout () |
1377 { | 1503 { |
1378 NS_LOG_FUNCTION (this); | 1504 NS_LOG_FUNCTION (this); |
1379 NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().Get Seconds ()); | 1505 NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().Get Seconds ()); |
1380 // If erroneous timeout in closed/timed-wait state, just return | 1506 // If erroneous timeout in closed/timed-wait state, just return |
1381 if (m_state == CLOSED || m_state == TIME_WAIT) return; | 1507 if (m_state == CLOSED || m_state == TIME_WAIT) return; |
1382 // If all data are received, just return | 1508 // If all data are received, just return |
1383 if (m_txBuffer.HeadSequence () >= m_nextTxSequence) return; | 1509 if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_nextTxSequence) return; |
1384 | 1510 |
1385 Retransmit (); | 1511 Retransmit (); |
1386 } | 1512 } |
1387 | 1513 |
1388 void | 1514 void |
1389 TcpSocketBase::DelAckTimeout () | 1515 TcpSocketBase::DelAckTimeout (void) |
1390 { | 1516 { |
1517 m_delAckCount = 0; | |
1391 SendEmptyPacket (TcpHeader::ACK); | 1518 SendEmptyPacket (TcpHeader::ACK); |
1392 } | 1519 } |
1393 | 1520 |
1394 void | 1521 void |
1395 TcpSocketBase::LastAckTimeout () | 1522 TcpSocketBase::LastAckTimeout (void) |
1396 { | 1523 { |
1524 NS_LOG_FUNCTION (this); | |
1525 | |
1397 m_lastAckEvent.Cancel (); | 1526 m_lastAckEvent.Cancel (); |
1398 if (m_state == LAST_ACK) | 1527 if (m_state == LAST_ACK) |
1399 { | 1528 { |
1400 CloseAndNotify (); | 1529 CloseAndNotify (); |
1401 } | 1530 } |
1402 if (!m_closeNotified) | 1531 if (!m_closeNotified) |
1403 { | 1532 { |
1404 m_closeNotified = true; | 1533 m_closeNotified = true; |
1405 } | 1534 } |
1406 } | 1535 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1449 if (m_cnCount > 0) | 1578 if (m_cnCount > 0) |
1450 { | 1579 { |
1451 SendEmptyPacket (TcpHeader::SYN); | 1580 SendEmptyPacket (TcpHeader::SYN); |
1452 } | 1581 } |
1453 else | 1582 else |
1454 { | 1583 { |
1455 NotifyConnectionFailed (); | 1584 NotifyConnectionFailed (); |
1456 } | 1585 } |
1457 return; | 1586 return; |
1458 } | 1587 } |
1459 // Retransmit non-data packet: Only if in FIN_WAIT_1 state | 1588 // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state |
1460 if (m_txBuffer.Size () == 0) | 1589 if (m_txBuffer.Size () == 0) |
1461 { | 1590 { |
1462 if (m_state == FIN_WAIT_1) | 1591 if (m_state == FIN_WAIT_1 || m_state == CLOSING) |
1463 { // Must have lost FIN, re-send | 1592 { // Must have lost FIN, re-send |
1464 SendEmptyPacket (TcpHeader::FIN); | 1593 SendEmptyPacket (TcpHeader::FIN); |
1465 } | 1594 } |
1466 return; | 1595 return; |
1467 } | 1596 } |
1468 // Retransmit a data packet: Extract data | 1597 // Retransmit a data packet: Extract data |
1469 Ptr<Packet> p = m_txBuffer.CopyFromSequence (m_segmentSize, m_txBuffer.HeadSeq uence ()); | 1598 Ptr<Packet> p = m_txBuffer.CopyFromSequence (m_segmentSize, m_txBuffer.HeadSeq uence ()); |
1470 // Close-on-Empty check | 1599 // Close-on-Empty check |
1471 if (m_closeOnEmpty && m_txBuffer.Size () == p->GetSize ()) | 1600 if (m_closeOnEmpty && m_txBuffer.Size () == p->GetSize ()) |
1472 { | 1601 { |
1473 flags |= TcpHeader::FIN; | 1602 flags |= TcpHeader::FIN; |
1474 } | 1603 } |
1475 // Reset transmission timeout | 1604 // Reset transmission timeout |
1476 NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSe quence ()); | 1605 NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSe quence ()); |
1477 if (m_retxEvent.IsExpired ()) | 1606 if (m_retxEvent.IsExpired ()) |
1478 { | 1607 { |
1479 Time rto = m_rtt->RetransmitTimeout (); | 1608 m_rto = m_rtt->RetransmitTimeout (); |
1480 NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " << | 1609 NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " << |
1481 Simulator::Now ().GetSeconds () << " to expire at time " << | 1610 Simulator::Now ().GetSeconds () << " to expire at time " << |
1482 (Simulator::Now () + rto).GetSeconds ()); | 1611 (Simulator::Now () + m_rto.Get ()).GetSeconds ()); |
1483 m_retxEvent = Simulator::Schedule (rto, &TcpSocketBase::ReTxTimeout, this) ; | 1612 m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, thi s); |
1484 } | 1613 } |
1485 m_rtt->SentSeq (m_txBuffer.HeadSequence (), p->GetSize ()); | 1614 m_rtt->SentSeq (m_txBuffer.HeadSequence (), p->GetSize ()); |
1486 // And send the packet | 1615 // And send the packet |
1487 TcpHeader tcpHeader; | 1616 TcpHeader tcpHeader; |
1488 tcpHeader.SetSequenceNumber (m_txBuffer.HeadSequence ()); | 1617 tcpHeader.SetSequenceNumber (m_txBuffer.HeadSequence ()); |
1489 tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ()); | 1618 tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ()); |
1490 tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ()); | 1619 tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ()); |
1491 tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ()); | 1620 tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ()); |
1492 tcpHeader.SetFlags (flags); | 1621 tcpHeader.SetFlags (flags); |
1493 tcpHeader.SetWindowSize (AdvertisedWindowSize ()); | 1622 tcpHeader.SetWindowSize (AdvertisedWindowSize ()); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1597 { | 1726 { |
1598 m_persistTimeout = timeout; | 1727 m_persistTimeout = timeout; |
1599 } | 1728 } |
1600 | 1729 |
1601 Time | 1730 Time |
1602 TcpSocketBase::GetPersistTimeout (void) const | 1731 TcpSocketBase::GetPersistTimeout (void) const |
1603 { | 1732 { |
1604 return m_persistTimeout; | 1733 return m_persistTimeout; |
1605 } | 1734 } |
1606 | 1735 |
1607 void | 1736 bool |
1608 TcpSocketBase::SetAllowBroadcast (bool allowBroadcast) | 1737 TcpSocketBase::SetAllowBroadcast (bool allowBroadcast) |
1609 { | 1738 { |
1610 NS_FATAL_ERROR ("not implemented"); | 1739 // Broadcast is not implemented. Return true only if allowBroadcast==false |
1740 return (! allowBroadcast); | |
1611 } | 1741 } |
1612 | 1742 |
1613 bool | 1743 bool |
1614 TcpSocketBase::GetAllowBroadcast () const | 1744 TcpSocketBase::GetAllowBroadcast () const |
1615 { | 1745 { |
1616 return false; | 1746 return false; |
1617 } | 1747 } |
1618 | 1748 |
1619 } // namespace ns3 | 1749 } // namespace ns3 |
LEFT | RIGHT |