* 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:
Axel Dörfler 2007-02-07 14:13:37 +00:00
parent aa547f5fbb
commit bbf8311d15
2 changed files with 18 additions and 3 deletions

View File

@ -314,11 +314,14 @@ EndpointManager::Unbind(TCPEndpoint *endpoint)
TCPEndpoint *other = _LookupEndpoint(gAddressModule->get_port((sockaddr *)&endpoint->socket->address)); TCPEndpoint *other = _LookupEndpoint(gAddressModule->get_port((sockaddr *)&endpoint->socket->address));
if (other != endpoint) { if (other != endpoint) {
// remove endpoint from the list of endpoints with the same port // 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 = other->fEndpointNextWithSamePort;
} }
other->fEndpointNextWithSamePort = endpoint->fEndpointNextWithSamePort; if (other != NULL)
other->fEndpointNextWithSamePort = endpoint->fEndpointNextWithSamePort;
else
panic("bound endpoint %p not in hash!", endpoint);
} else { } else {
// we need to replace the first endpoint in the list // we need to replace the first endpoint in the list
hash_remove(fEndpointHash, endpoint); hash_remove(fEndpointHash, endpoint);

View File

@ -102,6 +102,8 @@ TCPEndpoint::TCPEndpoint(net_socket *socket)
TCPEndpoint::~TCPEndpoint() TCPEndpoint::~TCPEndpoint()
{ {
recursive_lock_lock(&fLock);
gStackModule->cancel_timer(&fRetransmitTimer); gStackModule->cancel_timer(&fRetransmitTimer);
gStackModule->cancel_timer(&fPersistTimer); gStackModule->cancel_timer(&fPersistTimer);
gStackModule->cancel_timer(&fDelayedAcknowledgeTimer); gStackModule->cancel_timer(&fDelayedAcknowledgeTimer);
@ -1215,6 +1217,8 @@ TCPEndpoint::_RetransmitTimer(net_timer *timer, void *data)
TCPEndpoint *endpoint = (TCPEndpoint *)data; TCPEndpoint *endpoint = (TCPEndpoint *)data;
RecursiveLocker locker(endpoint->Lock()); RecursiveLocker locker(endpoint->Lock());
if (!locker.IsLocked())
return;
endpoint->fSendNext = endpoint->fSendUnacknowledged; endpoint->fSendNext = endpoint->fSendUnacknowledged;
endpoint->_SendQueued(); endpoint->_SendQueued();
@ -1228,6 +1232,9 @@ TCPEndpoint::_PersistTimer(net_timer *timer, void *data)
TCPEndpoint *endpoint = (TCPEndpoint *)data; TCPEndpoint *endpoint = (TCPEndpoint *)data;
RecursiveLocker locker(endpoint->Lock()); RecursiveLocker locker(endpoint->Lock());
if (!locker.IsLocked())
return;
endpoint->_SendQueued(true); endpoint->_SendQueued(true);
} }
@ -1238,6 +1245,9 @@ TCPEndpoint::_DelayedAcknowledgeTimer(struct net_timer *timer, void *data)
TCPEndpoint *endpoint = (TCPEndpoint *)data; TCPEndpoint *endpoint = (TCPEndpoint *)data;
RecursiveLocker locker(endpoint->Lock()); RecursiveLocker locker(endpoint->Lock());
if (!locker.IsLocked())
return;
endpoint->_SendQueued(true); endpoint->_SendQueued(true);
} }
@ -1247,7 +1257,9 @@ TCPEndpoint::_TimeWaitTimer(struct net_timer *timer, void *data)
{ {
TCPEndpoint *endpoint = (TCPEndpoint *)data; TCPEndpoint *endpoint = (TCPEndpoint *)data;
recursive_lock_lock(&endpoint->Lock()); if (recursive_lock_lock(&endpoint->Lock()) < B_OK)
return;
gSocketModule->delete_socket(endpoint->socket); gSocketModule->delete_socket(endpoint->socket);
} }