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