]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
Fix cb_connserver() to handle aborted outgoing connections
[ngircd-alex.git] / src / ngircd / conn.c
index d62be359c5435000418d75956e9b5fa2b41e086e..731647d9cda3f5dd7576bbfbebb4e885657c8ee2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
  *
  * 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
@@ -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 = sizeof( err );
-       res = getsockopt( My_Connections[idx].sock, SOL_SOCKET, SO_ERROR, &err, &sock_len );
-       assert( sock_len == sizeof( err ));
+       sock_len = (socklen_t)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 )) {
@@ -485,7 +493,7 @@ set_v6_only(int af, int sock)
        if (af != AF_INET6)
                return;
 
-       if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
+       if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, (socklen_t)sizeof(on)))
                Log(LOG_ERR, "Could not set IPV6_V6ONLY: %s", strerror(errno));
 #else
        (void)af;
@@ -900,7 +908,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
         * sub-processes are closed down. */
 
        CLIENT *c;
-       const char *txt;
        double in_k, out_k;
        UINT16 port;
 #ifdef ZLIB
@@ -923,13 +930,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
        /* Mark link as "closing" */
        Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
 
-       if (LogMsg)
-               txt = LogMsg;
-       else
-               txt = FwdMsg;
-       if (! txt)
-               txt = "Reason unknown";
-
        port = ng_ipaddr_getport(&My_Connections[Idx].addr);
        Log(LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx,
            LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, port);
@@ -1526,7 +1526,7 @@ Handle_Buffer(CONN_ID Idx)
                        return 0;
                }
 
-               len_processed += len;
+               len_processed += (unsigned int)len;
                if (len <= delta) {
                        /* Request is empty (only '\r\n', '\r' or '\n');
                         * delta is 2 ('\r\n') or 1 ('\r' or '\n'), see above */
@@ -1834,7 +1834,8 @@ cb_Connect_to_Server(int fd, UNUSED short events)
        size_t len;
        ng_ipaddr_t dest_addrs[4];      /* we can handle at most 3; but we read up to
                                           four so we can log the 'more than we can handle'
-                                          condition */
+                                          condition. First result is tried immediately, rest
+                                          is saved for later if needed. */
 
        LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events);
 
@@ -1859,13 +1860,13 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 
        LogDebug("Got result from resolver: %u structs (%u bytes).", len/sizeof(ng_ipaddr_t), len);
 
-       memset(&Conf_Server[i].dst_addr, 0, sizeof(&Conf_Server[i].dst_addr));
+       memset(&Conf_Server[i].dst_addr, 0, sizeof(Conf_Server[i].dst_addr));
        if (len > sizeof(ng_ipaddr_t)) {
                /* more than one address for this hostname, remember them
                 * in case first address is unreachable/not available */
                len -= sizeof(ng_ipaddr_t);
-               if (len > sizeof(&Conf_Server[i].dst_addr)) {
-                       len = sizeof(&Conf_Server[i].dst_addr);
+               if (len > sizeof(Conf_Server[i].dst_addr)) {
+                       len = sizeof(Conf_Server[i].dst_addr);
                        Log(LOG_NOTICE,
                                "Notice: Resolver returned more IP Addresses for host than we can handle, additional addresses dropped.");
                }
@@ -2008,4 +2009,6 @@ Conn_UsesSSL(CONN_ID Idx)
        return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);
 }
 #endif
+
+
 /* -eof- */