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