]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
Add Doxygen @file documentation to each source and header file
[ngircd-alex.git] / src / ngircd / conn.c
index 03e2905cc5af0e1afa70f4299627d0cfbe43a373..e73dd3060e9d51887f21a610418c34b408e4c7f6 100644 (file)
@@ -7,8 +7,6 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
- *
- * Connection management
  */
 
 
 #include "conf-ssl.h"
 #include "io.h"
 
+/**
+ * @file
+ * Connection management
+ */
+
 #include "imp.h"
 #include <assert.h>
 #ifdef PROTOTYPES
 #include "resolve.h"
 #include "tool.h"
 
-#ifdef ZEROCONF
-# include "rendezvous.h"
-#endif
-
 #include "exp.h"
 
 
@@ -82,6 +81,7 @@
 
 #define MAX_COMMANDS 3
 #define MAX_COMMANDS_SERVER 10
+#define MAX_COMMANDS_SERVICE MAX_COMMANDS_SERVER
 
 
 static bool Handle_Write PARAMS(( CONN_ID Idx ));
@@ -207,7 +207,7 @@ cb_connserver(int sock, UNUSED short what)
 
                if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
                        /* more addresses to try... */
-                       New_Server(res, &Conf_Server[server].dst_addr[0]);
+                       New_Server(server, &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] =
@@ -241,8 +241,10 @@ cb_connserver(int sock, UNUSED short what)
 static void
 server_login(CONN_ID idx)
 {
-       Log( LOG_INFO, "Connection %d with \"%s:%d\" established. Now logging in ...", idx,
-                       My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
+       Log(LOG_INFO,
+           "Connection %d (socket %d) with \"%s:%d\" established. Now logging in ...",
+           idx, My_Connections[idx].sock, My_Connections[idx].host,
+           Conf_Server[Conf_GetServer(idx)].port);
 
        io_event_setcb( My_Connections[idx].sock, cb_clientserver);
        io_event_add( My_Connections[idx].sock, IO_WANTREAD|IO_WANTWRITE);
@@ -515,9 +517,6 @@ Conn_ExitListeners( void )
        /* Close down all listening sockets */
        int *fd;
        size_t arraylen;
-#ifdef ZEROCONF
-       Rendezvous_UnregisterListeners( );
-#endif
 
        arraylen = array_length(&My_Listeners, sizeof (int));
        Log(LOG_INFO,
@@ -574,9 +573,7 @@ NewListener(const char *listen_addr, UINT16 Port)
        /* Create new listening socket on specified port */
        ng_ipaddr_t addr;
        int sock, af;
-#ifdef ZEROCONF
-       char name[CLIENT_ID_LEN], *info;
-#endif
+
        if (!InitSinaddrListenAddr(&addr, listen_addr, Port))
                return -1;
 
@@ -612,38 +609,8 @@ NewListener(const char *listen_addr, UINT16 Port)
                return -1;
        }
 
-       Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
-
-#ifdef ZEROCONF
-       /* Get best server description text */
-       if( ! Conf_ServerInfo[0] ) info = Conf_ServerName;
-       else
-       {
-               /* Use server info string */
-               info = NULL;
-               if( Conf_ServerInfo[0] == '[' )
-               {
-                       /* Cut off leading hostname part in "[]" */
-                       info = strchr( Conf_ServerInfo, ']' );
-                       if( info )
-                       {
-                               info++;
-                               while( *info == ' ' ) info++;
-                       }
-               }
-               if( ! info ) info = Conf_ServerInfo;
-       }
-
-       /* Add port number to description if non-standard */
-       if (Port != 6667)
-               snprintf(name, sizeof name, "%s (port %u)", info,
-                        (unsigned int)Port);
-       else
-               strlcpy(name, info, sizeof name);
-
-       /* Register service */
-       Rendezvous_Register( name, MDNS_TYPE, Port );
-#endif
+       Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).",
+           ng_ipaddr_tostr(&addr), Port, sock);
        return sock;
 } /* NewListener */
 
@@ -681,9 +648,11 @@ SSL_WantWrite(const CONNECTION *c)
 }
 #else
 static inline bool
-SSL_WantRead(UNUSED const CONNECTION *c) { return false; }
+SSL_WantRead(UNUSED const CONNECTION *c)
+{ return false; }
 static inline bool
-SSL_WantWrite(UNUSED const CONNECTION *c) { return false; }
+SSL_WantWrite(UNUSED const CONNECTION *c)
+{ return false; }
 #endif
 
 
