* 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

View File

@ -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);
}

View File

@ -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

View File

@ -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;