Enhanced the handler for PING and PONG commands: fix forwarding and enable

back-passing of a client supplied additional argument of PING.
This commit is contained in:
Alexander Barton 2005-08-28 11:40:13 +00:00
parent 2f105b1c0a
commit 4074fd9149
2 changed files with 96 additions and 48 deletions

View File

@ -12,6 +12,8 @@
ngIRCd CVSHEAD ngIRCd CVSHEAD
- Enhanced the handler for PING and PONG commands: fix forwarding and enable
back-passing of a client supplied additional argument of PING.
- Changed handling of timeouts for unregistered connections: don't reset - Changed handling of timeouts for unregistered connections: don't reset
the counter if data is received and disconnect clients earlier. the counter if data is received and disconnect clients earlier.
- Fixed a format string bug in "connection statistics" messages to clients. - Fixed a format string bug in "connection statistics" messages to clients.
@ -634,4 +636,4 @@ ngIRCd 0.0.1, 31.12.2001
-- --
$Id: ChangeLog,v 1.289 2005/08/27 23:33:10 alex Exp $ $Id: ChangeLog,v 1.290 2005/08/28 11:40:13 alex Exp $

View File

@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-login.c,v 1.47 2005/08/27 18:39:56 fw Exp $"; static char UNUSED id[] = "$Id: irc-login.c,v 1.48 2005/08/28 11:40:13 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@ -427,81 +427,127 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
GLOBAL bool GLOBAL bool
IRC_PING( CLIENT *Client, REQUEST *Req ) IRC_PING(CLIENT *Client, REQUEST *Req)
{ {
CLIENT *target, *from; CLIENT *target, *from;
assert( Client != NULL ); assert(Client != NULL);
assert( Req != NULL ); assert(Req != NULL);
/* wrong number of arguments? */ /* Wrong number of arguments? */
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client )); if (Req->argc < 1)
return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client));
#ifdef STRICT_RFC #ifdef STRICT_RFC
if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); /* Don't ignore additional arguments when in "strict" mode */
if (Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
#endif #endif
if( Req->argc > 1 ) { if (Req->argc > 1) {
/* a target client was specified */ /* A target has been specified ... */
target = Client_Search( Req->argv[1] ); target = Client_Search(Req->argv[1]);
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER ))
return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] ); if (!target || Client_Type(target) != CLIENT_SERVER)
if( target != Client_ThisServer( )) { return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
/* ok, forward */ Client_ID(Client), Req->argv[1]);
if( Client_Type( Client ) == CLIENT_SERVER )
from = Client_Search( Req->prefix ); if (target != Client_ThisServer()) {
/* Ok, we have to forward the PING */
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else else
from = Client; from = Client;
if (!from) if (!from)
return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, return IRC_WriteStrClient(Client,
Client_ID( Client ), Req->prefix ); ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->prefix);
return IRC_WriteStrClientPrefix(target, from, return IRC_WriteStrClientPrefix(target, from,
"PING %s :%s", Client_ID( from ), Req->argv[1] ); "PING %s :%s", Req->argv[0],
Req->argv[1] );
} }
} }
Log( LOG_DEBUG, "Connection %d: got PING, sending PONG ...", Client_Conn( Client )); if (Client_Type(Client) == CLIENT_SERVER) {
if (Req->prefix)
from = Client_Search(Req->prefix);
else
from = Client;
} else
from = Client_ThisServer();
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->prefix);
Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...",
Client_Conn(Client));
#ifdef STRICT_RFC #ifdef STRICT_RFC
return IRC_WriteStrClient( Client, "PONG %s :%s", Client_ID( Client_ThisServer( )), return IRC_WriteStrClient(Client, "PONG %s :%s",
Client_ID( Client )); Client_ID(from), Client_ID(Client));
#else #else
/* some clients depend on argument being returned in PONG reply (not mentioned in any RFC, though) */ /* Some clients depend on the argument being returned in the PONG
return IRC_WriteStrClient( Client, "PONG %s :%s", Client_ID( Client_ThisServer( )), Req->argv[0]); * reply (not mentioned in any RFC, though) */
#endif return IRC_WriteStrClient(Client, "PONG %s :%s",
Client_ID(from), Req->argv[0]);
#endif
} /* IRC_PING */ } /* IRC_PING */
GLOBAL bool GLOBAL bool
IRC_PONG( CLIENT *Client, REQUEST *Req ) IRC_PONG(CLIENT *Client, REQUEST *Req)
{ {
CLIENT *target, *from; CLIENT *target, *from;
char *s;
assert( Client != NULL ); assert(Client != NULL);
assert( Req != NULL ); assert(Req != NULL);
/* Falsche Anzahl Parameter? */ /* Wrong number of arguments? */
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client )); if (Req->argc < 1)
if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client));
if (Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* forwarden? */ /* Forward? */
if( Req->argc == 2 ) if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
{ target = Client_Search(Req->argv[0]);
target = Client_Search( Req->argv[1] ); if (!target)
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] ); return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
if( target != Client_ThisServer( )) Client_ID(Client), Req->argv[0]);
{
/* ok, forwarden */ if (target != Client_ThisServer()) {
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); /* Ok, we have to forward the message. */
else from = Client; from = Client_Search(Req->prefix);
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix ); if (!from)
return IRC_WriteStrClientPrefix( target, from, "PONG %s :%s", Client_ID( from ), Req->argv[1] ); return IRC_WriteStrClient(Client,
ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->prefix);
if (Client_Type(Client_NextHop(target)) != CLIENT_SERVER)
s = Client_ID(from);
else
s = Req->argv[0];
return IRC_WriteStrClientPrefix(target, from,
"PONG %s :%s", s, Req->argv[1]);
} }
} }
/* Der Connection-Timestamp wurde schon beim Lesen aus dem Socket /* The connection timestamp has already been updated when the data has
* aktualisiert, daher muss das hier nicht mehr gemacht werden. */ * been read from so socket, so we don't need to update it here. */
if( Client_Conn( Client ) > NONE ) Log( LOG_DEBUG, "Connection %d: received PONG. Lag: %ld seconds.", Client_Conn( Client ), time( NULL ) - Conn_LastPing( Client_Conn( Client ))); if (Client_Conn(Client) > NONE)
else Log( LOG_DEBUG, "Connection %d: received PONG.", Client_Conn( Client )); Log(LOG_DEBUG,
"Connection %d: received PONG. Lag: %ld seconds.",
Client_Conn(Client),
time(NULL) - Conn_LastPing(Client_Conn(Client)));
else
Log(LOG_DEBUG,
"Connection %d: received PONG.", Client_Conn(Client));
return CONNECTED; return CONNECTED;
} /* IRC_PONG */ } /* IRC_PONG */