* Fixed a race condition between deletion of the endpoint and canceling its timers;
the timer functions could access invalid memory. * The endpoint manager now panics if a bound endpoint is not in the hash. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20100 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
aa547f5fbb
commit
bbf8311d15
@ -314,11 +314,14 @@ EndpointManager::Unbind(TCPEndpoint *endpoint)
|
||||
TCPEndpoint *other = _LookupEndpoint(gAddressModule->get_port((sockaddr *)&endpoint->socket->address));
|
||||
if (other != endpoint) {
|
||||
// remove endpoint from the list of endpoints with the same port
|
||||
while (other->fEndpointNextWithSamePort != endpoint) {
|
||||
while (other != NULL && other->fEndpointNextWithSamePort != endpoint) {
|
||||
other = other->fEndpointNextWithSamePort;
|
||||
}
|
||||
|
||||
other->fEndpointNextWithSamePort = endpoint->fEndpointNextWithSamePort;
|
||||
if (other != NULL)
|
||||
other->fEndpointNextWithSamePort = endpoint->fEndpointNextWithSamePort;
|
||||
else
|
||||
panic("bound endpoint %p not in hash!", endpoint);
|
||||
} else {
|
||||
// we need to replace the first endpoint in the list
|
||||
hash_remove(fEndpointHash, endpoint);
|
||||
|
@ -102,6 +102,8 @@ TCPEndpoint::TCPEndpoint(net_socket *socket)
|
||||
|
||||
TCPEndpoint::~TCPEndpoint()
|
||||
{
|
||||
recursive_lock_lock(&fLock);
|
||||
|
||||
gStackModule->cancel_timer(&fRetransmitTimer);
|
||||
gStackModule->cancel_timer(&fPersistTimer);
|
||||
gStackModule->cancel_timer(&fDelayedAcknowledgeTimer);
|
||||
@ -1215,6 +1217,8 @@ TCPEndpoint::_RetransmitTimer(net_timer *timer, void *data)
|
||||
TCPEndpoint *endpoint = (TCPEndpoint *)data;
|
||||
|
||||
RecursiveLocker locker(endpoint->Lock());
|
||||
if (!locker.IsLocked())
|
||||
return;
|
||||
|
||||
endpoint->fSendNext = endpoint->fSendUnacknowledged;
|
||||
endpoint->_SendQueued();
|
||||
@ -1228,6 +1232,9 @@ TCPEndpoint::_PersistTimer(net_timer *timer, void *data)
|
||||
TCPEndpoint *endpoint = (TCPEndpoint *)data;
|
||||
|
||||
RecursiveLocker locker(endpoint->Lock());
|
||||
if (!locker.IsLocked())
|
||||
return;
|
||||
|
||||
endpoint->_SendQueued(true);
|
||||
}
|
||||
|
||||
@ -1238,6 +1245,9 @@ TCPEndpoint::_DelayedAcknowledgeTimer(struct net_timer *timer, void *data)
|
||||
TCPEndpoint *endpoint = (TCPEndpoint *)data;
|
||||
|
||||
RecursiveLocker locker(endpoint->Lock());
|
||||
if (!locker.IsLocked())
|
||||
return;
|
||||
|
||||
endpoint->_SendQueued(true);
|
||||
}
|
||||
|
||||
@ -1247,7 +1257,9 @@ TCPEndpoint::_TimeWaitTimer(struct net_timer *timer, void *data)
|
||||
{
|
||||
TCPEndpoint *endpoint = (TCPEndpoint *)data;
|
||||
|
||||
recursive_lock_lock(&endpoint->Lock());
|
||||
if (recursive_lock_lock(&endpoint->Lock()) < B_OK)
|
||||
return;
|
||||
|
||||
gSocketModule->delete_socket(endpoint->socket);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user