about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlexander Barton <alex@barton.de>2012-06-09 01:03:48 +0200
committerAlexander Barton <alex@barton.de>2012-06-09 01:03:48 +0200
commit684e50f0a4d827965b61c4b9feeda403ec3c3b87 (patch)
tree4285dd2208ab453a5b25c08880f67d93b6c8029a /src
parent4a90959cb563e7c6ca57d32779074b448982c94f (diff)
downloadngircd-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.
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/conf.c10
-rw-r--r--src/ngircd/conn.c12
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;