@@ -706,14 +675,6 @@ Conn_Handler(void)
        while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
                t = time(NULL);
 
-#ifdef ZEROCONF
-               Rendezvous_Handler();
-#endif
-
-               /* Should the configuration be reloaded? */
-               if (NGIRCd_SignalRehash)
-                       NGIRCd_Rehash();
-
                /* Check configured servers and established links */
                Check_Servers();
                Check_Connections();
@@ -900,7 +861,7 @@ static bool
 Conn_Write( CONN_ID Idx, char *Data, size_t Len )
 {
        CLIENT *c;
-       size_t writebuf_limit = WRITEBUFFER_LEN;
+       size_t writebuf_limit = WRITEBUFFER_MAX_LEN;
        assert( Idx > NONE );
        assert( Data != NULL );
        assert( Len > 0 );
@@ -936,7 +897,7 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len )
                /* Uncompressed link:
                 * Check if outbound buffer has enough space for the data. */
                if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
-                   writebuf_limit) {
+                   WRITEBUFFER_FLUSH_LEN) {
                        /* Buffer is full, flush it. Handle_Write deals with
                         * low-level errors, if any. */
                        if (!Handle_Write(Idx))
@@ -948,8 +909,8 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len )
                if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
                    writebuf_limit) {
                        Log(LOG_NOTICE,
-                           "Write buffer overflow (connection %d, size %lu byte)!",
-                           Idx,
+                           "Write buffer overflow (connection %d, limit is %lu bytes, %lu bytes new, %lu bytes pending)!",
+                           Idx, writebuf_limit, Len,
                            (unsigned long)array_bytes(&My_Connections[Idx].wbuf));
                        Conn_Close(Idx, "Write buffer overflow!", NULL, false);
                        return false;
@@ -1022,7 +983,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
                if (FwdMsg)
                        Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
                else
-                       Conn_WriteStr(Idx, "ERROR :Closing connection.");
+                       Conn_WriteStr(Idx, "ERROR :Closing connection");
        }
 
        /* Try to write out the write buffer. Note: Handle_Write() eventually
@@ -1318,7 +1279,7 @@ New_Connection(int Sock)
                    "Refused connection from %s: too may connections (%ld) from this IP address!",
                    ip_str, cnt);
                Simple_Message(new_sock,
-                              "ERROR :Connection refused, too many connections from your IP address!");
+                              "ERROR :Connection refused, too many connections from your IP address");
                close(new_sock);
                return -1;
        }
@@ -1382,10 +1343,10 @@ New_Connection(int Sock)
 
        identsock = new_sock;
 #ifdef IDENTAUTH
-       if (Conf_NoIdent)
+       if (!Conf_Ident)
                identsock = -1;
 #endif
-       if (!Conf_NoDNS)
+       if (Conf_DNS)
                Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
                             identsock, cb_Read_Resolver_Result);
 
@@ -1497,16 +1458,21 @@ Read_Request( CONN_ID Idx )
 
        /* Update connection statistics */
        My_Connections[Idx].bytes_in += len;
+       My_Connections[Idx].bps += Handle_Buffer(Idx);
+
+       /* Make sure that there is still a valid client registered */
+       c = Conn_GetClient(Idx);
+       if (!c)
+               return;
 
        /* Update timestamp of last data received if this connection is
         * registered as a user, server or service connection. Don't update
         * otherwise, so users have at least Conf_PongTimeout seconds time to
         * register with the IRC server -- see Check_Connections().
         * Update "lastping", too, if time shifted backwards ... */
