]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
NewListener(): Code cleanup
[ngircd-alex.git] / src / ngircd / conn.c
index 46a3ecc2caefe0c1dc5fe41754357aadc08db128..07f26f319ca2a4ff8a646202d7e2d001fe5c2408 100644 (file)
 # include <netinet/ip.h>
 #endif
 
-#ifdef HAVE_STDINT_H
-# include <stdint.h>                   /* e.g. for Mac OS X */
-#endif
-
 #ifdef TCPWRAP
 # include <tcpd.h>                     /* for TCP Wrappers */
 #endif
@@ -67,6 +63,7 @@
 #include "client.h"
 #include "class.h"
 #include "conf.h"
+#include "conn-encoding.h"
 #include "conn-ssl.h"
 #include "conn-zip.h"
 #include "conn-func.h"
@@ -88,7 +85,7 @@
 
 static bool Handle_Write PARAMS(( CONN_ID Idx ));
 static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
-static int New_Connection PARAMS(( int Sock ));
+static int New_Connection PARAMS(( int Sock, bool IsSSL ));
 static CONN_ID Socket2Index PARAMS(( int Sock ));
 static void Read_Request PARAMS(( CONN_ID Idx ));
 static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
@@ -134,7 +131,7 @@ static void
 cb_listen(int sock, short irrelevant)
 {
        (void) irrelevant;
-       (void) New_Connection(sock);
+       (void) New_Connection(sock, false);
 }
 
 
@@ -152,7 +149,7 @@ cb_listen_ssl(int sock, short irrelevant)
        int fd;
 
        (void) irrelevant;
-       fd = New_Connection(sock);
+       fd = New_Connection(sock, true);
        if (fd < 0)
                return;
        io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
@@ -208,7 +205,7 @@ cb_connserver(int sock, UNUSED short what)
                            My_Connections[idx].host, Conf_Server[server].port,
                            idx, strerror(err));
 
-               Conn_Close(idx, "Can't connect!", NULL, false);
+               Conn_Close(idx, "Can't connect", NULL, false);
 
                if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
                        /* more addresses to try... */
@@ -285,7 +282,7 @@ cb_connserver_login_ssl(int sock, short unused)
                return;
        case -1:
                Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
-               Conn_Close(idx, "Can't connect!", NULL, false);
+               Conn_Close(idx, "Can't connect", NULL, false);
                return;
        }
 
@@ -571,7 +568,7 @@ InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port
        ret = ng_ipaddr_init(addr, listen_addrstr, Port);
        if (!ret) {
                assert(listen_addrstr);
-               Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"",
+               Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"!",
                                                listen_addrstr, Port, listen_addrstr);
        }
        return ret;
@@ -623,8 +620,9 @@ NewListener(const char *listen_addr, UINT16 Port)
 
        af = ng_ipaddr_af(&addr);
        sock = socket(af, SOCK_STREAM, 0);
-       if( sock < 0 ) {
-               Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
+       if (sock < 0) {
+               Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af,
+                   strerror(errno));
                return -1;
        }
 
@@ -634,22 +632,23 @@ NewListener(const char *listen_addr, UINT16 Port)
                return -1;
 
        if (bind(sock, (struct sockaddr *)&addr, ng_ipaddr_salen(&addr)) != 0) {
-               Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s",
-                       ng_ipaddr_tostr(&addr), Port, strerror(errno));
+               Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s!",
+                   ng_ipaddr_tostr(&addr), Port, strerror(errno));
                close(sock);
                return -1;
        }
 
