diff options
| author | Alexander Barton <alex@barton.de> | 2012-06-09 01:03:48 +0200 |
|---|---|---|
| committer | Alexander Barton <alex@barton.de> | 2012-06-09 01:03:48 +0200 |
| commit | 684e50f0a4d827965b61c4b9feeda403ec3c3b87 (patch) | |
| tree | 4285dd2208ab453a5b25c08880f67d93b6c8029a | |
| parent | 4a90959cb563e7c6ca57d32779074b448982c94f (diff) | |
| download | ngircd-684e50f0a4d827965b61c4b9feeda403ec3c3b87.tar.gz ngircd-684e50f0a4d827965b61c4b9feeda403ec3c3b87.zip | |
Correctly handle asynchronously re-established server links
Don't try to establish an outgoing server link after DNS lookup when this
server re-connected on its own in the meantime.
In addition, log a warning message if we try to update the connection
index of an already connected server structure -- and ignore it.
Up to now, both behaviour could lead to a race when the remote server
connects to this daemon while it still prepares the outgoing connection:
- The local server prepares the new outgoing connection ...
- in the meantime the remote server becomes connected and registered.
- Now the new outgoing connection overwrites the (correct) socket handle,
- then the 2nd connection becomes disconnected: "already registered",
- and the 1st connection becomes unhandled ("gets lost") because the
configuration structure is reset because of the wrong socket handle.
This patch hopefully fixes all these problems.
| -rw-r--r-- | src/ngircd/conf.c | 10 | ||||
| -rw-r--r-- | src/ngircd/conn.c | 12 |
2 files changed, 19 insertions, 3 deletions
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 54269009..f274eb82 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -492,6 +492,14 @@ Conf_SetServer( int ConfServer, CONN_ID Idx ) assert( ConfServer > NONE ); assert( Idx > NONE ); + 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; + } Conf_Server[ConfServer].conn_id = Idx; } diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 09f726ca..06236fd4 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1935,6 +1935,14 @@ New_Server( int Server , ng_ipaddr_t *dest) assert( Server > NONE ); + /* Make sure that the remote server hasn't re-linked to this server + * asynchronously on its own */ + if (Conf_Server[Server].conn_id > NONE) { + Log(LOG_INFO, + "Connection to \"%s\" meanwhile re-established, aborting preparation."); + return; + } + if (!ng_ipaddr_tostr_r(dest, ip_str)) { Log(LOG_WARNING, "New_Server: Could not convert IP to string"); return; @@ -2008,7 +2016,7 @@ New_Server( int Server , ng_ipaddr_t *dest) Client_SetToken( c, TOKEN_OUTBOUND ); /* Register connection */ - Conf_Server[Server].conn_id = new_sock; + Conf_SetServer(Server, new_sock); My_Connections[new_sock].sock = new_sock; My_Connections[new_sock].addr = *dest; My_Connections[new_sock].client = c; |