From 10fdb28c47d85f624881000c9687592df8e5fe0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 4 Dec 2006 14:41:12 +0000 Subject: [PATCH] * Some minor work on TIME_WAIT state, and its timer. * endpoints are no longer deleted without unbinding them. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19417 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/protocols/tcp/TCPConnection.cpp | 34 +++++++++++++++---- .../network/protocols/tcp/TCPConnection.h | 4 ++- .../kernel/network/protocols/tcp/tcp.h | 1 + 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp index 9987b37157..3a67adb7d2 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp @@ -51,9 +51,6 @@ // Initial estimate for packet round trip time (RTT) #define TCP_INITIAL_RTT 120000000LL -// Estimate for Maximum segment lifetime in the internet -#define TCP_MAX_SEGMENT_LIFETIME (2 * TCP_INITIAL_RTT) - // constants for the fFlags field enum { FLAG_OPTION_WINDOW_SHIFT = 0x01, @@ -98,12 +95,18 @@ TCPConnection::TCPConnection(net_socket *socket) gStackModule->init_timer(&fRetransmitTimer, TCPConnection::_RetransmitTimer, this); gStackModule->init_timer(&fDelayedAcknowledgeTimer, TCPConnection::_DelayedAcknowledgeTimer, this); + gStackModule->init_timer(&fTimeWaitTimer, TCPConnection::_TimeWaitTimer, this); } TCPConnection::~TCPConnection() { - //gStackModule->set_timer(&fTimer, -1); + gStackModule->cancel_timer(&fRetransmitTimer); + gStackModule->cancel_timer(&fPersistTimer); + gStackModule->cancel_timer(&fDelayedAcknowledgeTimer); + gStackModule->cancel_timer(&fTimeWaitTimer); + + gEndpointManager->Unbind(this); recursive_lock_destroy(&fLock); //benaphore_destroy(&fReceiveLock); @@ -179,8 +182,12 @@ TCPConnection::Free() { TRACE(("TCP:%p.Free()\n", this)); - // TODO: if this connection is not in the hash, we don't have to call this one - return B_OK; + if (fState <= SYNCHRONIZE_SENT || fState == TIME_WAIT) + return B_OK; + + _EnterTimeWait(); + return B_BUSY; + // we'll be freed later when the 2MSL timer expires } @@ -512,6 +519,13 @@ TCPConnection::_StartPersistTimer() } +void +TCPConnection::_EnterTimeWait() +{ + gStackModule->set_timer(&fTimeWaitTimer, TCP_MAX_SEGMENT_LIFETIME << 1); +} + + status_t TCPConnection::UpdateTimeWait() { @@ -850,6 +864,7 @@ TCPConnection::Receive(tcp_segment_header &segment, net_buffer *buffer) break; case CLOSING: fState = TIME_WAIT; + _EnterTimeWait(); break; case WAIT_FOR_FINISH_ACKNOWLEDGE: fState = CLOSED; @@ -883,6 +898,7 @@ TCPConnection::Receive(tcp_segment_header &segment, net_buffer *buffer) break; case FINISH_ACKNOWLEDGED: fState = TIME_WAIT; + _EnterTimeWait(); break; case FINISH_RECEIVED: // a second FIN? @@ -1177,7 +1193,11 @@ TCPConnection::_DelayedAcknowledgeTimer(struct net_timer *timer, void *data) /*static*/ void -TCPConnection::_TimeWait(struct net_timer *timer, void *data) +TCPConnection::_TimeWaitTimer(struct net_timer *timer, void *data) { + TCPConnection *connection = (TCPConnection *)data; + + RecursiveLocker locker(connection->Lock()); + gSocketModule->delete_socket(connection->socket); } diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPConnection.h b/src/add-ons/kernel/network/protocols/tcp/TCPConnection.h index 8ded5b78de..1d2a53c447 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPConnection.h +++ b/src/add-ons/kernel/network/protocols/tcp/TCPConnection.h @@ -60,12 +60,13 @@ class TCPConnection : public net_protocol { friend class EndpointManager; void _StartPersistTimer(); + void _EnterTimeWait(); uint8 _CurrentFlags(); bool _ShouldSendSegment(tcp_segment_header &segment, uint32 length, bool outstandingAcknowledge); status_t _SendQueued(bool force = false); - static void _TimeWait(net_timer *timer, void *data); + static void _TimeWaitTimer(net_timer *timer, void *data); static void _RetransmitTimer(net_timer *timer, void *data); static void _PersistTimer(net_timer *timer, void *data); static void _DelayedAcknowledgeTimer(net_timer *timer, void *data); @@ -124,6 +125,7 @@ class TCPConnection : public net_protocol { net_timer fRetransmitTimer; net_timer fPersistTimer; net_timer fDelayedAcknowledgeTimer; + net_timer fTimeWaitTimer; }; #endif // TCP_CONNECTION_H diff --git a/src/add-ons/kernel/network/protocols/tcp/tcp.h b/src/add-ons/kernel/network/protocols/tcp/tcp.h index 650fff2148..df2d775fc5 100644 --- a/src/add-ons/kernel/network/protocols/tcp/tcp.h +++ b/src/add-ons/kernel/network/protocols/tcp/tcp.h @@ -104,6 +104,7 @@ class tcp_sequence { #define TCP_DELAYED_ACKNOWLEDGE_TIMEOUT 100000 // 100 msecs #define TCP_DEFAULT_MAX_SEGMENT_SIZE 536 #define TCP_MAX_WINDOW 65535 +#define TCP_MAX_SEGMENT_LIFETIME 60000000 // 60 secs struct tcp_option { uint8 kind;