-       c = Conn_GetClient(Idx);
-       if (c && (Client_Type(c) == CLIENT_USER
-                 || Client_Type(c) == CLIENT_SERVER
-                 || Client_Type(c) == CLIENT_SERVICE)) {
+       if (Client_Type(c) == CLIENT_USER
+           || Client_Type(c) == CLIENT_SERVER
+           || Client_Type(c) == CLIENT_SERVICE) {
                t = time(NULL);
                if (My_Connections[Idx].lastdata != t)
                        My_Connections[Idx].bps = 0;
@@ -1517,8 +1483,9 @@ Read_Request( CONN_ID Idx )
        }
 
        /* Look at the data in the (read-) buffer of this connection */
-       My_Connections[Idx].bps += Handle_Buffer(Idx);
        if (Client_Type(c) != CLIENT_SERVER
+           && Client_Type(c) != CLIENT_UNKNOWNSERVER
+           && Client_Type(c) != CLIENT_SERVICE
            && My_Connections[Idx].bps >= maxbps) {
                LogDebug("Throttling connection %d: BPS exceeded! (%u >= %u)",
                         Idx, My_Connections[Idx].bps, maxbps);
@@ -1530,7 +1497,7 @@ Read_Request( CONN_ID Idx )
 /**
  * Handle all data in the connection read-buffer.
  * Data is processed until no complete command is left in the read buffer,
- * or MAX_COMMANDS[_SERVER] commands were processed.
+ * or MAX_COMMANDS[_SERVER|_SERVICE] commands were processed.
  * When a fatal error occurs, the connection is shut down.
  * @param Idx Index of the connection.
  * @return number of bytes processed.
@@ -1555,8 +1522,12 @@ Handle_Buffer(CONN_ID Idx)
 
        /* Servers do get special command limits, so they can process
         * all the messages that are required while peering. */
-       if (Client_Type(c) == CLIENT_SERVER)
-               maxcmd = MAX_COMMANDS_SERVER;
+       switch (Client_Type(c)) {
+           case CLIENT_SERVER:
+               maxcmd = MAX_COMMANDS_SERVER; break;
+           case CLIENT_SERVICE:
+               maxcmd = MAX_COMMANDS_SERVICE; break;
+       }
 
        starttime = time(NULL);
        for (i=0; i < maxcmd; i++) {
@@ -1776,6 +1747,9 @@ Check_Servers(void)
                }
 
                /* Okay, try to connect now */
+               Log(LOG_NOTICE,
+                   "Preparing to establish a new server link for \"%s\" ...",
+                   Conf_Server[i].name);
                Conf_Server[i].lasttry = time_now;
                Conf_Server[i].conn_id = SERVER_WAIT;
                assert(Proc_GetPipeFd(&Conf_Server[i].res_stat) < 0);
@@ -1800,13 +1774,17 @@ New_Server( int Server , ng_ipaddr_t *dest)
                return;
        }
 
-       Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d ... ",
-                       Conf_Server[Server].host, ip_str, Conf_Server[Server].port );
-
        af_dest = ng_ipaddr_af(dest);
        new_sock = socket(af_dest, SOCK_STREAM, 0);
+
+       Log(LOG_INFO,
+           "Establishing connection for \"%s\" to \"%s:%d\" (%s), socket %d ...",
+           Conf_Server[Server].name, Conf_Server[Server].host,
+           Conf_Server[Server].port, ip_str, new_sock);
+
        if (new_sock < 0) {
-               Log( LOG_CRIT, "Can't create socket (af %d) : %s!", af_dest, strerror( errno ));
+               Log(LOG_CRIT, "Can't create socket (af %d): %s!",
+                   af_dest, strerror(errno));
                return;
        }
 
@@ -1933,8 +1911,8 @@ Init_Socket( int Sock )
        LogDebug("Setting IP_TOS on socket %d to IPTOS_LOWDELAY.", Sock);
        if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
                       (socklen_t) sizeof(value))) {
-               Log(LOG_ERR, "Can't set socket option IP_TOS: %s!",
-                   strerror(errno));
+               LogDebug("Can't set socket option IP_TOS: %s!",
+                        strerror(errno));
                /* ignore this error */
        }
 #endif
@@ -1970,8 +1948,11 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 
        /* Read result from pipe */
        len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
-       if (len == 0)
+       if (len == 0) {
+               /* Error resolving hostname: reset server structure */
+               Conf_Server[i].conn_id = NONE;
                return;
+       }
 
        assert((len % sizeof(ng_ipaddr_t)) == 0);
 
@@ -2188,4 +2169,28 @@ Conn_UsesSSL(CONN_ID Idx)
 #endif
 
 
+#ifdef DEBUG
+
+GLOBAL void
+Conn_DebugDump(void)
+{
+       int i;
+
+       Log(LOG_DEBUG, "Connection status:");
+       for (i = 0; i < Pool_Size; i++) {
+               if (My_Connections[i].sock == NONE)
+                       continue;
+               Log(LOG_DEBUG,
+                   " - %d: host=%s, lastdata=%ld, lastping=%ld, delaytime=%ld, flag=%d, options=%d, bps=%d, client=%s",
+                   My_Connections[i].sock, My_Connections[i].host,
+                   My_Connections[i].lastdata, My_Connections[i].lastping,
+                   My_Connections[i].delaytime, My_Connections[i].flag,
+                   My_Connections[i].options, My_Connections[i].bps,
+                   My_Connections[i].client ? Client_ID(My_Connections[i].client) : "-");
+       }
+} /* Conn_DumpClients */
+
+#endif
+
+
 /* -eof- */