mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-10 11:09:04 -04:00
Remove handshake timer on server sockets that die before completing handshake
This fixes some very subtle and hard-to-trace bugs that are triggered when a file descriptor and memory address of an EventHandler* are reused after being deallocated. Impossible to trigger in valgrind; has been seen in live networks. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11369 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
parent
999febbac6
commit
b2159a9e4f
@ -32,28 +32,24 @@ HandshakeTimer::HandshakeTimer(InspIRCd* Inst, TreeSocket* s, Link* l, SpanningT
|
||||
thefd = sock->GetFd();
|
||||
}
|
||||
|
||||
void HandshakeTimer::Tick(time_t TIME)
|
||||
HandshakeTimer::~HandshakeTimer()
|
||||
{
|
||||
if (Instance->SE->GetRef(thefd) == sock)
|
||||
{
|
||||
if (!sock->GetHook())
|
||||
{
|
||||
CancelRepeat();
|
||||
sock->SendCapabilities();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sock->GetHook() && BufferedSocketHSCompleteRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send())
|
||||
{
|
||||
CancelRepeat();
|
||||
BufferedSocketAttachCertRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send();
|
||||
sock->SendCapabilities();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try again later...
|
||||
}
|
||||
}
|
||||
}
|
||||
sock->hstimer = NULL;
|
||||
}
|
||||
|
||||
void HandshakeTimer::Tick(time_t TIME)
|
||||
{
|
||||
if (!sock->GetHook())
|
||||
{
|
||||
CancelRepeat();
|
||||
sock->SendCapabilities();
|
||||
}
|
||||
else if (BufferedSocketHSCompleteRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send())
|
||||
{
|
||||
CancelRepeat();
|
||||
BufferedSocketAttachCertRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send();
|
||||
sock->SendCapabilities();
|
||||
}
|
||||
// otherwise, try again later
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ class HandshakeTimer : public Timer
|
||||
int thefd;
|
||||
public:
|
||||
HandshakeTimer(InspIRCd* Inst, TreeSocket* s, Link* l, SpanningTreeUtilities* u, int delay);
|
||||
~HandshakeTimer();
|
||||
virtual void Tick(time_t TIME);
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "transport.h"
|
||||
|
||||
#include "m_spanningtree/utils.h"
|
||||
#include "m_spanningtree/handshaketimer.h"
|
||||
|
||||
/*
|
||||
* The server list in InspIRCd is maintained as two structures
|
||||
@ -90,6 +91,7 @@ class TreeSocket : public BufferedSocket
|
||||
std::string OutboundPass; /* Outbound password */
|
||||
bool sentcapab; /* Have sent CAPAB already */
|
||||
public:
|
||||
HandshakeTimer* hstimer; /* Handshake timer, needed to work around I/O hook buffering */
|
||||
|
||||
/** Because most of the I/O gubbins are encapsulated within
|
||||
* BufferedSocket, we just call the superclass constructor for
|
||||
|
@ -46,6 +46,7 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string sh
|
||||
Utils->timeoutlist[this] = std::pair<std::string, int>(ServerName, maxtime);
|
||||
if (Hook)
|
||||
BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
|
||||
hstimer = NULL;
|
||||
}
|
||||
|
||||
/** When a listening socket gives us a new file descriptor,
|
||||
@ -65,7 +66,8 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, cha
|
||||
if (Hook)
|
||||
BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
|
||||
|
||||
ServerInstance->Timers->AddTimer(new HandshakeTimer(ServerInstance, this, &(Utils->LinkBlocks[0]), this->Utils, 1));
|
||||
hstimer = new HandshakeTimer(ServerInstance, this, &(Utils->LinkBlocks[0]), this->Utils, 1);
|
||||
ServerInstance->Timers->AddTimer(hstimer);
|
||||
|
||||
/* Fix by Brain - inbound sockets need a timeout, too. 30 secs should be pleanty */
|
||||
Utils->timeoutlist[this] = std::pair<std::string, int>("<unknown>", 30);
|
||||
@ -85,6 +87,8 @@ TreeSocket::~TreeSocket()
|
||||
{
|
||||
if (Hook)
|
||||
BufferedSocketUnhookRequest(this, (Module*)Utils->Creator, Hook).Send();
|
||||
if (hstimer)
|
||||
ServerInstance->Timers->DelTimer(hstimer);
|
||||
Utils->timeoutlist.erase(this);
|
||||
}
|
||||
|
||||
@ -115,7 +119,10 @@ bool TreeSocket::OnConnected()
|
||||
|
||||
/* found who we're supposed to be connecting to, send the neccessary gubbins. */
|
||||
if (this->GetHook())
|
||||
ServerInstance->Timers->AddTimer(new HandshakeTimer(ServerInstance, this, &(*x), this->Utils, 1));
|
||||
{
|
||||
hstimer = new HandshakeTimer(ServerInstance, this, &(*x), this->Utils, 1);
|
||||
ServerInstance->Timers->AddTimer(hstimer);
|
||||
}
|
||||
else
|
||||
this->SendCapabilities();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user