summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/connection.h17
-rw-r--r--src/commands.cpp4
-rw-r--r--src/connection.cpp31
-rw-r--r--src/servers.cpp10
4 files changed, 62 insertions, 0 deletions
diff --git a/include/connection.h b/include/connection.h
index 8f5efe2d7..88dc3ea54 100644
--- a/include/connection.h
+++ b/include/connection.h
@@ -93,6 +93,14 @@ class ircd_connector : public Extensible
*/
std::string WriteError;
+ /** Time this connection was last pinged
+ */
+ time_t nextping;
+
+ /** Did this connection reply to its last ping?
+ */
+ bool replied;
+
public:
/** IRCD Buffer for input characters, holds as many lines as are
@@ -236,6 +244,15 @@ class ircd_connector : public Extensible
/** Returns true if there is data to be written that hasn't been sent yet
*/
bool HasBufferedOutput();
+
+ /** Checks if the connection replied to its last ping, and if it did
+ * sends another and returns true, if not, returns false.
+ */
+ bool CheckPing();
+
+ /** Resets the ping counter
+ */
+ void ResetPing();
};
diff --git a/src/commands.cpp b/src/commands.cpp
index 916c9bc10..b66ad514c 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -2809,6 +2809,8 @@ void process_restricted_commands(char token,char* params,serverrec* source,serve
char buffer[MAXBUF];
int MOD_RESULT = 0;
+ ircd_connector* cn = source->FindHost(tcp_host);
+
switch(token)
{
// Y <TS>
@@ -2857,6 +2859,8 @@ void process_restricted_commands(char token,char* params,serverrec* source,serve
// ?
// pong
case '!':
+ if (cn)
+ cn->ResetPing();
break;
// *
// no operation
diff --git a/src/connection.cpp b/src/connection.cpp
index c7221ce74..2f6cbd6d5 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -82,6 +82,8 @@ ircd_connector::ircd_connector()
port = 0;
sendq = "";
WriteError = "";
+ nextping = TIME+30;
+ replied = false;
}
char* ircd_connector::GetServerIP()
@@ -179,6 +181,35 @@ bool ircd_connector::HasBufferedOutput()
return (sendq.length() > 0);
}
+bool ircd_connector::CheckPing()
+{
+ if (TIME > this->nextping)
+ {
+ if (this->replied)
+ {
+ this->AddWriteBuf("?\n");
+ this->nextping = TIME+30;
+ this->replied = false;
+ return true;
+ }
+ else
+ {
+ this->SetWriteError("Ping timeout");
+ this->CloseConnection();
+ this->SetState(STATE_DISCONNECTED);
+ WriteOpers("*** Ping timeout on link to %s (more routes may remain)",this->GetServerName().c_str());
+ return false;
+ }
+ }
+}
+
+void ircd_connector::ResetPing()
+{
+ log(DEBUG,"Reset ping counter");
+ this->replied = true;
+ this->nextping = TIME+30;
+}
+
// send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it)
bool ircd_connector::FlushWriteBuf()
{
diff --git a/src/servers.cpp b/src/servers.cpp
index 15929345f..38f9cfb5f 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -250,6 +250,15 @@ void serverrec::FlushWriteBuffers()
{
for (int i = 0; i < this->connectors.size(); i++)
{
+ if (this->connectors[i].GetState() != STATE_DISCONNECTED)
+ {
+ if (!this->connectors[i].CheckPing())
+ {
+ WriteOpers("*** Lost single connection to %s: Ping timeout",this->connectors[i].GetServerName().c_str());
+ this->connectors[i].CloseConnection();
+ this->connectors[i].SetState(STATE_DISCONNECTED);
+ }
+ }
if (this->connectors[i].HasBufferedOutput())
{
if (!this->connectors[i].FlushWriteBuf())
@@ -400,6 +409,7 @@ bool serverrec::RecvPacket(std::deque<std::string> &messages, char* recvhost,std
}
if (this->connectors[i].BufferIsComplete())
{
+ this->connectors[i].ResetPing();
while (this->connectors[i].BufferIsComplete())
{
std::string text = this->connectors[i].GetBuffer();