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