repo: ngircd action: commit revision: path_from: revision_from: 684e50f0a4d827965b61c4b9feeda403ec3c3b87: path_to: revision_to:
commit 684e50f0a4d827965b61c4b9feeda403ec3c3b87 Author: Alexander BartonDate: Sat Jun 9 01:03:48 2012 +0200 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. diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
--- 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
--- 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;
-----END OF PAGE-----