]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Don't accept connections for servers already beeing linked
authorAlexander Barton <alex@barton.de>
Sun, 28 Oct 2012 18:48:24 +0000 (19:48 +0100)
committerAlexander Barton <alex@barton.de>
Mon, 29 Oct 2012 10:33:49 +0000 (11:33 +0100)
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
src/ngircd/conf.h
src/ngircd/conn.c
src/ngircd/irc-server.c

index b60057070f5077bf71c2898368c98b21b795788f..6a7f63393c6f7177f054b991e72a15009cf6fa1c 100644 (file)
@@ -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;
 }
 
 /**
index 541fdb294c4aac81114f7b8c458dc4e6f81021f2..7860f019a8928d2959ed0e31e82fc3e18c34149d 100644 (file)
@@ -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 ));
index 5d086857dcd2f634ab4ec5b506d57ddf3f9d3ce2..80b085a83e2f3e4b6108ed36c30c8358ff5ac441 100644 (file)
@@ -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;
index 79facf5e0ead3a639c475956cc1a34a46aa1d4fc..02e3ae824e2d9c644e7f009d49db33ac8314a8a0 100644 (file)
@@ -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