* As Ingo pointed out to me earlier, TCP could now delete its socket too early
when using the shutdown() command. * If TCP no longer needs a socket, it will now set the flag FLAG_DELETE_ON_CLOSE; when the socket is closed from the upper layers, it will set the FLAG_CLOSED flag - and only if both are set, TCP will now delete the socket itself on receive. * This fixes bug #2189. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25278 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
184de764fe
commit
63368af591
@ -219,7 +219,7 @@ enum {
|
|||||||
// is performed on a listen()ing socket.
|
// is performed on a listen()ing socket.
|
||||||
FLAG_NO_RECEIVE = 0x04,
|
FLAG_NO_RECEIVE = 0x04,
|
||||||
FLAG_CLOSED = 0x08,
|
FLAG_CLOSED = 0x08,
|
||||||
FLAG_DELETE = 0x10,
|
FLAG_DELETE_ON_CLOSE = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -500,7 +500,6 @@ TCPEndpoint::Close()
|
|||||||
fSendQueue.Used());
|
fSendQueue.Used());
|
||||||
}
|
}
|
||||||
|
|
||||||
fFlags |= FLAG_CLOSED;
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,11 +511,16 @@ TCPEndpoint::Free()
|
|||||||
|
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
|
||||||
if (fState <= SYNCHRONIZE_SENT || fState == TIME_WAIT)
|
if (fState <= SYNCHRONIZE_SENT)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// we are only interested in the timer, not in changing state
|
// we are only interested in the timer, not in changing state
|
||||||
_EnterTimeWait();
|
_EnterTimeWait();
|
||||||
|
|
||||||
|
fFlags |= FLAG_CLOSED;
|
||||||
|
if ((fFlags & FLAG_DELETE_ON_CLOSE) != 0)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
return B_BUSY;
|
return B_BUSY;
|
||||||
// we'll be freed later when the 2MSL timer expires
|
// we'll be freed later when the 2MSL timer expires
|
||||||
}
|
}
|
||||||
@ -1009,14 +1013,15 @@ TCPEndpoint::_EnterTimeWait()
|
|||||||
{
|
{
|
||||||
TRACE("_EnterTimeWait()\n");
|
TRACE("_EnterTimeWait()\n");
|
||||||
|
|
||||||
|
_CancelConnectionTimers();
|
||||||
|
|
||||||
if (fState == TIME_WAIT && fRoute != NULL
|
if (fState == TIME_WAIT && fRoute != NULL
|
||||||
&& (fRoute->flags & RTF_LOCAL) != 0) {
|
&& (fRoute->flags & RTF_LOCAL) != 0) {
|
||||||
// we do not use TIME_WAIT state for local connections
|
// we do not use TIME_WAIT state for local connections
|
||||||
fFlags |= FLAG_DELETE;
|
fFlags |= FLAG_DELETE_ON_CLOSE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_CancelConnectionTimers();
|
|
||||||
_UpdateTimeWait();
|
_UpdateTimeWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,11 +1111,7 @@ TCPEndpoint::_Close()
|
|||||||
fState = CLOSED;
|
fState = CLOSED;
|
||||||
T(State(this));
|
T(State(this));
|
||||||
|
|
||||||
if ((fFlags & FLAG_CLOSED) != 0) {
|
fFlags |= FLAG_DELETE_ON_CLOSE;
|
||||||
// this socket has been closed already, we don't need to keep
|
|
||||||
// it around anymore
|
|
||||||
fFlags |= FLAG_DELETE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1671,7 +1672,8 @@ TCPEndpoint::SegmentReceived(tcp_segment_header& segment, net_buffer* buffer)
|
|||||||
else if (segmentAction & ACKNOWLEDGE)
|
else if (segmentAction & ACKNOWLEDGE)
|
||||||
DelayedAcknowledge();
|
DelayedAcknowledge();
|
||||||
|
|
||||||
if ((fFlags & FLAG_DELETE) != 0) {
|
if ((fFlags & (FLAG_CLOSED | FLAG_DELETE_ON_CLOSE))
|
||||||
|
== (FLAG_CLOSED | FLAG_DELETE_ON_CLOSE)) {
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
gSocketModule->delete_socket(socket);
|
gSocketModule->delete_socket(socket);
|
||||||
// this will also delete us
|
// this will also delete us
|
||||||
|
Loading…
Reference in New Issue
Block a user