diff options
-rw-r--r-- | include/connection.h | 17 | ||||
-rw-r--r-- | src/commands.cpp | 4 | ||||
-rw-r--r-- | src/connection.cpp | 31 | ||||
-rw-r--r-- | src/servers.cpp | 10 |
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(); |