-       if( listen( sock, 10 ) != 0 ) {
-               Log( LOG_CRIT, "Can't listen on socket: %s!", strerror( errno ));
-               close( sock );
+       if (listen(sock, 10) != 0) {
+               Log(LOG_CRIT, "Can't listen on socket: %s!", strerror(errno));
+               close(sock);
                return -1;
        }
 
        /* keep fd in list so we can close it when ngircd restarts/shuts down */
-       if (!array_catb( &My_Listeners,(char*) &sock, sizeof(int) )) {
-               Log( LOG_CRIT, "Can't add socket to My_Listeners array: %s!", strerror( errno ));
-               close( sock );
+       if (!array_catb(&My_Listeners, (char *)&sock, sizeof(int))) {
+               Log(LOG_CRIT, "Can't add socket to My_Listeners array: %s!",
+                   strerror(errno));
+               close(sock);
                return -1;
        }
 
@@ -865,6 +864,9 @@ va_dcl
 #endif
 {
        char buffer[COMMAND_LEN];
+#ifdef ICONV
+       char *ptr, *message;
+#endif
        size_t len;
        bool ok;
        va_list ap;
@@ -905,6 +907,16 @@ va_dcl
                        CUT_TXTSUFFIX);
        }
 
+#ifdef ICONV
+       ptr = strchr(buffer + 1, ':');
+       if (ptr) {
+               ptr++;
+               message = Conn_EncodingTo(Idx, ptr);
+               if (message != ptr)
+                       strlcpy(ptr, message, sizeof(buffer) - (ptr - buffer));
+       }
+#endif
+
 #ifdef SNIFFER
        if (NGIRCd_Sniffer)
                Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
@@ -932,6 +944,10 @@ GLOBAL void
 Conn_SetPassword( CONN_ID Idx, const char *Pwd )
 {
        assert( Idx > NONE );
+
+       if (My_Connections[Idx].pwd)
+               free(My_Connections[Idx].pwd);
+
        My_Connections[Idx].pwd = strdup(Pwd);
        if (My_Connections[Idx].pwd == NULL) {
                Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
@@ -1064,7 +1080,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
        Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
 
        port = ng_ipaddr_getport(&My_Connections[Idx].addr);
-       Log(LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx,
+       Log(LOG_INFO, "Shutting down connection %d (%s) with \"%s:%d\" ...", Idx,
            LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, port);
 
        /* Search client, if any */
@@ -1138,7 +1154,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
                in_p = (int)(( in_k * 100 ) / in_z_k );
                out_p = (int)(( out_k * 100 ) / out_z_k );
                Log(LOG_INFO,
-                   "Connection %d with %s:%d closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).",
+                   "Connection %d with \"%s:%d\" closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).",
                    Idx, My_Connections[Idx].host, port,
                    in_k, in_z_k, in_p, out_k, out_z_k, out_p);
        }
@@ -1146,7 +1162,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 #endif
        {
                Log(LOG_INFO,
-                   "Connection %d with %s:%d closed (in: %.1fk, out: %.1fk).",
+                   "Connection %d with \"%s:%d\" closed (in: %.1fk, out: %.1fk).",
                    Idx, My_Connections[Idx].host, port,
                    in_k, out_k);
        }
@@ -1358,17 +1374,18 @@ Count_Connections(ng_ipaddr_t *a)
  * Initialize new client connection on a listening socket.
  *
  * @param Sock Listening socket descriptor.
+ * @param IsSSL        true if this socket expects SSL-encrypted data.
  * @returns    Accepted socket descriptor or -1 on error.
  */
 static int
-New_Connection(int Sock)
+New_Connection(int Sock, UNUSED bool IsSSL)
 {
 #ifdef TCPWRAP
        struct request_info req;
 #endif
        ng_ipaddr_t new_addr;
        char ip_str[NG_INET_ADDRSTRLEN];
-       int new_sock, new_sock_len, identsock;
+       int new_sock, new_sock_len;
        CLIENT *c;
        long cnt;
 
@@ -1485,33 +1502,59 @@ New_Connection(int Sock)
 
        Client_SetHostname(c, My_Connections[new_sock].host);
 
-       Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
+       Log(LOG_INFO, "Accepted connection %d from \"%s:%d\" on socket %d.",
            new_sock, My_Connections[new_sock].host,
            ng_ipaddr_getport(&new_addr), Sock);
+       Account_Connection();
+
+#ifdef SSL_SUPPORT
+       /* Delay connection initalization until SSL handshake is finished */
+       if (!IsSSL)
+#endif
+               Conn_StartLogin(new_sock);
+
+       return new_sock;
+} /* New_Connection */
+
+
+/**
+ * Finish connection initialization, start resolver subprocess.
+ *
+ * @param Idx Connection index.
+ */
+GLOBAL void
+Conn_StartLogin(CONN_ID Idx)
+{
+       int ident_sock = -1;
+
+       assert(Idx >= 0);
+
+       /* Nothing to do if DNS (and resolver subprocess) is disabled */
+       if (!Conf_DNS)
+               return;
 
-       identsock = new_sock;
 #ifdef IDENTAUTH
-       if (!Conf_Ident)
-               identsock = -1;
+       /* Should we make an IDENT request? */
+       if (Conf_Ident)
+               ident_sock = My_Connections[Idx].sock;
 #endif
-       if (Conf_DNS) {
-               if (Conf_NoticeAuth) {
+
+       if (Conf_NoticeAuth) {
+               /* Send "NOTICE AUTH" messages to the client */
 #ifdef IDENTAUTH
-                       if (Conf_Ident)
-                               (void)Conn_WriteStr(new_sock,
-                                       "NOTICE AUTH :*** Looking up your hostname and checking ident");
-                       else
+               if (Conf_Ident)
+                       (void)Conn_WriteStr(Idx,
+                               "NOTICE AUTH :*** Looking up your hostname and checking ident");
+               else
 #endif
-                               (void)Conn_WriteStr(new_sock,
-                                       "NOTICE AUTH :*** Looking up your hostname");
-               }
-               Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
-                            identsock, cb_Read_Resolver_Result);
+                       (void)Conn_WriteStr(Idx,
+                               "NOTICE AUTH :*** Looking up your hostname");
+               (void)Handle_Write(Idx);
        }
 
-       Account_Connection();
-       return new_sock;
-} /* New_Connection */
+       Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
+                    ident_sock, cb_Read_Resolver_Result);
+}
 
 
 /**
@@ -1588,13 +1631,10 @@ Read_Request( CONN_ID Idx )
 #endif
        len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
        if (len == 0) {
-               Log(LOG_INFO, "%s:%u (%s) is closing the connection ...",
-                               My_Connections[Idx].host,
-                               (unsigned int) ng_ipaddr_getport(&My_Connections[Idx].addr),
-                               ng_ipaddr_tostr(&My_Connections[Idx].addr));
-               Conn_Close(Idx,
-                          "Socket closed!", "Client closed connection",
-                          false);
+               LogDebug("Client \"%s:%u\" is closing connection %d ...",
+                        My_Connections[Idx].host,
+                        ng_ipaddr_tostr(&My_Connections[Idx].addr), Idx);
+               Conn_Close(Idx, NULL, "Client closed connection", false);
                return;
        }
 
@@ -1602,7 +1642,7 @@ Read_Request( CONN_ID Idx )
                if( errno == EAGAIN ) return;
                Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
                    Idx, My_Connections[Idx].sock, strerror(errno));
-               Conn_Close(Idx, "Read error!", "Client closed connection",
+               Conn_Close(Idx, "Read error", "Client closed connection",
                           false);
                return;
        }
@@ -1861,10 +1901,10 @@ Check_Connections(void)
                                if (My_Connections[i].lastping <
                                    time(NULL) - Conf_PongTimeout) {
                                        /* Timeout */
-                                       LogDebug
-                                           ("Connection %d: Ping timeout: %d seconds.",
-                                            i, Conf_PongTimeout);
-                                       snprintf(msg, sizeof(msg), "Ping timeout: %d seconds", Conf_PongTimeout);
+                                       snprintf(msg, sizeof(msg),
+                                                "Ping timeout: %d seconds",
+                                                Conf_PongTimeout);
+                                       LogDebug("Connection %d: %s.", i, msg);
                                        Conn_Close(i, NULL, msg, true);
                                }
                        } else if (My_Connections[i].lastdata <
@@ -2038,7 +2078,8 @@ New_Server( int Server , ng_ipaddr_t *dest)
        Client_SetToken( c, TOKEN_OUTBOUND );
 
        /* Register connection */
-       Conf_SetServer(Server, new_sock);
+       if (!Conf_SetServer(Server, new_sock))
+               return;
        My_Connections[new_sock].sock = new_sock;
        My_Connections[new_sock].addr = *dest;
        My_Connections[new_sock].client = c;
@@ -2078,6 +2119,11 @@ Init_Conn_Struct(CONN_ID Idx)
        My_Connections[Idx].lastdata = now;
        My_Connections[Idx].lastprivmsg = now;
        Proc_InitStruct(&My_Connections[Idx].proc_stat);
+
+#ifdef ICONV
+       My_Connections[Idx].iconv_from = (iconv_t)(-1);
+       My_Connections[Idx].iconv_to = (iconv_t)(-1);
+#endif
 } /* Init_Conn_Struct */
 
 
@@ -2253,7 +2299,8 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                Client_SetHostname(c, readbuf);
                if (Conf_NoticeAuth)
                        (void)Conn_WriteStr(i,
-                                       "NOTICE AUTH :*** Found your hostname");
+                                       "NOTICE AUTH :*** Found your hostname: %s",
+                                       My_Connections[i].host);
 #ifdef IDENTAUTH
                ++identptr;
                if (*identptr) {
@@ -2278,8 +2325,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                        }
                        if (Conf_NoticeAuth) {
                                (void)Conn_WriteStr(i,
-                                       "NOTICE AUTH :*** Got %sident response",
-                                       *ptr ? "invalid " : "");
+                                       "NOTICE AUTH :*** Got %sident response%s%s",
+                                       *ptr ? "invalid " : "",
+                                       *ptr ? "" : ": ",
+                                       *ptr ? "" : identptr);
                        }
                } else {
                        Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
@@ -2288,6 +2337,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                                        "NOTICE AUTH :*** No ident response");
                }
 #endif
+
+               if (Conf_NoticeAuth)
+                       (void)Handle_Write(i);
+
                Class_HandleServerBans(c);
        }
 #ifdef DEBUG