Module: ngircd.git Branch: master Commit: eb4f9eac0c35071838c9367f1204db0d0b98ad2e URL: http://ngircd.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git&a=commit;h=eb4f9...
Author: Alexander Barton alex@barton.de Date: Sun Oct 28 19:48:24 2012 +0100
Don't accept connections for servers already beeing linked
If two servers try to link each other, there was a time frame that could result in one connection overwriting the other, e. g. the incoming connection overwriting the status of the outgoing one. And this could lead to all kind of weirdness (even crashes!) later on.
So now such incoming connections are dropped. But this most probably prevents the two servers from linking until timing changes somehow (network latency?) because each server drops the incoming connection of the other one, so no connection survives in the end.
But this has to be addressed by an other patch ...
---
src/ngircd/conf.c | 14 ++++++++------ src/ngircd/conf.h | 2 +- src/ngircd/conn.c | 3 ++- src/ngircd/irc-server.c | 7 ++++--- 4 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index b600570..6a7f633 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -490,7 +490,7 @@ Conf_UnsetServer( CONN_ID Idx ) /** * Set connection information for specified configured server. */ -GLOBAL void +GLOBAL bool Conf_SetServer( int ConfServer, CONN_ID Idx ) { assert( ConfServer > NONE ); @@ -498,13 +498,15 @@ Conf_SetServer( int ConfServer, CONN_ID Idx )
if (Conf_Server[ConfServer].conn_id > NONE && Conf_Server[ConfServer].conn_id != Idx) { - Log(LOG_ALERT, - "Trying to update connection index for already registered server "%s": %d/%d - ignored.", - Conf_Server[ConfServer].name, - Conf_Server[ConfServer].conn_id, Idx); - return; + Log(LOG_ERR, + "Connection %d: Server configuration of "%s" already in use by connection %d!", + Idx, Conf_Server[ConfServer].name, + Conf_Server[ConfServer].conn_id); + Conn_Close(Idx, NULL, "Server configuration already in use", true); + return false; } Conf_Server[ConfServer].conn_id = Idx; + return true; }
/** diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index 541fdb2..7860f01 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -242,7 +242,7 @@ GLOBAL bool Conf_Rehash PARAMS((void)); GLOBAL int Conf_Test PARAMS((void));
GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx )); -GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx )); +GLOBAL bool Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx )); GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
GLOBAL bool Conf_EnableServer PARAMS(( const char *Name, UINT16 Port )); diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 5d08685..80b085a 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -2079,7 +2079,8 @@ New_Server( int Server , ng_ipaddr_t *dest) Client_SetToken( c, TOKEN_OUTBOUND );
/* Register connection */ - Conf_SetServer(Server, new_sock); + if (!Conf_SetServer(Server, new_sock)) + return; My_Connections[new_sock].sock = new_sock; My_Connections[new_sock].addr = *dest; My_Connections[new_sock].client = c; diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index 79facf5..02e3ae8 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -104,6 +104,10 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) if (!Client_CheckID(Client, Req->argv[0])) return DISCONNECTED;
+ /* Mark this connection as belonging to an configured server */ + if (!Conf_SetServer(i, Client_Conn(Client))) + return DISCONNECTED; + Client_SetID( Client, Req->argv[0] ); Client_SetHops( Client, 1 ); Client_SetInfo( Client, Req->argv[Req->argc - 1] ); @@ -131,9 +135,6 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) Client_SetToken(Client, atoi(Req->argv[1])); }
- /* Mark this connection as belonging to an configured server */ - Conf_SetServer(i, Client_Conn(Client)); - /* Check protocol level */ if (Client_Type(Client) == CLIENT_GOTPASS) { /* We got a "simple" PASS command, so the peer is