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