* 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
This commit is contained in:
Axel Dörfler
2006-12-04 14:41:12 +00:00
parent 9cbe6ce200
commit 10fdb28c47
3 changed files with 31 additions and 8 deletions
@@ -51,9 +51,6 @@
// Initial estimate for packet round trip time (RTT) // Initial estimate for packet round trip time (RTT)
#define TCP_INITIAL_RTT 120000000LL #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 // constants for the fFlags field
enum { enum {
FLAG_OPTION_WINDOW_SHIFT = 0x01, FLAG_OPTION_WINDOW_SHIFT = 0x01,
@@ -98,12 +95,18 @@ TCPConnection::TCPConnection(net_socket *socket)
gStackModule->init_timer(&fRetransmitTimer, TCPConnection::_RetransmitTimer, this); gStackModule->init_timer(&fRetransmitTimer, TCPConnection::_RetransmitTimer, this);
gStackModule->init_timer(&fDelayedAcknowledgeTimer, gStackModule->init_timer(&fDelayedAcknowledgeTimer,
TCPConnection::_DelayedAcknowledgeTimer, this); TCPConnection::_DelayedAcknowledgeTimer, this);
gStackModule->init_timer(&fTimeWaitTimer, TCPConnection::_TimeWaitTimer, this);
} }
TCPConnection::~TCPConnection() 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); recursive_lock_destroy(&fLock);
//benaphore_destroy(&fReceiveLock); //benaphore_destroy(&fReceiveLock);
@@ -179,8 +182,12 @@ TCPConnection::Free()
{ {
TRACE(("TCP:%p.Free()\n", this)); TRACE(("TCP:%p.Free()\n", this));
// TODO: if this connection is not in the hash, we don't have to call this one if (fState <= SYNCHRONIZE_SENT || fState == TIME_WAIT)
return B_OK; 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 status_t
TCPConnection::UpdateTimeWait() TCPConnection::UpdateTimeWait()
{ {
@@ -850,6 +864,7 @@ TCPConnection::Receive(tcp_segment_header &segment, net_buffer *buffer)
break; break;
case CLOSING: case CLOSING:
fState = TIME_WAIT; fState = TIME_WAIT;
_EnterTimeWait();
break; break;
case WAIT_FOR_FINISH_ACKNOWLEDGE: case WAIT_FOR_FINISH_ACKNOWLEDGE:
fState = CLOSED; fState = CLOSED;
@@ -883,6 +898,7 @@ TCPConnection::Receive(tcp_segment_header &segment, net_buffer *buffer)
break; break;
case FINISH_ACKNOWLEDGED: case FINISH_ACKNOWLEDGED:
fState = TIME_WAIT; fState = TIME_WAIT;
_EnterTimeWait();
break; break;
case FINISH_RECEIVED: case FINISH_RECEIVED:
// a second FIN? // a second FIN?
@@ -1177,7 +1193,11 @@ TCPConnection::_DelayedAcknowledgeTimer(struct net_timer *timer, void *data)
/*static*/ void /*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);
} }
@@ -60,12 +60,13 @@ class TCPConnection : public net_protocol {
friend class EndpointManager; friend class EndpointManager;
void _StartPersistTimer(); void _StartPersistTimer();
void _EnterTimeWait();
uint8 _CurrentFlags(); uint8 _CurrentFlags();
bool _ShouldSendSegment(tcp_segment_header &segment, uint32 length, bool _ShouldSendSegment(tcp_segment_header &segment, uint32 length,
bool outstandingAcknowledge); bool outstandingAcknowledge);
status_t _SendQueued(bool force = false); 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 _RetransmitTimer(net_timer *timer, void *data);
static void _PersistTimer(net_timer *timer, void *data); static void _PersistTimer(net_timer *timer, void *data);
static void _DelayedAcknowledgeTimer(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 fRetransmitTimer;
net_timer fPersistTimer; net_timer fPersistTimer;
net_timer fDelayedAcknowledgeTimer; net_timer fDelayedAcknowledgeTimer;
net_timer fTimeWaitTimer;
}; };
#endif // TCP_CONNECTION_H #endif // TCP_CONNECTION_H
@@ -104,6 +104,7 @@ class tcp_sequence {
#define TCP_DELAYED_ACKNOWLEDGE_TIMEOUT 100000 // 100 msecs #define TCP_DELAYED_ACKNOWLEDGE_TIMEOUT 100000 // 100 msecs
#define TCP_DEFAULT_MAX_SEGMENT_SIZE 536 #define TCP_DEFAULT_MAX_SEGMENT_SIZE 536
#define TCP_MAX_WINDOW 65535 #define TCP_MAX_WINDOW 65535
#define TCP_MAX_SEGMENT_LIFETIME 60000000 // 60 secs
struct tcp_option { struct tcp_option {
uint8 kind; uint8 kind;