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