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