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