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