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