[BACK]Return to conn.c CVS log [TXT][DIR] Up to [local] / ircnowd / src / ngircd

Annotation of ircnowd/src/ngircd/conn.c, Revision 1.1.1.1

1.1       tomglok     1: /*
                      2:  * ngIRCd -- The Next Generation IRC Daemon
                      3:  * Copyright (c)2001-2019 Alexander Barton (alex@barton.de) and Contributors.
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify
                      6:  * it under the terms of the GNU General Public License as published by
                      7:  * the Free Software Foundation; either version 2 of the License, or
                      8:  * (at your option) any later version.
                      9:  * Please read the file COPYING, README and AUTHORS for more information.
                     10:  */
                     11:
                     12: #define CONN_MODULE
                     13: #define CONN_MODULE_GLOBAL_INIT
                     14:
                     15: #include "portab.h"
                     16:
                     17: /**
                     18:  * @file
                     19:  * Connection management
                     20:  */
                     21:
                     22: /* Additionan debug messages related to buffer handling: 0=off / 1=on */
                     23: #define DEBUG_BUFFER 0
                     24:
                     25: #include <assert.h>
                     26: #ifdef PROTOTYPES
                     27: # include <stdarg.h>
                     28: #else
                     29: # include <varargs.h>
                     30: #endif
                     31: #include <stdio.h>
                     32: #include <stdlib.h>
                     33: #include <unistd.h>
                     34: #include <errno.h>
                     35: #include <string.h>
                     36: #include <strings.h>
                     37: #include <sys/socket.h>
                     38: #include <sys/stat.h>
                     39: #include <sys/types.h>
                     40: #include <time.h>
                     41: #include <netinet/in.h>
                     42:
                     43: #ifdef HAVE_NETINET_IP_H
                     44: # ifdef HAVE_NETINET_IN_SYSTM_H
                     45: #  include <netinet/in_systm.h>
                     46: # endif
                     47: # include <netinet/ip.h>
                     48: #endif
                     49:
                     50: #ifdef TCPWRAP
                     51: # include <tcpd.h>                     /* for TCP Wrappers */
                     52: #endif
                     53:
                     54: #include "conn.h"
                     55:
                     56: #include "ngircd.h"
                     57: #include "class.h"
                     58: #ifdef ICONV
                     59: # include "conn-encoding.h"
                     60: #endif
                     61: #include "conn-ssl.h"
                     62: #include "conn-zip.h"
                     63: #include "conn-func.h"
                     64: #include "io.h"
                     65: #include "log.h"
                     66: #include "ng_ipaddr.h"
                     67: #include "parse.h"
                     68: #include "resolve.h"
                     69:
                     70: #define SERVER_WAIT (NONE - 1)         /** "Wait for outgoing connection" flag */
                     71:
                     72: #define MAX_COMMANDS 3                 /** Max. commands per loop for users */
                     73: #define MAX_COMMANDS_SERVER_MIN 10     /** Min. commands per loop for servers */
                     74: #define MAX_COMMANDS_SERVICE 10                /** Max. commands per loop for services */
                     75:
                     76: #define SD_LISTEN_FDS_START 3          /** systemd(8) socket activation offset */
                     77:
                     78: #define THROTTLE_CMDS 1                        /** Throttling: max commands reached */
                     79: #define THROTTLE_BPS 2                 /** Throttling: max bps reached */
                     80:
                     81: static bool Handle_Write PARAMS(( CONN_ID Idx ));
                     82: static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
                     83: static int New_Connection PARAMS(( int Sock, bool IsSSL ));
                     84: static CONN_ID Socket2Index PARAMS(( int Sock ));
                     85: static void Read_Request PARAMS(( CONN_ID Idx ));
                     86: static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
                     87: static void Check_Connections PARAMS(( void ));
                     88: static void Check_Servers PARAMS(( void ));
                     89: static void Init_Conn_Struct PARAMS(( CONN_ID Idx ));
                     90: static bool Init_Socket PARAMS(( int Sock ));
                     91: static void New_Server PARAMS(( int Server, ng_ipaddr_t *dest ));
                     92: static void Simple_Message PARAMS(( int Sock, const char *Msg ));
                     93: static int NewListener PARAMS(( const char *listen_addr, UINT16 Port ));
                     94: static void Account_Connection PARAMS((void));
                     95: static void Throttle_Connection PARAMS((const CONN_ID Idx, CLIENT *Client,
                     96:                                        const int Reason, unsigned int Value));
                     97:
                     98: static array My_Listeners;
                     99: static array My_ConnArray;
                    100: static size_t NumConnections, NumConnectionsMax, NumConnectionsAccepted;
                    101:
                    102: #ifdef TCPWRAP
                    103: int allow_severity = LOG_INFO;
                    104: int deny_severity = LOG_ERR;
                    105: #endif
                    106:
                    107: static void server_login PARAMS((CONN_ID idx));
                    108:
                    109: #ifdef SSL_SUPPORT
                    110: extern struct SSLOptions Conf_SSLOptions;
                    111: static bool SSL_WantRead PARAMS((const CONNECTION *c));
                    112: static bool SSL_WantWrite PARAMS((const CONNECTION *c));
                    113: static void cb_listen_ssl PARAMS((int sock, short irrelevant));
                    114: static void cb_connserver_login_ssl PARAMS((int sock, short what));
                    115: static void cb_clientserver_ssl PARAMS((int sock, short what));
                    116: #endif
                    117: static void cb_Read_Resolver_Result PARAMS((int sock, UNUSED short what));
                    118: static void cb_Connect_to_Server PARAMS((int sock, UNUSED short what));
                    119: static void cb_clientserver PARAMS((int sock, short what));
                    120:
                    121: time_t idle_t = 0;
                    122:
                    123: /**
                    124:  * Get number of sockets available from systemd(8).
                    125:  *
                    126:  * ngIRCd needs to implement its own sd_listen_fds(3) function and can't
                    127:  * use the one provided by systemd itself, because the sockets will be
                    128:  * used in a forked child process with a new PID, and this would trigger
                    129:  * an error in the standard implementation.
                    130:  *
                    131:  * @return Number of sockets available, -1 if sockets have already been
                    132:  *         initialized, or 0 when no sockets have been passed.
                    133:  */
                    134: static int
                    135: my_sd_listen_fds(void)
                    136: {
                    137:        const char *e;
                    138:        int count;
                    139:
                    140:        /* Check if LISTEN_PID exists; but we ignore the result, because
                    141:         * normally ngircd forks a child before checking this, and therefore
                    142:         * the PID set in the environment is always wrong ... */
                    143:        e = getenv("LISTEN_PID");
                    144:        if (!e || !*e)
                    145:                return 0;
                    146:
                    147:        e = getenv("LISTEN_FDS");
                    148:        if (!e || !*e)
                    149:                return -1;
                    150:        count = atoi(e);
                    151: #ifdef HAVE_UNSETENV
                    152:        unsetenv("LISTEN_FDS");
                    153: #endif
                    154:
                    155:        return count;
                    156: }
                    157:
                    158: /**
                    159:  * IO callback for listening sockets: handle new connections. This callback
                    160:  * gets called when a new non-SSL connection should be accepted.
                    161:  *
                    162:  * @param sock         Socket descriptor.
                    163:  * @param irrelevant   (ignored IO specification)
                    164:  */
                    165: static void
                    166: cb_listen(int sock, short irrelevant)
                    167: {
                    168:        (void) irrelevant;
                    169:        (void) New_Connection(sock, false);
                    170: }
                    171:
                    172: /**
                    173:  * IO callback for new outgoing non-SSL server connections.
                    174:  *
                    175:  * @param sock Socket descriptor.
                    176:  * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...).
                    177:  */
                    178: static void
                    179: cb_connserver(int sock, UNUSED short what)
                    180: {
                    181:        int res, err, server;
                    182:        socklen_t sock_len;
                    183:        CONN_ID idx = Socket2Index( sock );
                    184:
                    185:        if (idx <= NONE) {
                    186:                io_close(sock);
                    187:                return;
                    188:        }
                    189:
                    190:        assert(what & IO_WANTWRITE);
                    191:
                    192:        /* Make sure that the server is still configured; it could have been
                    193:         * removed in the meantime! */
                    194:        server = Conf_GetServer(idx);
                    195:        if (server < 0) {
                    196:                Log(LOG_ERR, "Connection on socket %d to \"%s\" aborted!",
                    197:                    sock, My_Connections[idx].host);
                    198:                Conn_Close(idx, "Connection aborted", NULL, false);
                    199:                return;
                    200:        }
                    201:
                    202:        /* connect() finished, get result. */
                    203:        sock_len = (socklen_t)sizeof(err);
                    204:        res = getsockopt(My_Connections[idx].sock, SOL_SOCKET, SO_ERROR,
                    205:                         &err, &sock_len );
                    206:        assert(sock_len == sizeof(err));
                    207:
                    208:        /* Error while connecting? */
                    209:        if ((res != 0) || (err != 0)) {
                    210:                if (res != 0)
                    211:                        Log(LOG_CRIT, "getsockopt (connection %d): %s!",
                    212:                            idx, strerror(errno));
                    213:                else
                    214:                        Log(LOG_CRIT,
                    215:                            "Can't connect socket to \"%s:%d\" (connection %d): %s!",
                    216:                            My_Connections[idx].host, Conf_Server[server].port,
                    217:                            idx, strerror(err));
                    218:
                    219:                Conn_Close(idx, "Can't connect", NULL, false);
                    220:
                    221:                if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
                    222:                        /* more addresses to try... */
                    223:                        New_Server(server, &Conf_Server[server].dst_addr[0]);
                    224:                        /* connection to dst_addr[0] is now in progress, so
                    225:                         * remove this address... */
                    226:                        Conf_Server[server].dst_addr[0] =
                    227:                                Conf_Server[server].dst_addr[1];
                    228:                        memset(&Conf_Server[server].dst_addr[1], 0,
                    229:                               sizeof(Conf_Server[server].dst_addr[1]));
                    230:                }
                    231:                return;
                    232:        }
                    233:
                    234:        /* connect() succeeded, remove all additional addresses */
                    235:        memset(&Conf_Server[server].dst_addr, 0,
                    236:               sizeof(Conf_Server[server].dst_addr));
                    237:
                    238:        Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING );
                    239: #ifdef SSL_SUPPORT
                    240:        if ( Conn_OPTION_ISSET( &My_Connections[idx], CONN_SSL_CONNECT )) {
                    241:                io_event_setcb( sock, cb_connserver_login_ssl );
                    242:                io_event_add( sock, IO_WANTWRITE|IO_WANTREAD );
                    243:                return;
                    244:        }
                    245: #endif
                    246:        server_login(idx);
                    247: }
                    248:
                    249: /**
                    250:  * Login to a remote server.
                    251:  *
                    252:  * @param idx  Connection index.
                    253:  */
                    254: static void
                    255: server_login(CONN_ID idx)
                    256: {
                    257:        Log(LOG_INFO,
                    258:            "Connection %d (socket %d) with \"%s:%d\" established. Now logging in ...",
                    259:            idx, My_Connections[idx].sock, My_Connections[idx].host,
                    260:            Conf_Server[Conf_GetServer(idx)].port);
                    261:
                    262:        io_event_setcb( My_Connections[idx].sock, cb_clientserver);
                    263:        io_event_add( My_Connections[idx].sock, IO_WANTREAD|IO_WANTWRITE);
                    264:
                    265:        /* Send PASS and SERVER command to peer */
                    266:        Conn_WriteStr(idx, "PASS %s %s",
                    267:                      Conf_Server[Conf_GetServer( idx )].pwd_out, NGIRCd_ProtoID);
                    268:        Conn_WriteStr(idx, "SERVER %s :%s",
                    269:                      Conf_ServerName, Conf_ServerInfo);
                    270: }
                    271:
                    272: /**
                    273:  * IO callback for established non-SSL client and server connections.
                    274:  *
                    275:  * @param sock Socket descriptor.
                    276:  * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...).
                    277:  */
                    278: static void
                    279: cb_clientserver(int sock, short what)
                    280: {
                    281:        CONN_ID idx = Socket2Index(sock);
                    282:
                    283:        if (idx <= NONE) {
                    284:                io_close(sock);
                    285:                return;
                    286:        }
                    287:
                    288: #ifdef SSL_SUPPORT
                    289:        if (what & IO_WANTREAD
                    290:            || (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE))) {
                    291:                /* if TLS layer needs to write additional data, call
                    292:                 * Read_Request() instead so that SSL/TLS can continue */
                    293:                Read_Request(idx);
                    294:        }
                    295: #else
                    296:        if (what & IO_WANTREAD)
                    297:                Read_Request(idx);
                    298: #endif
                    299:        if (what & IO_WANTWRITE)
                    300:                Handle_Write(idx);
                    301: }
                    302:
                    303: /**
                    304:  * Initialize connection module.
                    305:  */
                    306: GLOBAL void
                    307: Conn_Init( void )
                    308: {
                    309:        int size;
                    310:
                    311:        /* Initialize the "connection pool".
                    312:         * FIXME: My_Connetions/Pool_Size is needed by other parts of the
                    313:         * code; remove them! */
                    314:        Pool_Size = 0;
                    315:        size = Conf_MaxConnections > 0 ? Conf_MaxConnections : CONNECTION_POOL;
                    316:        if (Socket2Index(size) <= NONE) {
                    317:                Log(LOG_EMERG, "Failed to initialize connection pool!");
                    318:                exit(1);
                    319:        }
                    320:
                    321:        /* Initialize "listener" array. */
                    322:        array_free( &My_Listeners );
                    323: } /* Conn_Init */
                    324:
                    325: /**
                    326:  * Clean up connection module.
                    327:  */
                    328: GLOBAL void
                    329: Conn_Exit( void )
                    330: {
                    331:        CONN_ID idx;
                    332:
                    333:        Conn_ExitListeners();
                    334:
                    335:        LogDebug("Shutting down all connections ..." );
                    336:        for( idx = 0; idx < Pool_Size; idx++ ) {
                    337:                if( My_Connections[idx].sock > NONE ) {
                    338:                        Conn_Close( idx, NULL, NGIRCd_SignalRestart ?
                    339:                                "Server going down (restarting)":"Server going down", true );
                    340:                }
                    341:        }
                    342:
                    343:        array_free(&My_ConnArray);
                    344:        My_Connections = NULL;
                    345:        Pool_Size = 0;
                    346:        io_library_shutdown();
                    347: } /* Conn_Exit */
                    348:
                    349: /**
                    350:  * Close all sockets (file descriptors) of open connections.
                    351:  * This is useful in forked child processes, for example, to make sure that
                    352:  * they don't hold connections open that the main process wants to close.
                    353:  */
                    354: GLOBAL void
                    355: Conn_CloseAllSockets(int ExceptOf)
                    356: {
                    357:        CONN_ID idx;
                    358:
                    359:        for(idx = 0; idx < Pool_Size; idx++) {
                    360:                if(My_Connections[idx].sock > NONE &&
                    361:                   My_Connections[idx].sock != ExceptOf)
                    362:                        close(My_Connections[idx].sock);
                    363:        }
                    364: }
                    365:
                    366: /**
                    367:  * Initialize listening ports.
                    368:  *
                    369:  * @param a            Array containing the ports the daemon should listen on.
                    370:  * @param listen_addr  Address the socket should listen on (can be "0.0.0.0").
                    371:  * @param func         IO callback function to register.
                    372:  * @returns            Number of listening sockets created.
                    373:  */
                    374: static unsigned int
                    375: Init_Listeners(array *a, const char *listen_addr, void (*func)(int,short))
                    376: {
                    377:        unsigned int created = 0;
                    378:        size_t len;
                    379:        int fd;
                    380:        UINT16 *port;
                    381:
                    382:        len = array_length(a, sizeof (UINT16));
                    383:        port = array_start(a);
                    384:        while (len--) {
                    385:                fd = NewListener(listen_addr, *port);
                    386:                if (fd < 0) {
                    387:                        port++;
                    388:                        continue;
                    389:                }
                    390:                if (!io_event_create( fd, IO_WANTREAD, func )) {
                    391:                        Log(LOG_ERR,
                    392:                            "io_event_create(): Can't add fd %d (port %u): %s!",
                    393:                            fd, (unsigned int) *port, strerror(errno));
                    394:                        close(fd);
                    395:                        port++;
                    396:                        continue;
                    397:                }
                    398:                created++;
                    399:                port++;
                    400:        }
                    401:        return created;
                    402: }
                    403:
                    404: /**
                    405:  * Initialize all listening sockets.
                    406:  *
                    407:  * @returns    Number of created listening sockets
                    408:  */
                    409: GLOBAL unsigned int
                    410: Conn_InitListeners( void )
                    411: {
                    412:        /* Initialize ports on which the server should accept connections */
                    413:        unsigned int created = 0;
                    414:        char *af_str, *copy, *listen_addr;
                    415:        int count, fd, i, addr_len;
                    416:        ng_ipaddr_t addr;
                    417:
                    418:        assert(Conf_ListenAddress);
                    419:
                    420:        count = my_sd_listen_fds();
                    421:        if (count < 0) {
                    422:                Log(LOG_INFO,
                    423:                    "Not re-initializing listening sockets of systemd(8) ...");
                    424:                return 0;
                    425:        }
                    426:        if (count > 0) {
                    427:                /* systemd(8) passed sockets to us, so don't try to initialize
                    428:                 * listening sockets on our own but use the passed ones */
                    429:                LogDebug("Initializing %d systemd sockets ...", count);
                    430:                for (i = 0; i < count; i++) {
                    431:                        fd = SD_LISTEN_FDS_START + i;
                    432:                        addr_len = (int)sizeof(addr);
                    433:                        getsockname(fd, (struct sockaddr *)&addr,
                    434:                                    (socklen_t*)&addr_len);
                    435: #ifdef WANT_IPV6
                    436:                        if (addr.sin4.sin_family != AF_INET
                    437:                            && addr.sin4.sin_family != AF_INET6)
                    438: #else
                    439:                        if (addr.sin4.sin_family != AF_INET)
                    440: #endif
                    441:                        {
                    442:                                /* Socket is of unsupported type! For example,
                    443:                                 * systemd passed in an IPv6 socket but ngIRCd
                    444:                                 * isn't compiled with IPv6 support. */
                    445:                                switch (addr.sin4.sin_family)
                    446:                                {
                    447:                                        case AF_UNSPEC: af_str = "AF_UNSPEC"; break;
                    448:                                        case AF_UNIX: af_str = "AF_UNIX"; break;
                    449:                                        case AF_INET: af_str = "AF_INET"; break;
                    450: #ifdef AF_INET6
                    451:                                        case AF_INET6: af_str = "AF_INET6"; break;
                    452: #endif
                    453: #ifdef AF_NETLINK
                    454:                                        case AF_NETLINK: af_str = "AF_NETLINK"; break;
                    455: #endif
                    456:                                        default: af_str = "unknown"; break;
                    457:                                }
                    458:                                Log(LOG_CRIT,
                    459:                                    "Socket %d is of unsupported type \"%s\" (%d), have to ignore it!",
                    460:                                    fd, af_str, addr.sin4.sin_family);
                    461:                                close(fd);
                    462:                                continue;
                    463:                        }
                    464:
                    465:                        Init_Socket(fd);
                    466:                        if (!io_event_create(fd, IO_WANTREAD, cb_listen)) {
                    467:                                Log(LOG_ERR,
                    468:                                    "io_event_create(): Can't add fd %d: %s!",
                    469:                                    fd, strerror(errno));
                    470:                                continue;
                    471:                        }
                    472:                        Log(LOG_INFO,
                    473:                            "Initialized socket %d from systemd(8): %s:%d.", fd,
                    474:                            ng_ipaddr_tostr(&addr), ng_ipaddr_getport(&addr));
                    475:                        created++;
                    476:                }
                    477:                return created;
                    478:        }
                    479:
                    480:        /* not using systemd socket activation, initialize listening sockets: */
                    481:
                    482:        /* can't use Conf_ListenAddress directly, see below */
                    483:        copy = strdup(Conf_ListenAddress);
                    484:        if (!copy) {
                    485:                Log(LOG_CRIT, "Cannot copy %s: %s", Conf_ListenAddress,
                    486:                    strerror(errno));
                    487:                return 0;
                    488:        }
                    489:        listen_addr = strtok(copy, ",");
                    490:
                    491:        while (listen_addr) {
                    492:                ngt_TrimStr(listen_addr);
                    493:                if (*listen_addr) {
                    494:                        created += Init_Listeners(&Conf_ListenPorts,
                    495:                                                  listen_addr, cb_listen);
                    496: #ifdef SSL_SUPPORT
                    497:                        created += Init_Listeners(&Conf_SSLOptions.ListenPorts,
                    498:                                                  listen_addr, cb_listen_ssl);
                    499: #endif
                    500:                }
                    501:
                    502:                listen_addr = strtok(NULL, ",");
                    503:        }
                    504:
                    505:        /* Can't free() Conf_ListenAddress here: on REHASH, if the config file
                    506:         * cannot be re-loaded, we'd end up with a NULL Conf_ListenAddress.
                    507:         * Instead, free() takes place in conf.c, before the config file
                    508:         * is being parsed. */
                    509:        free(copy);
                    510:
                    511:        return created;
                    512: } /* Conn_InitListeners */
                    513:
                    514: /**
                    515:  * Shut down all listening sockets.
                    516:  */
                    517: GLOBAL void
                    518: Conn_ExitListeners( void )
                    519: {
                    520:        /* Close down all listening sockets */
                    521:        int *fd;
                    522:        size_t arraylen;
                    523:
                    524:        /* Get number of listening sockets to shut down. There can be none
                    525:         * if ngIRCd has been "socket activated" by systemd. */
                    526:        arraylen = array_length(&My_Listeners, sizeof (int));
                    527:        if (arraylen < 1)
                    528:                return;
                    529:
                    530:        Log(LOG_INFO,
                    531:            "Shutting down all listening sockets (%d total) ...", arraylen);
                    532:        fd = array_start(&My_Listeners);
                    533:        while(arraylen--) {
                    534:                assert(fd != NULL);
                    535:                assert(*fd >= 0);
                    536:                io_close(*fd);
                    537:                LogDebug("Listening socket %d closed.", *fd );
                    538:                fd++;
                    539:        }
                    540:        array_free(&My_Listeners);
                    541: } /* Conn_ExitListeners */
                    542:
                    543: /**
                    544:  * Bind a socket to a specific (source) address.
                    545:  *
                    546:  * @param addr                 Address structure.
                    547:  * @param listen_addrstr       Source address as string.
                    548:  * @param Port                 Port number.
                    549:  * @returns                    true on success, false otherwise.
                    550:  */
                    551: static bool
                    552: InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port)
                    553: {
                    554:        bool ret;
                    555:
                    556:        ret = ng_ipaddr_init(addr, listen_addrstr, Port);
                    557:        if (!ret) {
                    558:                assert(listen_addrstr);
                    559:                Log(LOG_CRIT,
                    560:                    "Can't listen on [%s]:%u: Failed to parse IP address!",
                    561:                    listen_addrstr, Port);
                    562:        }
                    563:        return ret;
                    564: }
                    565:
                    566: /**
                    567:  * Set a socket to "IPv6 only". If the given socket doesn't belong to the
                    568:  * AF_INET6 family, or the operating system doesn't support this functionality,
                    569:  * this function retruns silently.
                    570:  *
                    571:  * @param af   Address family of the socket.
                    572:  * @param sock Socket handle.
                    573:  */
                    574: static void
                    575: set_v6_only(int af, int sock)
                    576: {
                    577: #if defined(IPV6_V6ONLY) && defined(WANT_IPV6)
                    578:        int on = 1;
                    579:
                    580:        if (af != AF_INET6)
                    581:                return;
                    582:
                    583:        if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, (socklen_t)sizeof(on)))
                    584:                Log(LOG_ERR, "Could not set IPV6_V6ONLY: %s", strerror(errno));
                    585: #else
                    586:        (void)af;
                    587:        (void)sock;
                    588: #endif
                    589: }
                    590:
                    591: /**
                    592:  * Initialize new listening port.
                    593:  *
                    594:  * @param listen_addr  Local address to bind the socet to (can be 0.0.0.0).
                    595:  * @param Port         Port number on which the new socket should be listening.
                    596:  * @returns            file descriptor of the socket or -1 on failure.
                    597:  */
                    598: static int
                    599: NewListener(const char *listen_addr, UINT16 Port)
                    600: {
                    601:        /* Create new listening socket on specified port */
                    602:        ng_ipaddr_t addr;
                    603:        int sock, af;
                    604:
                    605:        if (!InitSinaddrListenAddr(&addr, listen_addr, Port))
                    606:                return -1;
                    607:
                    608:        af = ng_ipaddr_af(&addr);
                    609:        sock = socket(af, SOCK_STREAM, 0);
                    610:        if (sock < 0) {
                    611:                Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af,
                    612:                    strerror(errno));
                    613:                return -1;
                    614:        }
                    615:
                    616:        set_v6_only(af, sock);
                    617:
                    618:        if (!Init_Socket(sock))
                    619:                return -1;
                    620:
                    621:        if (bind(sock, (struct sockaddr *)&addr, ng_ipaddr_salen(&addr)) != 0) {
                    622:                Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s!",
                    623:                    ng_ipaddr_tostr(&addr), Port, strerror(errno));
                    624:                close(sock);
                    625:                return -1;
                    626:        }
                    627:
                    628:        if (listen(sock, 10) != 0) {
                    629:                Log(LOG_CRIT, "Can't listen on socket: %s!", strerror(errno));
                    630:                close(sock);
                    631:                return -1;
                    632:        }
                    633:
                    634:        /* keep fd in list so we can close it when ngircd restarts/shuts down */
                    635:        if (!array_catb(&My_Listeners, (char *)&sock, sizeof(int))) {
                    636:                Log(LOG_CRIT, "Can't add socket to My_Listeners array: %s!",
                    637:                    strerror(errno));
                    638:                close(sock);
                    639:                return -1;
                    640:        }
                    641:
                    642:        Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).",
                    643:            ng_ipaddr_tostr(&addr), Port, sock);
                    644:        return sock;
                    645: } /* NewListener */
                    646:
                    647: /**
                    648:  * "Main Loop": Loop until shutdown or restart is signalled.
                    649:  *
                    650:  * This function loops until a shutdown or restart of ngIRCd is signalled and
                    651:  * calls io_dispatch() to check for readable and writable sockets every second.
                    652:  * It checks for status changes on pending connections (e. g. when a hostname
                    653:  * has been resolved), checks for "penalties" and timeouts, and handles the
                    654:  * input buffers.
                    655:  */
                    656: GLOBAL void
                    657: Conn_Handler(void)
                    658: {
                    659:        int i;
                    660:        size_t wdatalen;
                    661:        struct timeval tv;
                    662:        time_t t;
                    663:        bool command_available;
                    664:
                    665:        Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.",
                    666:            Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer()));
                    667:
                    668:        while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
                    669:                t = time(NULL);
                    670:                command_available = false;
                    671:
                    672:                /* Check configured servers and established links */
                    673:                Check_Servers();
                    674:                Check_Connections();
                    675:
                    676:                /* Expire outdated class/list items */
                    677:                Class_Expire();
                    678:
                    679:                /* Look for non-empty read buffers ... */
                    680:                for (i = 0; i < Pool_Size; i++) {
                    681:                        if ((My_Connections[i].sock > NONE)
                    682:                            && (array_bytes(&My_Connections[i].rbuf) > 0)) {
                    683:                                /* ... and try to handle the received data */
                    684:                                Handle_Buffer(i);
                    685:                        }
                    686:                }
                    687:
                    688:                /* Look for non-empty write buffers ... */
                    689:                for (i = 0; i < Pool_Size; i++) {
                    690:                        if (My_Connections[i].sock <= NONE)
                    691:                                continue;
                    692:
                    693:                        wdatalen = array_bytes(&My_Connections[i].wbuf);
                    694: #ifdef ZLIB
                    695:                        if (wdatalen > 0 ||
                    696:                            array_bytes(&My_Connections[i].zip.wbuf) > 0)
                    697: #else
                    698:                        if (wdatalen > 0)
                    699: #endif
                    700:                        {
                    701: #ifdef SSL_SUPPORT
                    702:                                if (SSL_WantRead(&My_Connections[i]))
                    703:                                        continue;
                    704: #endif
                    705:                                io_event_add(My_Connections[i].sock,
                    706:                                             IO_WANTWRITE);
                    707:                        }
                    708:                }
                    709:
                    710:                /* Check from which sockets we possibly could read ... */
                    711:                for (i = 0; i < Pool_Size; i++) {
                    712:                        if (My_Connections[i].sock <= NONE)
                    713:                                continue;
                    714: #ifdef SSL_SUPPORT
                    715:                        if (SSL_WantWrite(&My_Connections[i]))
                    716:                                /* TLS/SSL layer needs to write data; deal
                    717:                                 * with this first! */
                    718:                                continue;
                    719: #endif
                    720:                        if (Proc_InProgress(&My_Connections[i].proc_stat)) {
                    721:                                /* Wait for completion of forked subprocess
                    722:                                 * and ignore the socket in the meantime ... */
                    723:                                io_event_del(My_Connections[i].sock,
                    724:                                             IO_WANTREAD);
                    725:                                continue;
                    726:                        }
                    727:
                    728:                        if (Conn_OPTION_ISSET(&My_Connections[i], CONN_ISCONNECTING))
                    729:                                /* Wait for completion of connect() ... */
                    730:                                continue;
                    731:
                    732:                        if (My_Connections[i].delaytime > t) {
                    733:                                /* There is a "penalty time" set: ignore socket! */
                    734:                                io_event_del(My_Connections[i].sock,
                    735:                                             IO_WANTREAD);
                    736:                                continue;
                    737:                        }
                    738:
                    739:                        if (array_bytes(&My_Connections[i].rbuf) >= COMMAND_LEN) {
                    740:                                /* There is still more data in the read buffer
                    741:                                 * than a single valid command can get long:
                    742:                                 * so either there is a complete command, or
                    743:                                 * invalid data. Therefore don't try to read in
                    744:                                 * even more data from the network but wait for
                    745:                                 * this command(s) to be handled first! */
                    746:                                io_event_del(My_Connections[i].sock,
                    747:                                             IO_WANTREAD);
                    748:                                command_available = true;
                    749:                                continue;
                    750:                        }
                    751:
                    752:                        io_event_add(My_Connections[i].sock, IO_WANTREAD);
                    753:                }
                    754:
                    755:                /* Don't wait for data when there is still at least one command
                    756:                 * available in a read buffer which can be handled immediately;
                    757:                 * set the timeout for reading from the network to 1 second
                    758:                 * otherwise, which is the granularity with witch we handle
                    759:                 * "penalty times" for example.
                    760:                 * Note: tv_sec/usec are undefined(!) after io_dispatch()
                    761:                 * returns, so we have to set it before each call to it! */
                    762:                tv.tv_usec = 0;
                    763:                tv.tv_sec = command_available ? 0 : 1;
                    764:
                    765:                /* Wait for activity ... */
                    766:                i = io_dispatch(&tv);
                    767:                if (i == -1 && errno != EINTR) {
                    768:                        Log(LOG_EMERG, "Conn_Handler(): io_dispatch(): %s!",
                    769:                            strerror(errno));
                    770:                        Log(LOG_ALERT, "%s exiting due to fatal errors!",
                    771:                            PACKAGE_NAME);
                    772:                        exit(1);
                    773:                }
                    774:
                    775:                /* Should ngIRCd timeout when idle? */
                    776:                if (Conf_IdleTimeout > 0 && NumConnectionsAccepted > 0
                    777:                    && idle_t > 0 && time(NULL) - idle_t >= Conf_IdleTimeout) {
                    778:                        LogDebug("Server idle timeout reached: %d second%s. Initiating shutdown ...",
                    779:                                 Conf_IdleTimeout,
                    780:                                 Conf_IdleTimeout == 1 ? "" : "s");
                    781:                        NGIRCd_SignalQuit = true;
                    782:                }
                    783:        }
                    784:
                    785:        if (NGIRCd_SignalQuit)
                    786:                Log(LOG_NOTICE | LOG_snotice, "Server going down NOW!");
                    787:        else if (NGIRCd_SignalRestart)
                    788:                Log(LOG_NOTICE | LOG_snotice, "Server restarting NOW!");
                    789: } /* Conn_Handler */
                    790:
                    791: /**
                    792:  * Write a text string into the socket of a connection.
                    793:  *
                    794:  * This function automatically appends CR+LF to the string and validates that
                    795:  * the result is a valid IRC message (oversized messages are shortened, for
                    796:  * example). Then it calls the Conn_Write() function to do the actual sending.
                    797:  *
                    798:  * @param Idx          Index fo the connection.
                    799:  * @param Format       Format string, see printf().
                    800:  * @returns            true on success, false otherwise.
                    801:  */
                    802: #ifdef PROTOTYPES
                    803: GLOBAL bool
                    804: Conn_WriteStr(CONN_ID Idx, const char *Format, ...)
                    805: #else
                    806: GLOBAL bool
                    807: Conn_WriteStr(Idx, Format, va_alist)
                    808: CONN_ID Idx;
                    809: const char *Format;
                    810: va_dcl
                    811: #endif
                    812: {
                    813:        char buffer[COMMAND_LEN];
                    814: #ifdef ICONV
                    815:        char *ptr, *message;
                    816: #endif
                    817:        size_t len;
                    818:        bool ok;
                    819:        va_list ap;
                    820:        int r;
                    821:
                    822:        assert( Idx > NONE );
                    823:        assert( Format != NULL );
                    824:
                    825: #ifdef PROTOTYPES
                    826:        va_start( ap, Format );
                    827: #else
                    828:        va_start( ap );
                    829: #endif
                    830:        r = vsnprintf(buffer, COMMAND_LEN - 2, Format, ap);
                    831:        if (r >= COMMAND_LEN - 2 || r == -1) {
                    832:                /*
                    833:                 * The string that should be written to the socket is longer
                    834:                 * than the allowed size of COMMAND_LEN bytes (including both
                    835:                 * the CR and LF characters). This can be caused by the
                    836:                 * IRC_WriteXXX() functions when the prefix of this server had
                    837:                 * to be added to an already "quite long" command line which
                    838:                 * has been received from a regular IRC client, for example.
                    839:                 *
                    840:                 * We are not allowed to send such "oversized" messages to
                    841:                 * other servers and clients, see RFC 2812 2.3 and 2813 3.3
                    842:                 * ("these messages SHALL NOT exceed 512 characters in length,
                    843:                 * counting all characters including the trailing CR-LF").
                    844:                 *
                    845:                 * So we have a big problem here: we should send more bytes
                    846:                 * to the network than we are allowed to and we don't know
                    847:                 * the originator (any more). The "old" behavior of blaming
                    848:                 * the receiver ("next hop") is a bad idea (it could be just
                    849:                 * an other server only routing the message!), so the only
                    850:                 * option left is to shorten the string and to hope that the
                    851:                 * result is still somewhat useful ...
                    852:                 *
                    853:                 * Note:
                    854:                 * C99 states that vsnprintf() "returns the number of characters
                    855:                 * that would have been printed if the n were unlimited"; but
                    856:                 * according to the Linux manual page "glibc until 2.0.6 would
                    857:                 * return -1 when the output was truncated" -- so we have to
                    858:                 * handle both cases ...
                    859:                 *                                                   -alex-
                    860:                 */
                    861:
                    862:                strcpy (buffer + sizeof(buffer) - strlen(CUT_TXTSUFFIX) - 2 - 1,
                    863:                        CUT_TXTSUFFIX);
                    864:        }
                    865:
                    866: #ifdef ICONV
                    867:        ptr = strchr(buffer + 1, ':');
                    868:        if (ptr) {
                    869:                ptr++;
                    870:                message = Conn_EncodingTo(Idx, ptr);
                    871:                if (message != ptr)
                    872:                        strlcpy(ptr, message, sizeof(buffer) - (ptr - buffer));
                    873:        }
                    874: #endif
                    875:
                    876: #ifdef SNIFFER
                    877:        if (NGIRCd_Sniffer)
                    878:                Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
                    879: #endif
                    880:
                    881:        len = strlcat( buffer, "\r\n", sizeof( buffer ));
                    882:        ok = Conn_Write(Idx, buffer, len);
                    883:        My_Connections[Idx].msg_out++;
                    884:
                    885:        va_end( ap );
                    886:        return ok;
                    887: } /* Conn_WriteStr */
                    888:
                    889: GLOBAL char*
                    890: Conn_Password( CONN_ID Idx )
                    891: {
                    892:        assert( Idx > NONE );
                    893:        if (My_Connections[Idx].pwd == NULL)
                    894:                return (char*)"\0";
                    895:        else
                    896:                return My_Connections[Idx].pwd;
                    897: } /* Conn_Password */
                    898:
                    899: GLOBAL void
                    900: Conn_SetPassword( CONN_ID Idx, const char *Pwd )
                    901: {
                    902:        assert( Idx > NONE );
                    903:
                    904:        if (My_Connections[Idx].pwd)
                    905:                free(My_Connections[Idx].pwd);
                    906:
                    907:        My_Connections[Idx].pwd = strdup(Pwd);
                    908:        if (My_Connections[Idx].pwd == NULL) {
                    909:                Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
                    910:                exit(1);
                    911:        }
                    912: } /* Conn_SetPassword */
                    913:
                    914: /**
                    915:  * Append Data to the outbound write buffer of a connection.
                    916:  *
                    917:  * @param Idx  Index of the connection.
                    918:  * @param Data pointer to the data.
                    919:  * @param Len  length of Data.
                    920:  * @returns    true on success, false otherwise.
                    921:  */
                    922: static bool
                    923: Conn_Write( CONN_ID Idx, char *Data, size_t Len )
                    924: {
                    925:        CLIENT *c;
                    926:        size_t writebuf_limit = WRITEBUFFER_MAX_LEN;
                    927:        assert( Idx > NONE );
                    928:        assert( Data != NULL );
                    929:        assert( Len > 0 );
                    930:
                    931:        /* Is the socket still open? A previous call to Conn_Write()
                    932:         * may have closed the connection due to a fatal error.
                    933:         * In this case it is sufficient to return an error, as well. */
                    934:        if (My_Connections[Idx].sock <= NONE) {
                    935:                LogDebug("Skipped write on closed socket (connection %d).", Idx);
                    936:                return false;
                    937:        }
                    938:
                    939:        /* Make sure that there still exists a CLIENT structure associated
                    940:         * with this connection and check if this is a server or not: */
                    941:        c = Conn_GetClient(Idx);
                    942:        if (c) {
                    943:                /* Servers do get special write buffer limits, so they can
                    944:                 * generate all the messages that are required while peering. */
                    945:                if (Client_Type(c) == CLIENT_SERVER)
                    946:                        writebuf_limit = WRITEBUFFER_SLINK_LEN;
                    947:        } else
                    948:                LogDebug("Write on socket without client (connection %d)!?", Idx);
                    949:
                    950: #ifdef ZLIB
                    951:        if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
                    952:                /* Compressed link:
                    953:                 * Zip_Buffer() does all the dirty work for us: it flushes
                    954:                 * the (pre-)compression buffers if required and handles
                    955:                 * all error conditions. */
                    956:                if (!Zip_Buffer(Idx, Data, Len))
                    957:                        return false;
                    958:        }
                    959:        else
                    960: #endif
                    961:        {
                    962:                /* Uncompressed link:
                    963:                 * Check if outbound buffer has enough space for the data. */
                    964:                if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
                    965:                    WRITEBUFFER_FLUSH_LEN) {
                    966:                        /* Buffer is full, flush it. Handle_Write deals with
                    967:                         * low-level errors, if any. */
                    968:                        if (!Handle_Write(Idx))
                    969:                                return false;
                    970:                }
                    971:
                    972:                /* When the write buffer is still too big after flushing it,
                    973:                 * the connection will be killed. */
                    974:                if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
                    975:                    writebuf_limit) {
                    976:                        Log(LOG_NOTICE,
                    977:                            "Write buffer space exhausted (connection %d, limit is %lu bytes, %lu bytes new, %lu bytes pending)",
                    978:                            Idx, writebuf_limit, Len,
                    979:                            (unsigned long)array_bytes(&My_Connections[Idx].wbuf));
                    980:                        Conn_Close(Idx, "Write buffer space exhausted", NULL, false);
                    981:                        return false;
                    982:                }
                    983:
                    984:                /* Copy data to write buffer */
                    985:                if (!array_catb(&My_Connections[Idx].wbuf, Data, Len))
                    986:                        return false;
                    987:
                    988:                My_Connections[Idx].bytes_out += Len;
                    989:        }
                    990:
                    991:        /* Adjust global write counter */
                    992:        WCounter += Len;
                    993:
                    994:        return true;
                    995: } /* Conn_Write */
                    996:
                    997: /**
                    998:  * Shut down a connection.
                    999:  *
                   1000:  * @param Idx          Connection index.
                   1001:  * @param LogMsg       Message to write to the log or NULL. If no LogMsg
                   1002:  *                     is given, the FwdMsg is logged.
                   1003:  * @param FwdMsg       Message to forward to remote servers.
                   1004:  * @param InformClient If true, inform the client on the connection which is
                   1005:  *                     to be shut down of the reason (FwdMsg) and send
                   1006:  *                     connection statistics before disconnecting it.
                   1007:  */
                   1008: GLOBAL void
                   1009: Conn_Close(CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient)
                   1010: {
                   1011:        /* Close connection. Open pipes of asynchronous resolver
                   1012:         * sub-processes are closed down. */
                   1013:
                   1014:        CLIENT *c;
                   1015:        double in_k, out_k;
                   1016:        UINT16 port;
                   1017: #ifdef ZLIB
                   1018:        double in_z_k, out_z_k;
                   1019:        int in_p, out_p;
                   1020: #endif
                   1021:
                   1022:        assert( Idx > NONE );
                   1023:
                   1024:        /* Is this link already shutting down? */
                   1025:        if( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ISCLOSING )) {
                   1026:                /* Conn_Close() has been called recursively for this link;
                   1027:                 * probable reason: Handle_Write() failed -- see below. */
                   1028:                LogDebug("Recursive request to close connection %d!", Idx );
                   1029:                return;
                   1030:        }
                   1031:
                   1032:        assert( My_Connections[Idx].sock > NONE );
                   1033:
                   1034:        /* Mark link as "closing" */
                   1035:        Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
                   1036:
                   1037:        port = ng_ipaddr_getport(&My_Connections[Idx].addr);
                   1038:        Log(LOG_INFO, "Shutting down connection %d (%s) with \"%s:%d\" ...", Idx,
                   1039:            LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, port);
                   1040:
                   1041:        /* Search client, if any */
                   1042:        c = Conn_GetClient( Idx );
                   1043:
                   1044:        /* Should the client be informed? */
                   1045:        if (InformClient) {
                   1046: #ifndef STRICT_RFC
                   1047:                /* Send statistics to client if registered as user: */
                   1048:                if ((c != NULL) && (Client_Type(c) == CLIENT_USER)) {
                   1049:                        Conn_WriteStr( Idx,
                   1050:                         ":%s NOTICE %s :%sConnection statistics: client %.1f kb, server %.1f kb.",
                   1051:                         Client_ID(Client_ThisServer()), Client_ID(c),
                   1052:                         NOTICE_TXTPREFIX,
                   1053:                         (double)My_Connections[Idx].bytes_in / 1024,
                   1054:                         (double)My_Connections[Idx].bytes_out / 1024);
                   1055:                }
                   1056: #endif
                   1057:                /* Send ERROR to client (see RFC 2812, section 3.1.7) */
                   1058:                if (FwdMsg)
                   1059:                        Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
                   1060:                else
                   1061:                        Conn_WriteStr(Idx, "ERROR :Closing connection");
                   1062:        }
                   1063:
                   1064:        /* Try to write out the write buffer. Note: Handle_Write() eventually
                   1065:         * removes the CLIENT structure associated with this connection if an
                   1066:         * error occurs! So we have to re-check if there is still an valid
                   1067:         * CLIENT structure after calling Handle_Write() ...*/
                   1068:        (void)Handle_Write( Idx );
                   1069:
                   1070:        /* Search client, if any (re-check!) */
                   1071:        c = Conn_GetClient( Idx );
                   1072: #ifdef SSL_SUPPORT
                   1073:        if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
                   1074:                LogDebug("SSL connection %d shutting down ...", Idx);
                   1075:                ConnSSL_Free(&My_Connections[Idx]);
                   1076:        }
                   1077: #endif
                   1078:        /* Shut down socket */
                   1079:        if (! io_close(My_Connections[Idx].sock)) {
                   1080:                /* Oops, we can't close the socket!? This is ... ugly! */
                   1081:                Log(LOG_CRIT,
                   1082:                    "Error closing connection %d (socket %d) with %s:%d - %s! (ignored)",
                   1083:                    Idx, My_Connections[Idx].sock, My_Connections[Idx].host,
                   1084:                    port, strerror(errno));
                   1085:        }
                   1086:
                   1087:        /* Mark socket as invalid: */
                   1088:        My_Connections[Idx].sock = NONE;
                   1089:
                   1090:        /* If there is still a client, unregister it now */
                   1091:        if (c)
                   1092:                Client_Destroy(c, LogMsg, FwdMsg, true);
                   1093:
                   1094:        /* Calculate statistics and log information */
                   1095:        in_k = (double)My_Connections[Idx].bytes_in / 1024;
                   1096:        out_k = (double)My_Connections[Idx].bytes_out / 1024;
                   1097: #ifdef ZLIB
                   1098:        if (Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP)) {
                   1099:                in_z_k = (double)My_Connections[Idx].zip.bytes_in / 1024;
                   1100:                out_z_k = (double)My_Connections[Idx].zip.bytes_out / 1024;
                   1101:                /* Make sure that no division by zero can occur during
                   1102:                 * the calculation of in_p and out_p: in_z_k and out_z_k
                   1103:                 * are non-zero, that's guaranteed by the protocol until
                   1104:                 * compression can be enabled. */
                   1105:                if (in_z_k <= 0)
                   1106:                        in_z_k = in_k;
                   1107:                if (out_z_k <= 0)
                   1108:                        out_z_k = out_k;
                   1109:                in_p = (int)(( in_k * 100 ) / in_z_k );
                   1110:                out_p = (int)(( out_k * 100 ) / out_z_k );
                   1111:                Log(LOG_INFO,
                   1112:                    "Connection %d with \"%s:%d\" closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).",
                   1113:                    Idx, My_Connections[Idx].host, port,
                   1114:                    in_k, in_z_k, in_p, out_k, out_z_k, out_p);
                   1115:        }
                   1116:        else
                   1117: #endif
                   1118:        {
                   1119:                Log(LOG_INFO,
                   1120:                    "Connection %d with \"%s:%d\" closed (in: %.1fk, out: %.1fk).",
                   1121:                    Idx, My_Connections[Idx].host, port,
                   1122:                    in_k, out_k);
                   1123:        }
                   1124:
                   1125:        /* Servers: Modify time of next connect attempt? */
                   1126:        Conf_UnsetServer( Idx );
                   1127:
                   1128: #ifdef ZLIB
                   1129:        /* Clean up zlib, if link was compressed */
                   1130:        if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
                   1131:                inflateEnd( &My_Connections[Idx].zip.in );
                   1132:                deflateEnd( &My_Connections[Idx].zip.out );
                   1133:                array_free(&My_Connections[Idx].zip.rbuf);
                   1134:                array_free(&My_Connections[Idx].zip.wbuf);
                   1135:        }
                   1136: #endif
                   1137:
                   1138:        array_free(&My_Connections[Idx].rbuf);
                   1139:        array_free(&My_Connections[Idx].wbuf);
                   1140:        if (My_Connections[Idx].pwd != NULL)
                   1141:                free(My_Connections[Idx].pwd);
                   1142:
                   1143:        /* Clean up connection structure (=free it) */
                   1144:        Init_Conn_Struct( Idx );
                   1145:
                   1146:        assert(NumConnections > 0);
                   1147:        if (NumConnections)
                   1148:                NumConnections--;
                   1149:        LogDebug("Shutdown of connection %d completed, %ld connection%s left.",
                   1150:                 Idx, NumConnections, NumConnections != 1 ? "s" : "");
                   1151:
                   1152:        idle_t = NumConnections > 0 ? 0 : time(NULL);
                   1153: } /* Conn_Close */
                   1154:
                   1155: /**
                   1156:  * Get current number of connections.
                   1157:  *
                   1158:  * @returns    Number of current connections.
                   1159:  */
                   1160: GLOBAL long
                   1161: Conn_Count(void)
                   1162: {
                   1163:        return NumConnections;
                   1164: } /* Conn_Count */
                   1165:
                   1166: /**
                   1167:  * Get number of maximum simultaneous connections.
                   1168:  *
                   1169:  * @returns    Number of maximum simultaneous connections.
                   1170:  */
                   1171: GLOBAL long
                   1172: Conn_CountMax(void)
                   1173: {
                   1174:        return NumConnectionsMax;
                   1175: } /* Conn_CountMax */
                   1176:
                   1177: /**
                   1178:  * Get number of connections accepted since the daemon startet.
                   1179:  *
                   1180:  * @returns    Number of connections accepted.
                   1181:  */
                   1182: GLOBAL long
                   1183: Conn_CountAccepted(void)
                   1184: {
                   1185:        return NumConnectionsAccepted;
                   1186: } /* Conn_CountAccepted */
                   1187:
                   1188: /**
                   1189:  * Synchronize established connections and configured server structures
                   1190:  * after a configuration update and store the correct connection IDs, if any.
                   1191:  */
                   1192: GLOBAL void
                   1193: Conn_SyncServerStruct(void)
                   1194: {
                   1195:        CLIENT *client;
                   1196:        CONN_ID i;
                   1197:        int c;
                   1198:
                   1199:        for (i = 0; i < Pool_Size; i++) {
                   1200:                if (My_Connections[i].sock == NONE)
                   1201:                        continue;
                   1202:
                   1203:                /* Server link? */
                   1204:                client = Conn_GetClient(i);
                   1205:                if (!client || Client_Type(client) != CLIENT_SERVER)
                   1206:                        continue;
                   1207:
                   1208:                for (c = 0; c < MAX_SERVERS; c++) {
                   1209:                        /* Configured server? */
                   1210:                        if (!Conf_Server[c].host[0])
                   1211:                                continue;
                   1212:
                   1213:                        if (strcasecmp(Conf_Server[c].name, Client_ID(client)) == 0)
                   1214:                                Conf_Server[c].conn_id = i;
                   1215:                }
                   1216:        }
                   1217: } /* SyncServerStruct */
                   1218:
                   1219: /**
                   1220:  * Get IP address string of a connection.
                   1221:  *
                   1222:  * @param Idx Connection index.
                   1223:  * @return Pointer to a global buffer containing the IP address as string.
                   1224:  */
                   1225: GLOBAL const char *
                   1226: Conn_GetIPAInfo(CONN_ID Idx)
                   1227: {
                   1228:        assert(Idx > NONE);
                   1229:        return ng_ipaddr_tostr(&My_Connections[Idx].addr);
                   1230: }
                   1231:
                   1232: /**
                   1233:  * Send out data of write buffer; connect new sockets.
                   1234:  *
                   1235:  * @param Idx  Connection index.
                   1236:  * @returns    true on success, false otherwise.
                   1237:  */
                   1238: static bool
                   1239: Handle_Write( CONN_ID Idx )
                   1240: {
                   1241:        ssize_t len;
                   1242:        size_t wdatalen;
                   1243:
                   1244:        assert( Idx > NONE );
                   1245:        if ( My_Connections[Idx].sock < 0 ) {
                   1246:                LogDebug("Handle_Write() on closed socket, connection %d", Idx);
                   1247:                return false;
                   1248:        }
                   1249:        assert( My_Connections[Idx].sock > NONE );
                   1250:
                   1251:        wdatalen = array_bytes(&My_Connections[Idx].wbuf );
                   1252:
                   1253: #ifdef ZLIB
                   1254:        if (wdatalen == 0) {
                   1255:                /* Write buffer is empty, so we try to flush the compression
                   1256:                 * buffer and get some data to work with from there :-) */
                   1257:                if (!Zip_Flush(Idx))
                   1258:                        return false;
                   1259:
                   1260:                /* Now the write buffer most probably has changed: */
                   1261:                wdatalen = array_bytes(&My_Connections[Idx].wbuf);
                   1262:        }
                   1263: #endif
                   1264:
                   1265:        if (wdatalen == 0) {
                   1266:                /* Still no data, fine. */
                   1267:                io_event_del(My_Connections[Idx].sock, IO_WANTWRITE );
                   1268:                return true;
                   1269:        }
                   1270:
                   1271: #if DEBUG_BUFFER
                   1272:        LogDebug
                   1273:            ("Handle_Write() called for connection %d, %ld bytes pending ...",
                   1274:             Idx, wdatalen);
                   1275: #endif
                   1276:
                   1277: #ifdef SSL_SUPPORT
                   1278:        if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
                   1279:                len = ConnSSL_Write(&My_Connections[Idx],
                   1280:                                    array_start(&My_Connections[Idx].wbuf),
                   1281:                                    wdatalen);
                   1282:        } else
                   1283: #endif
                   1284:        {
                   1285:                len = write(My_Connections[Idx].sock,
                   1286:                            array_start(&My_Connections[Idx].wbuf), wdatalen );
                   1287:        }
                   1288:        if( len < 0 ) {
                   1289:                if (errno == EAGAIN || errno == EINTR)
                   1290:                        return true;
                   1291:
                   1292:                /* Log write errors but do not close the connection yet.
                   1293:                 * Calling Conn_Close() now could result in too many recursive calls.
                   1294:                 */
                   1295:                if (!Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ISCLOSING))
                   1296:                        Log(LOG_ERR,
                   1297:                            "Write error on connection %d (socket %d): %s!",
                   1298:                            Idx, My_Connections[Idx].sock, strerror(errno));
                   1299:                else
                   1300:                        LogDebug("Recursive write error on connection %d (socket %d): %s!",
                   1301:                                 Idx, My_Connections[Idx].sock, strerror(errno));
                   1302:
                   1303:                return false;
                   1304:        }
                   1305:
                   1306:        /* move any data not yet written to beginning */
                   1307:        array_moveleft(&My_Connections[Idx].wbuf, 1, (size_t)len);
                   1308:
                   1309:        return true;
                   1310: } /* Handle_Write */
                   1311:
                   1312: /**
                   1313:  * Count established connections to a specific IP address.
                   1314:  *
                   1315:  * @returns    Number of established connections.
                   1316:  */
                   1317: static int
                   1318: Count_Connections(ng_ipaddr_t *a)
                   1319: {
                   1320:        int i, cnt;
                   1321:
                   1322:        cnt = 0;
                   1323:        for (i = 0; i < Pool_Size; i++) {
                   1324:                if (My_Connections[i].sock <= NONE)
                   1325:                        continue;
                   1326:                if (ng_ipaddr_ipequal(&My_Connections[i].addr, a))
                   1327:                        cnt++;
                   1328:        }
                   1329:        return cnt;
                   1330: } /* Count_Connections */
                   1331:
                   1332: /**
                   1333:  * Initialize new client connection on a listening socket.
                   1334:  *
                   1335:  * @param Sock Listening socket descriptor.
                   1336:  * @param IsSSL        true if this socket expects SSL-encrypted data.
                   1337:  * @returns    Accepted socket descriptor or -1 on error.
                   1338:  */
                   1339: static int
                   1340: New_Connection(int Sock, UNUSED bool IsSSL)
                   1341: {
                   1342: #ifdef TCPWRAP
                   1343:        struct request_info req;
                   1344: #endif
                   1345:        ng_ipaddr_t new_addr;
                   1346:        char ip_str[NG_INET_ADDRSTRLEN];
                   1347:        int new_sock, new_sock_len;
                   1348:        CLIENT *c;
                   1349:        long cnt;
                   1350:
                   1351:        assert(Sock > NONE);
                   1352:
                   1353:        LogDebug("Accepting new connection on socket %d ...", Sock);
                   1354:
                   1355:        new_sock_len = (int)sizeof(new_addr);
                   1356:        new_sock = accept(Sock, (struct sockaddr *)&new_addr,
                   1357:                          (socklen_t *)&new_sock_len);
                   1358:        if (new_sock < 0) {
                   1359:                Log(LOG_CRIT, "Can't accept connection: %s!", strerror(errno));
                   1360:                return -1;
                   1361:        }
                   1362:        NumConnectionsAccepted++;
                   1363:
                   1364:        if (!ng_ipaddr_tostr_r(&new_addr, ip_str)) {
                   1365:                Log(LOG_CRIT, "fd %d: Can't convert IP address!", new_sock);
                   1366:                Simple_Message(new_sock, "ERROR :Internal Server Error");
                   1367:                close(new_sock);
                   1368:                return -1;
                   1369:        }
                   1370:
                   1371: #ifdef TCPWRAP
                   1372:        /* Validate socket using TCP Wrappers */
                   1373:        request_init(&req, RQ_DAEMON, PACKAGE_NAME, RQ_FILE, new_sock,
                   1374:                     RQ_CLIENT_SIN, &new_addr, NULL);
                   1375:        fromhost(&req);
                   1376:        if (!hosts_access(&req)) {
                   1377:                Log(deny_severity,
                   1378:                    "Refused connection from %s (by TCP Wrappers)!", ip_str);
                   1379:                Simple_Message(new_sock, "ERROR :Connection refused");
                   1380:                close(new_sock);
                   1381:                return -1;
                   1382:        }
                   1383: #endif
                   1384:
                   1385:        if (!Init_Socket(new_sock))
                   1386:                return -1;
                   1387:
                   1388:        /* Check global connection limit */
                   1389:        if ((Conf_MaxConnections > 0) &&
                   1390:            (NumConnections >= (size_t) Conf_MaxConnections)) {
                   1391:                Log(LOG_ALERT, "Can't accept new connection on socket %d: Limit (%d) reached!",
                   1392:                    Sock, Conf_MaxConnections);
                   1393:                Simple_Message(new_sock, "ERROR :Connection limit reached");
                   1394:                close(new_sock);
                   1395:                return -1;
                   1396:        }
                   1397:
                   1398:        /* Check IP-based connection limit */
                   1399:        cnt = Count_Connections(&new_addr);
                   1400:        if ((Conf_MaxConnectionsIP > 0) && (cnt >= Conf_MaxConnectionsIP)) {
                   1401:                /* Access denied, too many connections from this IP address! */
                   1402:                Log(LOG_ERR,
                   1403:                    "Refused connection from %s: too may connections (%ld) from this IP address!",
                   1404:                    ip_str, cnt);
                   1405:                Simple_Message(new_sock,
                   1406:                               "ERROR :Connection refused, too many connections from your IP address");
                   1407:                close(new_sock);
                   1408:                return -1;
                   1409:        }
                   1410:
                   1411:        if (Socket2Index(new_sock) <= NONE) {
                   1412:                Simple_Message(new_sock, "ERROR: Internal error");
                   1413:                close(new_sock);
                   1414:                return -1;
                   1415:        }
                   1416:
                   1417:        /* register callback */
                   1418:        if (!io_event_create(new_sock, IO_WANTREAD, cb_clientserver)) {
                   1419:                Log(LOG_ALERT,
                   1420:                    "Can't accept connection: io_event_create failed!");
                   1421:                Simple_Message(new_sock, "ERROR :Internal error");
                   1422:                close(new_sock);
                   1423:                return -1;
                   1424:        }
                   1425:
                   1426:        c = Client_NewLocal(new_sock, NULL, CLIENT_UNKNOWN, false);
                   1427:        if (!c) {
                   1428:                Log(LOG_ALERT,
                   1429:                    "Can't accept connection: can't create client structure!");
                   1430:                Simple_Message(new_sock, "ERROR :Internal error");
                   1431:                io_close(new_sock);
                   1432:                return -1;
                   1433:        }
                   1434:
                   1435:        Init_Conn_Struct(new_sock);
                   1436:        My_Connections[new_sock].sock = new_sock;
                   1437:        My_Connections[new_sock].addr = new_addr;
                   1438:        My_Connections[new_sock].client = c;
                   1439:
                   1440:        /* Set initial hostname to IP address. This becomes overwritten when
                   1441:         * the DNS lookup is enabled and succeeds, but is used otherwise. */
                   1442:        if (ng_ipaddr_af(&new_addr) != AF_INET)
                   1443:                snprintf(My_Connections[new_sock].host,
                   1444:                         sizeof(My_Connections[new_sock].host), "[%s]", ip_str);
                   1445:        else
                   1446:                strlcpy(My_Connections[new_sock].host, ip_str,
                   1447:                        sizeof(My_Connections[new_sock].host));
                   1448:
                   1449:        Client_SetHostname(c, My_Connections[new_sock].host);
                   1450:
                   1451:        Log(LOG_INFO, "Accepted connection %d from \"%s:%d\" on socket %d.",
                   1452:            new_sock, My_Connections[new_sock].host,
                   1453:            ng_ipaddr_getport(&new_addr), Sock);
                   1454:        Account_Connection();
                   1455:
                   1456: #ifdef SSL_SUPPORT
                   1457:        /* Delay connection initalization until SSL handshake is finished */
                   1458:        if (!IsSSL)
                   1459: #endif
                   1460:                Conn_StartLogin(new_sock);
                   1461:
                   1462:        return new_sock;
                   1463: } /* New_Connection */
                   1464:
                   1465: /**
                   1466:  * Finish connection initialization, start resolver subprocess.
                   1467:  *
                   1468:  * @param Idx Connection index.
                   1469:  */
                   1470: GLOBAL void
                   1471: Conn_StartLogin(CONN_ID Idx)
                   1472: {
                   1473:        int ident_sock = -1;
                   1474:
                   1475:        assert(Idx >= 0);
                   1476:
                   1477:        /* Nothing to do if DNS (and resolver subprocess) is disabled */
                   1478:        if (!Conf_DNS)
                   1479:                return;
                   1480:
                   1481: #ifdef IDENTAUTH
                   1482:        /* Should we make an IDENT request? */
                   1483:        if (Conf_Ident)
                   1484:                ident_sock = My_Connections[Idx].sock;
                   1485: #endif
                   1486:
                   1487:        if (Conf_NoticeBeforeRegistration) {
                   1488:                /* Send "NOTICE *" messages to the client */
                   1489: #ifdef IDENTAUTH
                   1490:                if (Conf_Ident)
                   1491:                        (void)Conn_WriteStr(Idx,
                   1492:                                "NOTICE * :*** Looking up your hostname and checking ident");
                   1493:                else
                   1494: #endif
                   1495:                        (void)Conn_WriteStr(Idx,
                   1496:                                "NOTICE * :*** Looking up your hostname");
                   1497:                /* Send buffered data to the client, but break on errors
                   1498:                 * because Handle_Write() would have closed the connection
                   1499:                 * again in this case! */
                   1500:                if (!Handle_Write(Idx))
                   1501:                        return;
                   1502:        }
                   1503:
                   1504:        Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
                   1505:                     ident_sock, cb_Read_Resolver_Result);
                   1506: }
                   1507:
                   1508: /**
                   1509:  * Update global connection counters.
                   1510:  */
                   1511: static void
                   1512: Account_Connection(void)
                   1513: {
                   1514:        NumConnections++;
                   1515:        idle_t = 0;
                   1516:        if (NumConnections > NumConnectionsMax)
                   1517:                NumConnectionsMax = NumConnections;
                   1518:        LogDebug("Total number of connections now %lu (max %lu).",
                   1519:                 NumConnections, NumConnectionsMax);
                   1520: } /* Account_Connection */
                   1521:
                   1522: /**
                   1523:  * Translate socket handle into connection index (for historical reasons, it is
                   1524:  * a 1:1 mapping today) and enlarge the "connection pool" accordingly.
                   1525:  *
                   1526:  * @param Sock Socket handle.
                   1527:  * @returns    Connecion index or NONE when the pool is too small.
                   1528:  */
                   1529: static CONN_ID
                   1530: Socket2Index( int Sock )
                   1531: {
                   1532:        assert(Sock > 0);
                   1533:        assert(Pool_Size >= 0);
                   1534:
                   1535:        if (Sock < Pool_Size)
                   1536:                return Sock;
                   1537:
                   1538:        /* Try to allocate more memory ... */
                   1539:        if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Sock)) {
                   1540:                Log(LOG_EMERG,
                   1541:                    "Can't allocate memory to enlarge connection pool!");
                   1542:                return NONE;
                   1543:        }
                   1544:        LogDebug("Enlarged connection pool for %ld sockets (%ld items, %ld bytes)",
                   1545:                 Sock, array_length(&My_ConnArray, sizeof(CONNECTION)),
                   1546:                 array_bytes(&My_ConnArray));
                   1547:
                   1548:        /* Adjust pointer to new block, update size and initialize new items. */
                   1549:        My_Connections = array_start(&My_ConnArray);
                   1550:        while (Pool_Size <= Sock)
                   1551:                Init_Conn_Struct(Pool_Size++);
                   1552:
                   1553:        return Sock;
                   1554: }
                   1555:
                   1556: /**
                   1557:  * Read data from the network to the read buffer. If an error occurs,
                   1558:  * the socket of this connection will be shut down.
                   1559:  *
                   1560:  * @param Idx  Connection index.
                   1561:  */
                   1562: static void
                   1563: Read_Request(CONN_ID Idx)
                   1564: {
                   1565:        ssize_t len;
                   1566:        static const unsigned int maxbps = COMMAND_LEN / 2;
                   1567:        char readbuf[READBUFFER_LEN];
                   1568:        time_t t;
                   1569:        CLIENT *c;
                   1570:
                   1571:        assert(Idx > NONE);
                   1572:        assert(My_Connections[Idx].sock > NONE);
                   1573:
                   1574:        /* Check if the read buffer is "full". Basically this shouldn't happen
                   1575:         * here, because as long as there possibly are commands in the read
                   1576:         * buffer (buffer usage > COMMAND_LEN), the socket shouldn't be
                   1577:         * scheduled for reading in Conn_Handler() at all ... */
                   1578: #ifdef ZLIB
                   1579:        if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) ||
                   1580:                (array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN))
                   1581: #else
                   1582:        if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN)
                   1583: #endif
                   1584:        {
                   1585:                Log(LOG_ERR,
                   1586:                    "Receive buffer space exhausted (connection %d): %d/%d bytes",
                   1587:                    Idx, array_bytes(&My_Connections[Idx].rbuf), READBUFFER_LEN);
                   1588:                Conn_Close(Idx, "Receive buffer space exhausted", NULL, false);
                   1589:                return;
                   1590:        }
                   1591:
                   1592:        /* Now read new data from the network, up to READBUFFER_LEN bytes ... */
                   1593: #ifdef SSL_SUPPORT
                   1594:        if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL))
                   1595:                len = ConnSSL_Read(&My_Connections[Idx], readbuf, sizeof(readbuf));
                   1596:        else
                   1597: #endif
                   1598:                len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
                   1599:
                   1600:        if (len == 0) {
                   1601:                LogDebug("Client \"%s:%u\" is closing connection %d ...",
                   1602:                         My_Connections[Idx].host,
                   1603:                         ng_ipaddr_getport(&My_Connections[Idx].addr), Idx);
                   1604:                Conn_Close(Idx, NULL, "Client closed connection", false);
                   1605:                return;
                   1606:        }
                   1607:
                   1608:        if (len < 0) {
                   1609:                if (errno == EAGAIN)
                   1610:                        return;
                   1611:
                   1612:                Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
                   1613:                    Idx, My_Connections[Idx].sock, strerror(errno));
                   1614:                Conn_Close(Idx, "Read error", "Client closed connection",
                   1615:                           false);
                   1616:                return;
                   1617:        }
                   1618:
                   1619:        /* Now append the newly received data to the connection buffer.
                   1620:         * NOTE: This can lead to connection read buffers being bigger(!) than
                   1621:         * READBUFFER_LEN bytes, as we add up to READBUFFER_LEN new bytes to a
                   1622:         * buffer possibly being "almost" READBUFFER_LEN bytes already! */
                   1623: #ifdef ZLIB
                   1624:        if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
                   1625:                if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf,
                   1626:                                (size_t) len)) {
                   1627:                        Log(LOG_ERR,
                   1628:                            "Could not append received data to zip input buffer (connection %d): %d bytes!",
                   1629:                            Idx, len);
                   1630:                        Conn_Close(Idx, "Receive buffer space exhausted", NULL,
                   1631:                                   false);
                   1632:                        return;
                   1633:                }
                   1634:        } else
                   1635: #endif
                   1636:        {
                   1637:                if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
                   1638:                        Log(LOG_ERR,
                   1639:                            "Could not append received data to input buffer (connection %d): %d bytes!",
                   1640:                            Idx, len);
                   1641:                        Conn_Close(Idx, "Receive buffer space exhausted", NULL,
                   1642:                                   false );
                   1643:                }
                   1644:        }
                   1645:
                   1646:        /* Update connection statistics */
                   1647:        My_Connections[Idx].bytes_in += len;
                   1648:
                   1649:        /* Handle read buffer */
                   1650:        My_Connections[Idx].bps += Handle_Buffer(Idx);
                   1651:
                   1652:        /* Make sure that there is still a valid client registered */
                   1653:        c = Conn_GetClient(Idx);
                   1654:        if (!c)
                   1655:                return;
                   1656:
                   1657:        /* Update timestamp of last data received if this connection is
                   1658:         * registered as a user, server or service connection. Don't update
                   1659:         * otherwise, so users have at least Conf_PongTimeout seconds time to
                   1660:         * register with the IRC server -- see Check_Connections().
                   1661:         * Update "lastping", too, if time shifted backwards ... */
                   1662:        if (Client_Type(c) == CLIENT_USER
                   1663:            || Client_Type(c) == CLIENT_SERVER
                   1664:            || Client_Type(c) == CLIENT_SERVICE) {
                   1665:                t = time(NULL);
                   1666:                if (My_Connections[Idx].lastdata != t)
                   1667:                        My_Connections[Idx].bps = 0;
                   1668:
                   1669:                My_Connections[Idx].lastdata = t;
                   1670:                if (My_Connections[Idx].lastping > t)
                   1671:                        My_Connections[Idx].lastping = t;
                   1672:        }
                   1673:
                   1674:        /* Look at the data in the (read-) buffer of this connection */
                   1675:        if (My_Connections[Idx].bps >= maxbps)
                   1676:                Throttle_Connection(Idx, c, THROTTLE_BPS, maxbps);
                   1677: } /* Read_Request */
                   1678:
                   1679: /**
                   1680:  * Handle all data in the connection read-buffer.
                   1681:  *
                   1682:  * Data is processed until no complete command is left in the read buffer,
                   1683:  * or MAX_COMMANDS[_SERVER|_SERVICE] commands were processed.
                   1684:  * When a fatal error occurs, the connection is shut down.
                   1685:  *
                   1686:  * @param Idx  Index of the connection.
                   1687:  * @returns    Number of bytes processed.
                   1688:  */
                   1689: static unsigned int
                   1690: Handle_Buffer(CONN_ID Idx)
                   1691: {
                   1692: #ifndef STRICT_RFC
                   1693:        char *ptr1, *ptr2, *first_eol;
                   1694: #endif
                   1695:        char *ptr;
                   1696:        size_t len, delta;
                   1697:        time_t starttime;
                   1698: #ifdef ZLIB
                   1699:        bool old_z;
                   1700: #endif
                   1701:        unsigned int i, maxcmd = MAX_COMMANDS, len_processed = 0;
                   1702:        CLIENT *c;
                   1703:
                   1704:        c = Conn_GetClient(Idx);
                   1705:        starttime = time(NULL);
                   1706:
                   1707:        assert(c != NULL);
                   1708:
                   1709:        /* Servers get special command limits that depend on the user count */
                   1710:        switch (Client_Type(c)) {
                   1711:            case CLIENT_SERVER:
                   1712:                maxcmd = (int)(Client_UserCount() / 5)
                   1713:                       + MAX_COMMANDS_SERVER_MIN;
                   1714:                /* Allow servers to handle even more commands while peering
                   1715:                 * to speed up server login and network synchronization. */
                   1716:                if (Conn_LastPing(Idx) == 0)
                   1717:                        maxcmd *= 5;
                   1718:                break;
                   1719:            case CLIENT_SERVICE:
                   1720:                maxcmd = MAX_COMMANDS_SERVICE;
                   1721:                break;
                   1722:            case CLIENT_USER:
                   1723:                if (Client_HasMode(c, 'F'))
                   1724:                        maxcmd = MAX_COMMANDS_SERVICE;
                   1725:                break;
                   1726:        }
                   1727:
                   1728:        for (i=0; i < maxcmd; i++) {
                   1729:                /* Check penalty */
                   1730:                if (My_Connections[Idx].delaytime > starttime)
                   1731:                        return 0;
                   1732: #ifdef ZLIB
                   1733:                /* Unpack compressed data, if compression is in use */
                   1734:                if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
                   1735:                        /* When unzipping fails, Unzip_Buffer() shuts
                   1736:                         * down the connection itself */
                   1737:                        if (!Unzip_Buffer(Idx))
                   1738:                                return 0;
                   1739:                }
                   1740: #endif
                   1741:
                   1742:                if (0 == array_bytes(&My_Connections[Idx].rbuf))
                   1743:                        break;
                   1744:
                   1745:                /* Make sure that the buffer is NULL terminated */
                   1746:                if (!array_cat0_temporary(&My_Connections[Idx].rbuf)) {
                   1747:                        Conn_Close(Idx, NULL,
                   1748:                                   "Can't allocate memory [Handle_Buffer]",
                   1749:                                   true);
                   1750:                        return 0;
                   1751:                }
                   1752:
                   1753:                /* RFC 2812, section "2.3 Messages", 5th paragraph:
                   1754:                 * "IRC messages are always lines of characters terminated
                   1755:                 * with a CR-LF (Carriage Return - Line Feed) pair [...]". */
                   1756:                delta = 2;
                   1757:                ptr = strstr(array_start(&My_Connections[Idx].rbuf), "\r\n");
                   1758:
                   1759: #ifndef STRICT_RFC
                   1760:                /* Check for non-RFC-compliant request (only CR or LF)?
                   1761:                 * Unfortunately, there are quite a few clients out there
                   1762:                 * that do this -- e. g. mIRC, BitchX, and Trillian :-( */
                   1763:                ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r');
                   1764:                ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n');
                   1765:                if (ptr) {
                   1766:                        /* Check if there is a single CR or LF _before_ the
                   1767:                         * correct CR+LF line terminator:  */
                   1768:                        first_eol = ptr1 < ptr2 ? ptr1 : ptr2;
                   1769:                        if (first_eol < ptr) {
                   1770:                                /* Single CR or LF before CR+LF found */
                   1771:                                ptr = first_eol;
                   1772:                                delta = 1;
                   1773:                        }
                   1774:                } else if (ptr1 || ptr2) {
                   1775:                        /* No CR+LF terminated command found, but single
                   1776:                         * CR or LF found ... */
                   1777:                        if (ptr1 && ptr2)
                   1778:                                ptr = ptr1 < ptr2 ? ptr1 : ptr2;
                   1779:                        else
                   1780:                                ptr = ptr1 ? ptr1 : ptr2;
                   1781:                        delta = 1;
                   1782:                }
                   1783: #endif
                   1784:
                   1785:                if (!ptr)
                   1786:                        break;
                   1787:
                   1788:                /* Complete (=line terminated) request found, handle it! */
                   1789:                *ptr = '\0';
                   1790:
                   1791:                len = ptr - (char *)array_start(&My_Connections[Idx].rbuf) + delta;
                   1792:
                   1793:                if (len > (COMMAND_LEN - 1)) {
                   1794:                        /* Request must not exceed 512 chars (incl. CR+LF!),
                   1795:                         * see RFC 2812. Disconnect Client if this happens. */
                   1796:                        Log(LOG_ERR,
                   1797:                            "Request too long (connection %d): %d bytes (max. %d expected)!",
                   1798:                            Idx, array_bytes(&My_Connections[Idx].rbuf),
                   1799:                            COMMAND_LEN - 1);
                   1800:                        Conn_Close(Idx, NULL, "Request too long", true);
                   1801:                        return 0;
                   1802:                }
                   1803:
                   1804:                len_processed += (unsigned int)len;
                   1805:                if (len <= delta) {
                   1806:                        /* Request is empty (only '\r\n', '\r' or '\n');
                   1807:                         * delta is 2 ('\r\n') or 1 ('\r' or '\n'), see above */
                   1808:                        array_moveleft(&My_Connections[Idx].rbuf, 1, len);
                   1809:                        continue;
                   1810:                }
                   1811: #ifdef ZLIB
                   1812:                /* remember if stream is already compressed */
                   1813:                old_z = My_Connections[Idx].options & CONN_ZIP;
                   1814: #endif
                   1815:
                   1816:                My_Connections[Idx].msg_in++;
                   1817:                if (!Parse_Request
                   1818:                    (Idx, (char *)array_start(&My_Connections[Idx].rbuf)))
                   1819:                        return 0; /* error -> connection has been closed */
                   1820:
                   1821:                array_moveleft(&My_Connections[Idx].rbuf, 1, len);
                   1822: #ifdef ZLIB
                   1823:                if ((!old_z) && (My_Connections[Idx].options & CONN_ZIP) &&
                   1824:                    (array_bytes(&My_Connections[Idx].rbuf) > 0)) {
                   1825:                        /* The last command activated socket compression.
                   1826:                         * Data that was read after that needs to be copied
                   1827:                         * to the unzip buffer for decompression: */
                   1828:                        if (!array_copy
                   1829:                            (&My_Connections[Idx].zip.rbuf,
                   1830:                             &My_Connections[Idx].rbuf)) {
                   1831:                                Conn_Close(Idx, NULL,
                   1832:                                           "Can't allocate memory [Handle_Buffer]",
                   1833:                                           true);
                   1834:                                return 0;
                   1835:                        }
                   1836:
                   1837:                        array_trunc(&My_Connections[Idx].rbuf);
                   1838:                        LogDebug
                   1839:                            ("Moved already received data (%u bytes) to uncompression buffer.",
                   1840:                             array_bytes(&My_Connections[Idx].zip.rbuf));
                   1841:                }
                   1842: #endif
                   1843:        }
                   1844: #if DEBUG_BUFFER
                   1845:        LogDebug("Connection %d: Processed %ld commands (max=%ld), %ld bytes. %ld bytes left in read buffer.",
                   1846:                 Idx, i, maxcmd, len_processed,
                   1847:                 array_bytes(&My_Connections[Idx].rbuf));
                   1848: #endif
                   1849:
                   1850:        /* If data has been processed but there is still data in the read
                   1851:         * buffer, the command limit triggered. Enforce the penalty time: */
                   1852:        if (len_processed && array_bytes(&My_Connections[Idx].rbuf) > 2)
                   1853:                Throttle_Connection(Idx, c, THROTTLE_CMDS, maxcmd);
                   1854:
                   1855:        return len_processed;
                   1856: } /* Handle_Buffer */
                   1857:
                   1858: /**
                   1859:  * Check whether established connections are still alive or not.
                   1860:  * If not, play PING-PONG first; and if that doesn't help either,
                   1861:  * disconnect the respective peer.
                   1862:  */
                   1863: static void
                   1864: Check_Connections(void)
                   1865: {
                   1866:        CLIENT *c;
                   1867:        CONN_ID i;
                   1868:        char msg[64];
                   1869:        time_t time_now;
                   1870:
                   1871:        time_now = time(NULL);
                   1872:
                   1873:        for (i = 0; i < Pool_Size; i++) {
                   1874:                if (My_Connections[i].sock < 0)
                   1875:                        continue;
                   1876:
                   1877:                c = Conn_GetClient(i);
                   1878:                if (c && ((Client_Type(c) == CLIENT_USER)
                   1879:                          || (Client_Type(c) == CLIENT_SERVER)
                   1880:                          || (Client_Type(c) == CLIENT_SERVICE))) {
                   1881:                        /* connected User, Server or Service */
                   1882:                        if (My_Connections[i].lastping >
                   1883:                            My_Connections[i].lastdata) {
                   1884:                                /* We already sent a ping */
                   1885:                                if (My_Connections[i].lastping <
                   1886:                                    time_now - Conf_PongTimeout) {
                   1887:                                        /* Timeout */
                   1888:                                        snprintf(msg, sizeof(msg),
                   1889:                                                 "Ping timeout: %d seconds",
                   1890:                                                 Conf_PongTimeout);
                   1891:                                        LogDebug("Connection %d: %s.", i, msg);
                   1892:                                        Conn_Close(i, NULL, msg, true);
                   1893:                                }
                   1894:                        } else if (My_Connections[i].lastdata <
                   1895:                                   time_now - Conf_PingTimeout) {
                   1896:                                /* We need to send a PING ... */
                   1897:                                LogDebug("Connection %d: sending PING ...", i);
                   1898:                                Conn_UpdatePing(i, time_now);
                   1899:                                Conn_WriteStr(i, "PING :%s",
                   1900:                                              Client_ID(Client_ThisServer()));
                   1901:                        }
                   1902:                } else {
                   1903:                        /* The connection is not fully established yet, so
                   1904:                         * we don't do the PING-PONG game here but instead
                   1905:                         * disconnect the client after "a short time" if it's
                   1906:                         * still not registered. */
                   1907:
                   1908:                        if (My_Connections[i].lastdata <
                   1909:                            time_now - Conf_PongTimeout) {
                   1910:                                LogDebug
                   1911:                                    ("Unregistered connection %d timed out ...",
                   1912:                                     i);
                   1913:                                Conn_Close(i, NULL, "Timeout", false);
                   1914:                        }
                   1915:                }
                   1916:        }
                   1917: } /* Check_Connections */
                   1918:
                   1919: /**
                   1920:  * Check if further server links should be established.
                   1921:  */
                   1922: static void
                   1923: Check_Servers(void)
                   1924: {
                   1925:        int i, n;
                   1926:        time_t time_now;
                   1927:
                   1928:        time_now = time(NULL);
                   1929:
                   1930:        /* Check all configured servers */
                   1931:        for (i = 0; i < MAX_SERVERS; i++) {
                   1932:                if (Conf_Server[i].conn_id != NONE)
                   1933:                        continue;       /* Already establishing or connected */
                   1934:                if (!Conf_Server[i].host[0] || Conf_Server[i].port <= 0)
                   1935:                        continue;       /* No host and/or port configured */
                   1936:                if (Conf_Server[i].flags & CONF_SFLAG_DISABLED)
                   1937:                        continue;       /* Disabled configuration entry */
                   1938:                if (Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry))
                   1939:                        continue;       /* We have to wait a little bit ... */
                   1940:
                   1941:                /* Is there already a connection in this group? */
                   1942:                if (Conf_Server[i].group > NONE) {
                   1943:                        for (n = 0; n < MAX_SERVERS; n++) {
                   1944:                                if (n == i)
                   1945:                                        continue;
                   1946:                                if ((Conf_Server[n].conn_id != NONE) &&
                   1947:                                    (Conf_Server[n].group == Conf_Server[i].group))
                   1948:                                        break;
                   1949:                        }
                   1950:                        if (n < MAX_SERVERS)
                   1951:                                continue;
                   1952:                }
                   1953:
                   1954:                /* Okay, try to connect now */
                   1955:                Log(LOG_NOTICE,
                   1956:                    "Preparing to establish a new server link for \"%s\" ...",
                   1957:                    Conf_Server[i].name);
                   1958:                Conf_Server[i].lasttry = time_now;
                   1959:                Conf_Server[i].conn_id = SERVER_WAIT;
                   1960:                assert(Proc_GetPipeFd(&Conf_Server[i].res_stat) < 0);
                   1961:
                   1962:                /* Start resolver subprocess ... */
                   1963:                if (!Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host,
                   1964:                                  cb_Connect_to_Server))
                   1965:                        Conf_Server[i].conn_id = NONE;
                   1966:        }
                   1967: } /* Check_Servers */
                   1968:
                   1969: /**
                   1970:  * Establish a new outgoing server connection.
                   1971:  *
                   1972:  * @param Server       Configuration index of the server.
                   1973:  * @param dest         Destination IP address to connect to.
                   1974:  */
                   1975: static void
                   1976: New_Server( int Server , ng_ipaddr_t *dest)
                   1977: {
                   1978:        /* Establish new server link */
                   1979:        char ip_str[NG_INET_ADDRSTRLEN];
                   1980:        int af_dest, res, new_sock;
                   1981:        CLIENT *c;
                   1982:
                   1983:        assert( Server > NONE );
                   1984:
                   1985:        /* Make sure that the remote server hasn't re-linked to this server
                   1986:         * asynchronously on its own */
                   1987:        if (Conf_Server[Server].conn_id > NONE) {
                   1988:                Log(LOG_INFO,
                   1989:                        "Connection to \"%s\" meanwhile re-established, aborting preparation.");
                   1990:                return;
                   1991:        }
                   1992:
                   1993:        if (!ng_ipaddr_tostr_r(dest, ip_str)) {
                   1994:                Log(LOG_WARNING, "New_Server: Could not convert IP to string");
                   1995:                Conf_Server[Server].conn_id = NONE;
                   1996:                return;
                   1997:        }
                   1998:
                   1999:        af_dest = ng_ipaddr_af(dest);
                   2000:        new_sock = socket(af_dest, SOCK_STREAM, 0);
                   2001:
                   2002:        Log(LOG_INFO,
                   2003:            "Establishing connection for \"%s\" to \"%s:%d\" (%s), socket %d ...",
                   2004:            Conf_Server[Server].name, Conf_Server[Server].host,
                   2005:            Conf_Server[Server].port, ip_str, new_sock);
                   2006:
                   2007:        if (new_sock < 0) {
                   2008:                Log(LOG_CRIT, "Can't create socket (af %d): %s!",
                   2009:                    af_dest, strerror(errno));
                   2010:                Conf_Server[Server].conn_id = NONE;
                   2011:                return;
                   2012:        }
                   2013:
                   2014:        if (!Init_Socket(new_sock)) {
                   2015:                Conf_Server[Server].conn_id = NONE;
                   2016:                return;
                   2017:        }
                   2018:
                   2019:        /* is a bind address configured? */
                   2020:        res = ng_ipaddr_af(&Conf_Server[Server].bind_addr);
                   2021:
                   2022:        /* if yes, bind now. If it fails, warn and let connect() pick a
                   2023:         * source address */
                   2024:        if (res && bind(new_sock, (struct sockaddr *) &Conf_Server[Server].bind_addr,
                   2025:                                ng_ipaddr_salen(&Conf_Server[Server].bind_addr)))
                   2026:        {
                   2027:                ng_ipaddr_tostr_r(&Conf_Server[Server].bind_addr, ip_str);
                   2028:                Log(LOG_WARNING, "Can't bind socket to %s: %s!", ip_str,
                   2029:                    strerror(errno));
                   2030:        }
                   2031:        ng_ipaddr_setport(dest, Conf_Server[Server].port);
                   2032:        res = connect(new_sock, (struct sockaddr *) dest, ng_ipaddr_salen(dest));
                   2033:        if(( res != 0 ) && ( errno != EINPROGRESS )) {
                   2034:                Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno ));
                   2035:                close( new_sock );
                   2036:                Conf_Server[Server].conn_id = NONE;
                   2037:                return;
                   2038:        }
                   2039:
                   2040:        if (Socket2Index(new_sock) <= NONE) {
                   2041:                close( new_sock );
                   2042:                Conf_Server[Server].conn_id = NONE;
                   2043:                return;
                   2044:        }
                   2045:
                   2046:        if (!io_event_create( new_sock, IO_WANTWRITE, cb_connserver)) {
                   2047:                Log(LOG_ALERT, "io_event_create(): could not add fd %d",
                   2048:                    strerror(errno));
                   2049:                close(new_sock);
                   2050:                Conf_Server[Server].conn_id = NONE;
                   2051:                return;
                   2052:        }
                   2053:
                   2054:        assert(My_Connections[new_sock].sock <= 0);
                   2055:
                   2056:        Init_Conn_Struct(new_sock);
                   2057:
                   2058:        ng_ipaddr_tostr_r(dest, ip_str);
                   2059:        c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWNSERVER, false);
                   2060:        if (!c) {
                   2061:                Log( LOG_ALERT, "Can't establish connection: can't create client structure!" );
                   2062:                io_close(new_sock);
                   2063:                Conf_Server[Server].conn_id = NONE;
                   2064:                return;
                   2065:        }
                   2066:
                   2067:        /* Conn_Close() decrements this counter again */
                   2068:        Account_Connection();
                   2069:        Client_SetIntroducer( c, c );
                   2070:        Client_SetToken( c, TOKEN_OUTBOUND );
                   2071:
                   2072:        /* Register connection */
                   2073:        if (!Conf_SetServer(Server, new_sock))
                   2074:                return;
                   2075:        My_Connections[new_sock].sock = new_sock;
                   2076:        My_Connections[new_sock].addr = *dest;
                   2077:        My_Connections[new_sock].client = c;
                   2078:        strlcpy( My_Connections[new_sock].host, Conf_Server[Server].host,
                   2079:                                sizeof(My_Connections[new_sock].host ));
                   2080:
                   2081: #ifdef SSL_SUPPORT
                   2082:        if (Conf_Server[Server].SSLConnect &&
                   2083:            !ConnSSL_PrepareConnect(&My_Connections[new_sock], &Conf_Server[Server]))
                   2084:        {
                   2085:                Log(LOG_ALERT, "Could not initialize SSL for outgoing connection");
                   2086:                Conn_Close(new_sock, "Could not initialize SSL for outgoing connection",
                   2087:                           NULL, false);
                   2088:                Init_Conn_Struct(new_sock);
                   2089:                Conf_Server[Server].conn_id = NONE;
                   2090:                return;
                   2091:        }
                   2092: #endif
                   2093:        LogDebug("Registered new connection %d on socket %d (%ld in total).",
                   2094:                 new_sock, My_Connections[new_sock].sock, NumConnections);
                   2095:        Conn_OPTION_ADD( &My_Connections[new_sock], CONN_ISCONNECTING );
                   2096: } /* New_Server */
                   2097:
                   2098: /**
                   2099:  * Initialize connection structure.
                   2100:  *
                   2101:  * @param Idx  Connection index.
                   2102:  */
                   2103: static void
                   2104: Init_Conn_Struct(CONN_ID Idx)
                   2105: {
                   2106:        time_t now = time(NULL);
                   2107:
                   2108:        memset(&My_Connections[Idx], 0, sizeof(CONNECTION));
                   2109:        My_Connections[Idx].sock = -1;
                   2110:        My_Connections[Idx].signon = now;
                   2111:        My_Connections[Idx].lastdata = now;
                   2112:        My_Connections[Idx].lastprivmsg = now;
                   2113:        Proc_InitStruct(&My_Connections[Idx].proc_stat);
                   2114:
                   2115: #ifdef ICONV
                   2116:        My_Connections[Idx].iconv_from = (iconv_t)(-1);
                   2117:        My_Connections[Idx].iconv_to = (iconv_t)(-1);
                   2118: #endif
                   2119: } /* Init_Conn_Struct */
                   2120:
                   2121: /**
                   2122:  * Initialize options of a new socket.
                   2123:  *
                   2124:  * For example, we try to set socket options SO_REUSEADDR and IPTOS_LOWDELAY.
                   2125:  * The socket is automatically closed if a fatal error is encountered.
                   2126:  *
                   2127:  * @param Sock Socket handle.
                   2128:  * @returns false if socket was closed due to fatal error.
                   2129:  */
                   2130: static bool
                   2131: Init_Socket( int Sock )
                   2132: {
                   2133:        int value;
                   2134:
                   2135:        if (!io_setnonblock(Sock)) {
                   2136:                Log(LOG_CRIT, "Can't enable non-blocking mode for socket: %s!",
                   2137:                    strerror(errno));
                   2138:                close(Sock);
                   2139:                return false;
                   2140:        }
                   2141:
                   2142:        /* Don't block this port after socket shutdown */
                   2143:        value = 1;
                   2144:        if (setsockopt(Sock, SOL_SOCKET, SO_REUSEADDR, &value,
                   2145:                       (socklen_t)sizeof(value)) != 0) {
                   2146:                Log(LOG_ERR, "Can't set socket option SO_REUSEADDR: %s!",
                   2147:                    strerror(errno));
                   2148:                /* ignore this error */
                   2149:        }
                   2150:
                   2151:        /* Set type of service (TOS) */
                   2152: #if defined(IPPROTO_IP) && defined(IPTOS_LOWDELAY)
                   2153:        value = IPTOS_LOWDELAY;
                   2154:        if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
                   2155:                       (socklen_t) sizeof(value))) {
                   2156:                LogDebug("Can't set socket option IP_TOS: %s!",
                   2157:                         strerror(errno));
                   2158:                /* ignore this error */
                   2159:        } else
                   2160:                LogDebug("IP_TOS on socket %d has been set to IPTOS_LOWDELAY.",
                   2161:                         Sock);
                   2162: #endif
                   2163:
                   2164:        return true;
                   2165: } /* Init_Socket */
                   2166:
                   2167: /**
                   2168:  * Read results of a resolver sub-process and try to initiate a new server
                   2169:  * connection.
                   2170:  *
                   2171:  * @param fd           File descriptor of the pipe to the sub-process.
                   2172:  * @param events       (ignored IO specification)
                   2173:  */
                   2174: static void
                   2175: cb_Connect_to_Server(int fd, UNUSED short events)
                   2176: {
                   2177:        int i;
                   2178:        size_t len;
                   2179:
                   2180:        /* we can handle at most 3 addresses; but we read up to 4 so we can
                   2181:         * log the 'more than we can handle' condition. First result is tried
                   2182:         * immediately, rest is saved for later if needed. */
                   2183:        ng_ipaddr_t dest_addrs[4];
                   2184:
                   2185:        LogDebug("Resolver: Got forward lookup callback on fd %d, events %d",
                   2186:                 fd, events);
                   2187:
                   2188:        for (i=0; i < MAX_SERVERS; i++) {
                   2189:                  if (Proc_GetPipeFd(&Conf_Server[i].res_stat) == fd )
                   2190:                          break;
                   2191:        }
                   2192:
                   2193:        if( i >= MAX_SERVERS) {
                   2194:                /* Ops, no matching server found?! */
                   2195:                io_close( fd );
                   2196:                LogDebug("Resolver: Got Forward Lookup callback for unknown server!?");
                   2197:                return;
                   2198:        }
                   2199:
                   2200:        /* Read result from pipe */
                   2201:        len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
                   2202:        Proc_Close(&Conf_Server[i].res_stat);
                   2203:        if (len == 0) {
                   2204:                /* Error resolving hostname: reset server structure */
                   2205:                Conf_Server[i].conn_id = NONE;
                   2206:                return;
                   2207:        }
                   2208:
                   2209:        assert((len % sizeof(ng_ipaddr_t)) == 0);
                   2210:
                   2211:        LogDebug("Got result from resolver: %u structs (%u bytes).",
                   2212:                 len/sizeof(ng_ipaddr_t), len);
                   2213:
                   2214:        memset(&Conf_Server[i].dst_addr, 0, sizeof(Conf_Server[i].dst_addr));
                   2215:        if (len > sizeof(ng_ipaddr_t)) {
                   2216:                /* more than one address for this hostname, remember them
                   2217:                 * in case first address is unreachable/not available */
                   2218:                len -= sizeof(ng_ipaddr_t);
                   2219:                if (len > sizeof(Conf_Server[i].dst_addr)) {
                   2220:                        len = sizeof(Conf_Server[i].dst_addr);
                   2221:                        Log(LOG_NOTICE,
                   2222:                                "Notice: Resolver returned more IP Addresses for host than we can handle, additional addresses dropped.");
                   2223:                }
                   2224:                memcpy(&Conf_Server[i].dst_addr, &dest_addrs[1], len);
                   2225:        }
                   2226:        /* connect() */
                   2227:        New_Server(i, dest_addrs);
                   2228: } /* cb_Read_Forward_Lookup */
                   2229:
                   2230: /**
                   2231:  * Read results of a resolver sub-process from the pipe and update the
                   2232:  * appropriate connection/client structure(s): hostname and/or IDENT user name.
                   2233:  *
                   2234:  * @param r_fd         File descriptor of the pipe to the sub-process.
                   2235:  * @param events       (ignored IO specification)
                   2236:  */
                   2237: static void
                   2238: cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                   2239: {
                   2240:        CLIENT *c;
                   2241:        CONN_ID i;
                   2242:        size_t len;
                   2243:        char *identptr;
                   2244: #ifdef IDENTAUTH
                   2245:        char readbuf[HOST_LEN + 2 + CLIENT_USER_LEN];
                   2246:        char *ptr;
                   2247: #else
                   2248:        char readbuf[HOST_LEN + 1];
                   2249: #endif
                   2250:
                   2251:        LogDebug("Resolver: Got callback on fd %d, events %d", r_fd, events );
                   2252:        i = Conn_GetFromProc(r_fd);
                   2253:        if (i == NONE) {
                   2254:                /* Ops, none found? Probably the connection has already
                   2255:                 * been closed!? We'll ignore that ... */
                   2256:                io_close( r_fd );
                   2257:                LogDebug("Resolver: Got callback for unknown connection!?");
                   2258:                return;
                   2259:        }
                   2260:
                   2261:        /* Read result from pipe */
                   2262:        len = Proc_Read(&My_Connections[i].proc_stat, readbuf, sizeof readbuf -1);
                   2263:        Proc_Close(&My_Connections[i].proc_stat);
                   2264:        if (len == 0)
                   2265:                return;
                   2266:
                   2267:        readbuf[len] = '\0';
                   2268:        identptr = strchr(readbuf, '\n');
                   2269:        assert(identptr != NULL);
                   2270:        if (!identptr) {
                   2271:                Log( LOG_CRIT, "Resolver: Got malformed result!");
                   2272:                return;
                   2273:        }
                   2274:
                   2275:        *identptr = '\0';
                   2276:        LogDebug("Got result from resolver: \"%s\" (%u bytes read).", readbuf, len);
                   2277:        /* Okay, we got a complete result: this is a host name for outgoing
                   2278:         * connections and a host name and IDENT user name (if enabled) for
                   2279:         * incoming connections.*/
                   2280:        assert ( My_Connections[i].sock >= 0 );
                   2281:        /* Incoming connection. Search client ... */
                   2282:        c = Conn_GetClient( i );
                   2283:        assert( c != NULL );
                   2284:
                   2285:        /* Only update client information of unregistered clients.
                   2286:         * Note: user commands (e. g. WEBIRC) are always read _after_ reading
                   2287:         * the resolver results, so we don't have to worry to override settings
                   2288:         * from these commands here. */
                   2289:        if(Client_Type(c) == CLIENT_UNKNOWN) {
                   2290:                strlcpy(My_Connections[i].host, readbuf,
                   2291:                        sizeof(My_Connections[i].host));
                   2292:                Client_SetHostname(c, readbuf);
                   2293:                if (Conf_NoticeBeforeRegistration)
                   2294:                        (void)Conn_WriteStr(i,
                   2295:                                        "NOTICE * :*** Found your hostname: %s",
                   2296:                                        My_Connections[i].host);
                   2297: #ifdef IDENTAUTH
                   2298:                ++identptr;
                   2299:                if (*identptr) {
                   2300:                        ptr = identptr;
                   2301:                        while (*ptr) {
                   2302:                                if ((*ptr < '0' || *ptr > '9') &&
                   2303:                                    (*ptr < 'A' || *ptr > 'Z') &&
                   2304:                                    (*ptr < 'a' || *ptr > 'z'))
                   2305:                                        break;
                   2306:                                ptr++;
                   2307:                        }
                   2308:                        if (*ptr) {
                   2309:                                /* Erroneous IDENT reply */
                   2310:                                Log(LOG_NOTICE,
                   2311:                                    "Got invalid IDENT reply for connection %d! Ignored.",
                   2312:                                    i);
                   2313:                        } else {
                   2314:                                Log(LOG_INFO,
                   2315:                                    "IDENT lookup for connection %d: \"%s\".",
                   2316:                                    i, identptr);
                   2317:                                Client_SetUser(c, identptr, true);
                   2318:                        }
                   2319:                        if (Conf_NoticeBeforeRegistration) {
                   2320:                                (void)Conn_WriteStr(i,
                   2321:                                        "NOTICE * :*** Got %sident response%s%s",
                   2322:                                        *ptr ? "invalid " : "",
                   2323:                                        *ptr ? "" : ": ",
                   2324:                                        *ptr ? "" : identptr);
                   2325:                        }
                   2326:                } else if(Conf_Ident) {
                   2327:                        Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
                   2328:                        if (Conf_NoticeBeforeRegistration)
                   2329:                                (void)Conn_WriteStr(i,
                   2330:                                        "NOTICE * :*** No ident response");
                   2331:                }
                   2332: #endif
                   2333:
                   2334:                if (Conf_NoticeBeforeRegistration) {
                   2335:                        /* Send buffered data to the client, but break on
                   2336:                         * errors because Handle_Write() would have closed
                   2337:                         * the connection again in this case! */
                   2338:                        if (!Handle_Write(i))
                   2339:                                return;
                   2340:                }
                   2341:
                   2342:                Class_HandleServerBans(c);
                   2343:        }
                   2344: #ifdef DEBUG
                   2345:        else
                   2346:                LogDebug("Resolver: discarding result for already registered connection %d.", i);
                   2347: #endif
                   2348: } /* cb_Read_Resolver_Result */
                   2349:
                   2350: /**
                   2351:  * Write a "simple" (error) message to a socket.
                   2352:  *
                   2353:  * The message is sent without using the connection write buffers, without
                   2354:  * compression/encryption, and even without any error reporting. It is
                   2355:  * designed for error messages of e.g. New_Connection().
                   2356:  *
                   2357:  * @param Sock Socket handle.
                   2358:  * @param Msg  Message string to send.
                   2359:  */
                   2360: static void
                   2361: Simple_Message(int Sock, const char *Msg)
                   2362: {
                   2363:        char buf[COMMAND_LEN];
                   2364:        size_t len;
                   2365:
                   2366:        assert(Sock > NONE);
                   2367:        assert(Msg != NULL);
                   2368:
                   2369:        strlcpy(buf, Msg, sizeof buf - 2);
                   2370:        len = strlcat(buf, "\r\n", sizeof buf);
                   2371:        if (write(Sock, buf, len) < 0) {
                   2372:                /* Because this function most probably got called to log
                   2373:                 * an error message, any write error is ignored here to
                   2374:                 * avoid an endless loop. But casting the result of write()
                   2375:                 * to "void" doesn't satisfy the GNU C code attribute
                   2376:                 * "warn_unused_result" which is used by some versions of
                   2377:                 * glibc (e.g. 2.11.1), therefore this silly error
                   2378:                 * "handling" code here :-( */
                   2379:                return;
                   2380:        }
                   2381: } /* Simple_Error */
                   2382:
                   2383: /**
                   2384:  * Get CLIENT structure that belongs to a local connection identified by its
                   2385:  * index number. Each connection belongs to a client by definition, so it is
                   2386:  * not required that the caller checks for NULL return values.
                   2387:  *
                   2388:  * @param Idx  Connection index number.
                   2389:  * @returns    Pointer to CLIENT structure.
                   2390:  */
                   2391: GLOBAL CLIENT *
                   2392: Conn_GetClient( CONN_ID Idx )
                   2393: {
                   2394:        CONNECTION *c;
                   2395:
                   2396:        assert(Idx >= 0);
                   2397:        c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
                   2398:        assert(c != NULL);
                   2399:        return c ? c->client : NULL;
                   2400: }
                   2401:
                   2402: /**
                   2403:  * Get PROC_STAT sub-process structure of a connection.
                   2404:  *
                   2405:  * @param Idx  Connection index number.
                   2406:  * @returns    PROC_STAT structure.
                   2407:  */
                   2408: GLOBAL PROC_STAT *
                   2409: Conn_GetProcStat(CONN_ID Idx)
                   2410: {
                   2411:        CONNECTION *c;
                   2412:
                   2413:        assert(Idx >= 0);
                   2414:        c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
                   2415:        assert(c != NULL);
                   2416:        return &c->proc_stat;
                   2417: } /* Conn_GetProcStat */
                   2418:
                   2419: /**
                   2420:  * Get CONN_ID from file descriptor associated to a subprocess structure.
                   2421:  *
                   2422:  * @param fd   File descriptor.
                   2423:  * @returns    CONN_ID or NONE (-1).
                   2424:  */
                   2425: GLOBAL CONN_ID
                   2426: Conn_GetFromProc(int fd)
                   2427: {
                   2428:        int i;
                   2429:
                   2430:        assert(fd > 0);
                   2431:        for (i = 0; i < Pool_Size; i++) {
                   2432:                if ((My_Connections[i].sock != NONE)
                   2433:                    && (Proc_GetPipeFd(&My_Connections[i].proc_stat) == fd))
                   2434:                        return i;
                   2435:        }
                   2436:        return NONE;
                   2437: } /* Conn_GetFromProc */
                   2438:
                   2439: /**
                   2440:  * Throttle a connection because of excessive usage.
                   2441:  *
                   2442:  * @param Reason The reason, see THROTTLE_xxx constants.
                   2443:  * @param Idx The connection index.
                   2444:  * @param Client The client of this connection.
                   2445:  * @param Value The time to delay this connection.
                   2446:  */
                   2447: static void
                   2448: Throttle_Connection(const CONN_ID Idx, CLIENT *Client, const int Reason,
                   2449:                    unsigned int Value)
                   2450: {
                   2451:        assert(Idx > NONE);
                   2452:        assert(Client != NULL);
                   2453:
                   2454:        /* Never throttle servers or services, only interrupt processing */
                   2455:        if (Client_Type(Client) == CLIENT_SERVER
                   2456:            || Client_Type(Client) == CLIENT_UNKNOWNSERVER
                   2457:            || Client_Type(Client) == CLIENT_SERVICE)
                   2458:                return;
                   2459:
                   2460:        /* Don't throttle clients with user mode 'F' set */
                   2461:        if (Client_HasMode(Client, 'F'))
                   2462:                return;
                   2463:
                   2464:        LogDebug("Throttling connection %d: code %d, value %d!", Idx,
                   2465:                 Reason, Value);
                   2466:        Conn_SetPenalty(Idx, 1);
                   2467: }
                   2468:
                   2469: #ifndef STRICT_RFC
                   2470:
                   2471: GLOBAL long
                   2472: Conn_GetAuthPing(CONN_ID Idx)
                   2473: {
                   2474:        assert (Idx != NONE);
                   2475:        return My_Connections[Idx].auth_ping;
                   2476: } /* Conn_GetAuthPing */
                   2477:
                   2478: GLOBAL void
                   2479: Conn_SetAuthPing(CONN_ID Idx, long ID)
                   2480: {
                   2481:        assert (Idx != NONE);
                   2482:        My_Connections[Idx].auth_ping = ID;
                   2483: } /* Conn_SetAuthPing */
                   2484:
                   2485: #endif /* STRICT_RFC */
                   2486:
                   2487: #ifdef SSL_SUPPORT
                   2488:
                   2489: /**
                   2490:  * IO callback for new SSL-enabled client and server connections.
                   2491:  *
                   2492:  * @param sock Socket descriptor.
                   2493:  * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...).
                   2494:  */
                   2495: static void
                   2496: cb_clientserver_ssl(int sock, UNUSED short what)
                   2497: {
                   2498:        CONN_ID idx = Socket2Index(sock);
                   2499:
                   2500:        if (idx <= NONE) {
                   2501:                io_close(sock);
                   2502:                return;
                   2503:        }
                   2504:
                   2505:        switch (ConnSSL_Accept(&My_Connections[idx])) {
                   2506:                case 1:
                   2507:                        break;  /* OK */
                   2508:                case 0:
                   2509:                        return; /* EAGAIN: callback will be invoked again by IO layer */
                   2510:                default:
                   2511:                        Conn_Close(idx,
                   2512:                                   "SSL accept error, closing socket", "SSL accept error",
                   2513:                                   false);
                   2514:                        return;
                   2515:        }
                   2516:
                   2517:        io_event_setcb(sock, cb_clientserver);  /* SSL handshake completed */
                   2518: }
                   2519:
                   2520: /**
                   2521:  * IO callback for listening SSL sockets: handle new connections. This callback
                   2522:  * gets called when a new SSL-enabled connection should be accepted.
                   2523:  *
                   2524:  * @param sock         Socket descriptor.
                   2525:  * @param irrelevant   (ignored IO specification)
                   2526:  */
                   2527: static void
                   2528: cb_listen_ssl(int sock, short irrelevant)
                   2529: {
                   2530:        int fd;
                   2531:
                   2532:        (void) irrelevant;
                   2533:        fd = New_Connection(sock, true);
                   2534:        if (fd < 0)
                   2535:                return;
                   2536:        io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
                   2537: }
                   2538:
                   2539: /**
                   2540:  * IO callback for new outgoing SSL-enabled server connections.
                   2541:  *
                   2542:  * @param sock         Socket descriptor.
                   2543:  * @param unused       (ignored IO specification)
                   2544:  */
                   2545: static void
                   2546: cb_connserver_login_ssl(int sock, short unused)
                   2547: {
                   2548:        CONN_ID idx = Socket2Index(sock);
                   2549:
                   2550:        (void) unused;
                   2551:
                   2552:        if (idx <= NONE) {
                   2553:                io_close(sock);
                   2554:                return;
                   2555:        }
                   2556:
                   2557:        switch (ConnSSL_Connect( &My_Connections[idx])) {
                   2558:                case 1: break;
                   2559:                case 0: LogDebug("ConnSSL_Connect: not ready");
                   2560:                        return;
                   2561:                case -1:
                   2562:                        Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
                   2563:                        Conn_Close(idx, "Can't connect", NULL, false);
                   2564:                        return;
                   2565:        }
                   2566:
                   2567:        Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
                   2568:            My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
                   2569:
                   2570:        server_login(idx);
                   2571: }
                   2572:
                   2573:
                   2574: /**
                   2575:  * Check if SSL library needs to read SSL-protocol related data.
                   2576:  *
                   2577:  * SSL/TLS connections require extra treatment:
                   2578:  * When either CONN_SSL_WANT_WRITE or CONN_SSL_WANT_READ is set, we
                   2579:  * need to take care of that first, before checking read/write buffers.
                   2580:  * For instance, while we might have data in our write buffer, the
                   2581:  * TLS/SSL protocol might need to read internal data first for TLS/SSL
                   2582:  * writes to succeed.
                   2583:  *
                   2584:  * If this function returns true, such a condition is met and we have
                   2585:  * to reverse the condition (check for read even if we've data to write,
                   2586:  * do not check for read but writeability even if write-buffer is empty).
                   2587:  *
                   2588:  * @param c    Connection to check.
                   2589:  * @returns    true if SSL-library has to read protocol data.
                   2590:  */
                   2591: static bool
                   2592: SSL_WantRead(const CONNECTION *c)
                   2593: {
                   2594:        if (Conn_OPTION_ISSET(c, CONN_SSL_WANT_READ)) {
                   2595:                io_event_add(c->sock, IO_WANTREAD);
                   2596:                return true;
                   2597:        }
                   2598:        return false;
                   2599: }
                   2600:
                   2601: /**
                   2602:  * Check if SSL library needs to write SSL-protocol related data.
                   2603:  *
                   2604:  * Please see description of SSL_WantRead() for full description!
                   2605:  *
                   2606:  * @param c    Connection to check.
                   2607:  * @returns    true if SSL-library has to write protocol data.
                   2608:  */
                   2609: static bool
                   2610: SSL_WantWrite(const CONNECTION *c)
                   2611: {
                   2612:        if (Conn_OPTION_ISSET(c, CONN_SSL_WANT_WRITE)) {
                   2613:                io_event_add(c->sock, IO_WANTWRITE);
                   2614:                return true;
                   2615:        }
                   2616:        return false;
                   2617: }
                   2618:
                   2619: /**
                   2620:  * Get information about used SSL cipher.
                   2621:  *
                   2622:  * @param Idx  Connection index number.
                   2623:  * @param buf  Buffer for returned information text.
                   2624:  * @param len  Size of return buffer "buf".
                   2625:  * @returns    true on success, false otherwise.
                   2626:  */
                   2627: GLOBAL bool
                   2628: Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len)
                   2629: {
                   2630:        if (Idx < 0)
                   2631:                return false;
                   2632:        assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
                   2633:        return ConnSSL_GetCipherInfo(&My_Connections[Idx], buf, len);
                   2634: }
                   2635:
                   2636: /**
                   2637:  * Check if a connection is SSL-enabled or not.
                   2638:  *
                   2639:  * @param Idx  Connection index number.
                   2640:  * @return     true if connection is SSL-enabled, false otherwise.
                   2641:  */
                   2642: GLOBAL bool
                   2643: Conn_UsesSSL(CONN_ID Idx)
                   2644: {
                   2645:        if (Idx < 0)
                   2646:                return false;
                   2647:        assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
                   2648:        return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);
                   2649: }
                   2650:
                   2651: GLOBAL char *
                   2652: Conn_GetCertFp(CONN_ID Idx)
                   2653: {
                   2654:        if (Idx < 0)
                   2655:                return NULL;
                   2656:        assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
                   2657:        return ConnSSL_GetCertFp(&My_Connections[Idx]);
                   2658: }
                   2659:
                   2660: GLOBAL bool
                   2661: Conn_SetCertFp(CONN_ID Idx, const char *fingerprint)
                   2662: {
                   2663:        if (Idx < 0)
                   2664:                return false;
                   2665:        assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
                   2666:        return ConnSSL_SetCertFp(&My_Connections[Idx], fingerprint);
                   2667: }
                   2668:
                   2669: #else /* SSL_SUPPORT */
                   2670:
                   2671: GLOBAL bool
                   2672: Conn_UsesSSL(UNUSED CONN_ID Idx)
                   2673: {
                   2674:        return false;
                   2675: }
                   2676:
                   2677: GLOBAL char *
                   2678: Conn_GetCertFp(UNUSED CONN_ID Idx)
                   2679: {
                   2680:        return NULL;
                   2681: }
                   2682:
                   2683: GLOBAL bool
                   2684: Conn_SetCertFp(UNUSED CONN_ID Idx, UNUSED const char *fingerprint)
                   2685: {
                   2686:        return true;
                   2687: }
                   2688:
                   2689: #endif /* SSL_SUPPORT */
                   2690:
                   2691: #ifdef DEBUG
                   2692:
                   2693: /**
                   2694:  * Dump internal state of the "connection module".
                   2695:  */
                   2696: GLOBAL void
                   2697: Conn_DebugDump(void)
                   2698: {
                   2699:        int i;
                   2700:
                   2701:        Log(LOG_DEBUG, "Connection status:");
                   2702:        for (i = 0; i < Pool_Size; i++) {
                   2703:                if (My_Connections[i].sock == NONE)
                   2704:                        continue;
                   2705:                Log(LOG_DEBUG,
                   2706:                    " - %d: host=%s, lastdata=%ld, lastping=%ld, delaytime=%ld, flag=%d, options=%d, bps=%d, client=%s",
                   2707:                    My_Connections[i].sock, My_Connections[i].host,
                   2708:                    My_Connections[i].lastdata, My_Connections[i].lastping,
                   2709:                    My_Connections[i].delaytime, My_Connections[i].flag,
                   2710:                    My_Connections[i].options, My_Connections[i].bps,
                   2711:                    My_Connections[i].client ? Client_ID(My_Connections[i].client) : "-");
                   2712:        }
                   2713: } /* Conn_DumpClients */
                   2714:
                   2715: #endif /* DEBUG */
                   2716:
                   2717: /* -eof- */

CVSweb