]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Fix cb_connserver() to handle aborted outgoing connections
authorAlexander Barton <alex@barton.de>
Fri, 11 Sep 2009 22:17:42 +0000 (00:17 +0200)
committerAlexander Barton <alex@barton.de>
Fri, 11 Sep 2009 22:17:42 +0000 (00:17 +0200)
A configured server could have been removed while a connection apptempt
is still in progress. So the cb_connserver() callback has to test if the
server configuration record is still valid.

src/ngircd/conn.c

index d3b5357c8cfa2ed1108cb1c7f6964461e92b06bb..731647d9cda3f5dd7576bbfbebb4e885657c8ee2 100644 (file)
@@ -143,21 +143,33 @@ cb_listen_ssl(int sock, short irrelevant)
 static void
 cb_connserver(int sock, UNUSED short what)
 {
-       int res, err;
+       int res, err, server;
        socklen_t sock_len;
        CONN_ID idx = Socket2Index( sock );
+
        if (idx <= NONE) {
                LogDebug("cb_connserver wants to write on unknown socket?!");
                io_close(sock);
                return;
        }
 
-       assert( what & IO_WANTWRITE);
+       assert(what & IO_WANTWRITE);
+
+       /* Make sure that the server is still configured; it could have been
+        * removed in the meantime! */
+       server = Conf_GetServer(idx);
+       if (server < 0) {
+               Log(LOG_ERR, "Connection on socket %d to \"%s\" aborted!",
+                   sock, My_Connections[idx].host);
+               Conn_Close(idx, "Connection aborted!", NULL, false);
+               return;
+       }
 
        /* connect() finished, get result. */
        sock_len = (socklen_t)sizeof(err);
-       res = getsockopt( My_Connections[idx].sock, SOL_SOCKET, SO_ERROR, &err, &sock_len );
-       assert( sock_len == sizeof( err ));
+       res = getsockopt(My_Connections[idx].sock, SOL_SOCKET, SO_ERROR,
+                        &err, &sock_len );
+       assert(sock_len == sizeof(err));
 
        /* Error while connecting? */
        if ((res != 0) || (err != 0)) {
@@ -167,32 +179,28 @@ cb_connserver(int sock, UNUSED short what)
                else
                        Log(LOG_CRIT,
                            "Can't connect socket to \"%s:%d\" (connection %d): %s!",
-                           My_Connections[idx].host,
-                           Conf_Server[Conf_GetServer(idx)].port,
+                           My_Connections[idx].host, Conf_Server[server].port,
                            idx, strerror(err));
 
-               res = Conf_GetServer(idx);
-               assert(res >= 0);
-
                Conn_Close(idx, "Can't connect!", NULL, false);
 
-               if (res < 0)
-                       return;
-               if (ng_ipaddr_af(&Conf_Server[res].dst_addr[0])) {
+               if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
                        /* more addresses to try... */
-                       New_Server(res, &Conf_Server[res].dst_addr[0]);
-                       /* connection to dst_addr[0] in progress, remove this address... */
-                       Conf_Server[res].dst_addr[0] = Conf_Server[res].dst_addr[1];
-
-                       memset(&Conf_Server[res].dst_addr[1], 0, sizeof(Conf_Server[res].dst_addr[1]));
+                       New_Server(res, &Conf_Server[server].dst_addr[0]);
+                       /* connection to dst_addr[0] is now in progress, so
+                        * remove this address... */
+                       Conf_Server[server].dst_addr[0] =
+                               Conf_Server[server].dst_addr[1];
+                       memset(&Conf_Server[server].dst_addr[1], 0,
+                              sizeof(Conf_Server[server].dst_addr[1]));
                }
                return;
        }
 
-       res = Conf_GetServer(idx);
-       assert(res >= 0);
-       if (res >= 0) /* connect succeeded, remove all additional addresses */
-               memset(&Conf_Server[res].dst_addr, 0, sizeof(Conf_Server[res].dst_addr));
+       /* connect() succeeded, remove all additional addresses */
+       memset(&Conf_Server[server].dst_addr, 0,
+              sizeof(Conf_Server[server].dst_addr));
+
        Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING );
 #ifdef SSL_SUPPORT
        if ( Conn_OPTION_ISSET( &My_Connections[idx], CONN_SSL_CONNECT )) {