2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
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.
11 * Connection management
33 #include <sys/socket.h>
35 #include <sys/types.h>
37 #include <netinet/in.h>
39 #ifdef HAVE_NETINET_IP_H
40 # include <netinet/ip.h>
44 # include <stdint.h> /* e.g. for Mac OS X */
48 # include <tcpd.h> /* for TCP Wrappers */
64 #include "conn-func.h"
70 # include "rendezvous.h"
76 #define SERVER_WAIT (NONE - 1)
78 #define MAX_COMMANDS 3
79 #define MAX_COMMANDS_SERVER 10
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 ));
96 static array My_Listeners;
97 static array My_ConnArray;
98 static size_t NumConnections;
101 int allow_severity = LOG_INFO;
102 int deny_severity = LOG_ERR;
105 static void server_login PARAMS((CONN_ID idx));
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));
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));
118 * IO callback for listening sockets: handle new connections. This callback
119 * gets called when a new non-SSL connection should be accepted.
120 * @param sock Socket descriptor
121 * @param irrelevant (ignored IO specification)
124 cb_listen(int sock, short irrelevant)
127 if (New_Connection( sock ) >= 0)
129 LogDebug("Total number of connections now %ld.", NumConnections);
135 * IO callback for listening SSL sockets: handle new connections. This callback
136 * gets called when a new SSL-enabled connection should be accepted.
137 * @param sock Socket descriptor
138 * @param irrelevant (ignored IO specification)
141 cb_listen_ssl(int sock, short irrelevant)
146 fd = New_Connection(sock);
151 LogDebug("Total number of connections now %ld.", NumConnections);
152 io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
158 * IO callback for new outgoing non-SSL server connections.
159 * @param sock Socket descriptor
160 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
163 cb_connserver(int sock, UNUSED short what)
165 int res, err, server;
167 CONN_ID idx = Socket2Index( sock );
170 LogDebug("cb_connserver wants to write on unknown socket?!");
175 assert(what & IO_WANTWRITE);
177 /* Make sure that the server is still configured; it could have been
178 * removed in the meantime! */
179 server = Conf_GetServer(idx);
181 Log(LOG_ERR, "Connection on socket %d to \"%s\" aborted!",
182 sock, My_Connections[idx].host);
183 Conn_Close(idx, "Connection aborted!", NULL, false);
187 /* connect() finished, get result. */
188 sock_len = (socklen_t)sizeof(err);
189 res = getsockopt(My_Connections[idx].sock, SOL_SOCKET, SO_ERROR,
191 assert(sock_len == sizeof(err));
193 /* Error while connecting? */
194 if ((res != 0) || (err != 0)) {
196 Log(LOG_CRIT, "getsockopt (connection %d): %s!",
197 idx, strerror(errno));
200 "Can't connect socket to \"%s:%d\" (connection %d): %s!",
201 My_Connections[idx].host, Conf_Server[server].port,
204 Conn_Close(idx, "Can't connect!", NULL, false);
206 if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
207 /* more addresses to try... */
208 New_Server(res, &Conf_Server[server].dst_addr[0]);
209 /* connection to dst_addr[0] is now in progress, so
210 * remove this address... */
211 Conf_Server[server].dst_addr[0] =
212 Conf_Server[server].dst_addr[1];
213 memset(&Conf_Server[server].dst_addr[1], 0,
214 sizeof(Conf_Server[server].dst_addr[1]));
219 /* connect() succeeded, remove all additional addresses */
220 memset(&Conf_Server[server].dst_addr, 0,
221 sizeof(Conf_Server[server].dst_addr));
223 Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING );
225 if ( Conn_OPTION_ISSET( &My_Connections[idx], CONN_SSL_CONNECT )) {
226 io_event_setcb( sock, cb_connserver_login_ssl );
227 io_event_add( sock, IO_WANTWRITE|IO_WANTREAD );
236 * Login to a remote server.
237 * @param idx Connection index
240 server_login(CONN_ID idx)
242 Log( LOG_INFO, "Connection %d with \"%s:%d\" established. Now logging in ...", idx,
243 My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
245 io_event_setcb( My_Connections[idx].sock, cb_clientserver);
246 io_event_add( My_Connections[idx].sock, IO_WANTREAD|IO_WANTWRITE);
248 /* Send PASS and SERVER command to peer */
249 Conn_WriteStr( idx, "PASS %s %s", Conf_Server[Conf_GetServer( idx )].pwd_out, NGIRCd_ProtoID );
250 Conn_WriteStr( idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo );
256 * IO callback for new outgoing SSL-enabled server connections.
257 * @param sock Socket descriptor
258 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
261 cb_connserver_login_ssl(int sock, short unused)
263 CONN_ID idx = Socket2Index(sock);
271 switch (ConnSSL_Connect( &My_Connections[idx])) {
273 case 0: LogDebug("ConnSSL_Connect: not ready");
276 Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
277 Conn_Close(idx, "Can't connect!", NULL, false);
281 Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
282 My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
290 * IO callback for established non-SSL client and server connections.
291 * @param sock Socket descriptor
292 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
295 cb_clientserver(int sock, short what)
297 CONN_ID idx = Socket2Index(sock);
306 if (what & IO_WANTREAD
307 || (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE))) {
308 /* if TLS layer needs to write additional data, call
309 * Read_Request() instead so that SSL/TLS can continue */
313 if (what & IO_WANTREAD)
316 if (what & IO_WANTWRITE)
323 * IO callback for established SSL-enabled client and server connections.
324 * @param sock Socket descriptor
325 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
328 cb_clientserver_ssl(int sock, short what)
330 CONN_ID idx = Socket2Index(sock);
339 switch (ConnSSL_Accept(&My_Connections[idx])) {
343 return; /* EAGAIN: callback will be invoked again by IO layer */
345 Conn_Close(idx, "Socket closed!", "SSL accept error", false);
348 if (what & IO_WANTREAD)
351 if (what & IO_WANTWRITE)
354 io_event_setcb(sock, cb_clientserver); /* SSL handshake completed */
360 * Initialite connecion module.
367 /* Speicher fuer Verbindungs-Pool anfordern */
368 Pool_Size = CONNECTION_POOL;
369 if ((Conf_MaxConnections > 0) &&
370 (Pool_Size > Conf_MaxConnections))
371 Pool_Size = Conf_MaxConnections;
373 if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) {
374 Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" );
378 /* FIXME: My_Connetions/Pool_Size is needed by other parts of the
379 * code; remove them! */
380 My_Connections = (CONNECTION*) array_start(&My_ConnArray);
382 LogDebug("Allocated connection pool for %d items (%ld bytes).",
383 array_length(&My_ConnArray, sizeof( CONNECTION )), array_bytes(&My_ConnArray));
385 assert( array_length(&My_ConnArray, sizeof( CONNECTION )) >= (size_t) Pool_Size);
387 array_free( &My_Listeners );
389 /* Connection-Struktur initialisieren */
390 for( i = 0; i < Pool_Size; i++ ) Init_Conn_Struct( i );
392 /* Global write counter */
398 * Clean up connection module.
405 Conn_ExitListeners();
407 LogDebug("Shutting down all connections ..." );
408 for( idx = 0; idx < Pool_Size; idx++ ) {
409 if( My_Connections[idx].sock > NONE ) {
410 Conn_Close( idx, NULL, NGIRCd_SignalRestart ?
411 "Server going down (restarting)":"Server going down", true );
415 array_free(&My_ConnArray);
416 My_Connections = NULL;
418 io_library_shutdown();
423 ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
425 unsigned int created = 0;
430 len = array_length(a, sizeof (UINT16));
431 port = array_start(a);
433 fd = NewListener(listen_addr, *port);
438 if (!io_event_create( fd, IO_WANTREAD, func )) {
439 Log( LOG_ERR, "io_event_create(): Could not add listening fd %d (port %u): %s!",
440 fd, (unsigned int) *port, strerror(errno));
453 * Initialize all listening sockets.
454 * @return Number of created listening sockets
457 Conn_InitListeners( void )
459 /* Initialize ports on which the server should accept connections */
460 unsigned int created = 0;
461 char *copy, *listen_addr;
463 if (!io_library_init(CONNECTION_POOL)) {
464 Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno));
468 assert(Conf_ListenAddress);
470 /* can't use Conf_ListenAddress directly, see below */
471 copy = strdup(Conf_ListenAddress);
473 Log(LOG_CRIT, "Cannot copy %s: %s", Conf_ListenAddress, strerror(errno));
476 listen_addr = strtok(copy, ",");
478 while (listen_addr) {
479 ngt_TrimStr(listen_addr);
481 created += ports_initlisteners(&Conf_ListenPorts, listen_addr, cb_listen);
483 created += ports_initlisteners(&Conf_SSLOptions.ListenPorts, listen_addr, cb_listen_ssl);
487 listen_addr = strtok(NULL, ",");
490 /* Can't free() Conf_ListenAddress here: on REHASH, if the config file
491 * cannot be re-loaded, we'd end up with a NULL Conf_ListenAddress.
492 * Instead, free() takes place in conf.c, before the config file
493 * is being parsed. */
497 } /* Conn_InitListeners */
501 Conn_ExitListeners( void )
503 /* Close down all listening sockets */
507 Rendezvous_UnregisterListeners( );
510 arraylen = array_length(&My_Listeners, sizeof (int));
512 "Shutting down all listening sockets (%d total) ...", arraylen);
513 fd = array_start(&My_Listeners);
518 LogDebug("Listening socket %d closed.", *fd );
521 array_free(&My_Listeners);
522 } /* Conn_ExitListeners */
526 InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port)
530 ret = ng_ipaddr_init(addr, listen_addrstr, Port);
532 assert(listen_addrstr);
533 Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"",
534 listen_addrstr, Port, listen_addrstr);
541 set_v6_only(int af, int sock)
543 #if defined(IPV6_V6ONLY) && defined(WANT_IPV6)
549 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, (socklen_t)sizeof(on)))
550 Log(LOG_ERR, "Could not set IPV6_V6ONLY: %s", strerror(errno));
558 /* return new listening port file descriptor or -1 on failure */
560 NewListener(const char *listen_addr, UINT16 Port)
562 /* Create new listening socket on specified port */
566 char name[CLIENT_ID_LEN], *info;
568 if (!InitSinaddrListenAddr(&addr, listen_addr, Port))
571 af = ng_ipaddr_af(&addr);
572 sock = socket(af, SOCK_STREAM, 0);
574 Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
578 set_v6_only(af, sock);
580 if (!Init_Socket(sock))
583 if (bind(sock, (struct sockaddr *)&addr, ng_ipaddr_salen(&addr)) != 0) {
584 Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s",
585 ng_ipaddr_tostr(&addr), Port, strerror(errno));
590 if( listen( sock, 10 ) != 0 ) {
591 Log( LOG_CRIT, "Can't listen on socket: %s!", strerror( errno ));
596 /* keep fd in list so we can close it when ngircd restarts/shuts down */
597 if (!array_catb( &My_Listeners,(char*) &sock, sizeof(int) )) {
598 Log( LOG_CRIT, "Can't add socket to My_Listeners array: %s!", strerror( errno ));
603 Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
606 /* Get best server description text */
607 if( ! Conf_ServerInfo[0] ) info = Conf_ServerName;
610 /* Use server info string */
612 if( Conf_ServerInfo[0] == '[' )
614 /* Cut off leading hostname part in "[]" */
615 info = strchr( Conf_ServerInfo, ']' );
619 while( *info == ' ' ) info++;
622 if( ! info ) info = Conf_ServerInfo;
625 /* Add port number to description if non-standard */
627 snprintf(name, sizeof name, "%s (port %u)", info,
630 strlcpy(name, info, sizeof name);
632 /* Register service */
633 Rendezvous_Register( name, MDNS_TYPE, Port );
641 * SSL/TLS connections require extra treatment:
642 * When either CONN_SSL_WANT_WRITE or CONN_SSL_WANT_READ is set, we
643 * need to take care of that first, before checking read/write buffers.
644 * For instance, while we might have data in our write buffer, the
645 * TLS/SSL protocol might need to read internal data first for TLS/SSL
648 * If this function returns true, such a condition is met and we have
649 * to reverse the condition (check for read even if we've data to write,
650 * do not check for read but writeability even if write-buffer is empty).
653 SSL_WantRead(const CONNECTION *c)
655 if (Conn_OPTION_ISSET(c, CONN_SSL_WANT_READ)) {
656 io_event_add(c->sock, IO_WANTREAD);
662 SSL_WantWrite(const CONNECTION *c)
664 if (Conn_OPTION_ISSET(c, CONN_SSL_WANT_WRITE)) {
665 io_event_add(c->sock, IO_WANTWRITE);
672 SSL_WantRead(UNUSED const CONNECTION *c) { return false; }
674 SSL_WantWrite(UNUSED const CONNECTION *c) { return false; }
679 * "Main Loop": Loop until shutdown or restart is signalled.
680 * This function loops until a shutdown or restart of ngIRCd is signalled and
681 * calls io_dispatch() to check for readable and writable sockets every second.
682 * It checks for status changes on pending connections (e. g. when a hostname
683 * has been resolved), checks for "penalties" and timeouts, and handles the
690 unsigned int wdatalen, bytes_processed;
694 while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
698 Rendezvous_Handler();
701 /* Should the configuration be reloaded? */
702 if (NGIRCd_SignalRehash)
705 /* Check configured servers and established links */
709 /* Look for non-empty read buffers ... */
710 for (i = 0; i < Pool_Size; i++) {
711 if ((My_Connections[i].sock > NONE)
712 && (array_bytes(&My_Connections[i].rbuf) > 0)
713 && (My_Connections[i].delaytime <= t)) {
714 /* ... and try to handle the received data */
715 bytes_processed = Handle_Buffer(i);
716 /* if we processed data, and there might be
717 * more commands in the input buffer, do not
718 * try to read any more data now */
719 if (bytes_processed &&
720 array_bytes(&My_Connections[i].rbuf) > 2) {
722 ("Throttling connection %d: command limit reached!",
724 Conn_SetPenalty(i, 1);
729 /* Look for non-empty write buffers ... */
730 for (i = 0; i < Pool_Size; i++) {
731 if (My_Connections[i].sock <= NONE)
734 wdatalen = (unsigned int)array_bytes(&My_Connections[i].wbuf);
737 array_bytes(&My_Connections[i].zip.wbuf) > 0)
742 if (SSL_WantRead(&My_Connections[i]))
744 io_event_add(My_Connections[i].sock,
749 /* Check from which sockets we possibly could read ... */
750 for (i = 0; i < Pool_Size; i++) {
751 if (My_Connections[i].sock <= NONE)
754 if (SSL_WantWrite(&My_Connections[i]))
755 continue; /* TLS/SSL layer needs to write data; deal with this first */
757 if (Resolve_INPROGRESS(&My_Connections[i].res_stat)) {
758 /* Wait for completion of resolver sub-process ... */
759 io_event_del(My_Connections[i].sock,
764 if (Conn_OPTION_ISSET(&My_Connections[i], CONN_ISCONNECTING))
765 /* Wait for completion of connect() ... */
768 if (My_Connections[i].delaytime > t) {
769 /* There is a "penalty time" set: ignore socket! */
770 io_event_del(My_Connections[i].sock,
774 io_event_add(My_Connections[i].sock, IO_WANTREAD);
777 /* Set the timeout for reading from the network to 1 second,
778 * which is the granularity with witch we handle "penalty
779 * times" for example.
780 * Note: tv_sec/usec are undefined(!) after io_dispatch()
781 * returns, so we have to set it beforce each call to it! */
785 /* Wait for activity ... */
786 i = io_dispatch(&tv);
787 if (i == -1 && errno != EINTR) {
788 Log(LOG_EMERG, "Conn_Handler(): io_dispatch(): %s!",
790 Log(LOG_ALERT, "%s exiting due to fatal errors!",
796 if (NGIRCd_SignalQuit)
797 Log(LOG_NOTICE | LOG_snotice, "Server going down NOW!");
798 else if (NGIRCd_SignalRestart)
799 Log(LOG_NOTICE | LOG_snotice, "Server restarting NOW!");
804 * Write a text string into the socket of a connection.
805 * This function automatically appends CR+LF to the string and validates that
806 * the result is a valid IRC message (oversized messages are shortened, for
807 * example). Then it calls the Conn_Write() function to do the actual sending.
808 * @param Idx Index fo the connection.
809 * @param Format Format string, see printf().
810 * @return true on success, false otherwise.
814 Conn_WriteStr( CONN_ID Idx, char *Format, ... )
817 Conn_WriteStr( Idx, Format, va_alist )
823 char buffer[COMMAND_LEN];
828 assert( Idx > NONE );
829 assert( Format != NULL );
832 va_start( ap, Format );
836 if (vsnprintf( buffer, COMMAND_LEN - 2, Format, ap ) >= COMMAND_LEN - 2 ) {
838 * The string that should be written to the socket is longer
839 * than the allowed size of COMMAND_LEN bytes (including both
840 * the CR and LF characters). This can be caused by the
841 * IRC_WriteXXX() functions when the prefix of this server had
842 * to be added to an already "quite long" command line which
843 * has been received from a regular IRC client, for example.
845 * We are not allowed to send such "oversized" messages to
846 * other servers and clients, see RFC 2812 2.3 and 2813 3.3
847 * ("these messages SHALL NOT exceed 512 characters in length,
848 * counting all characters including the trailing CR-LF").
850 * So we have a big problem here: we should send more bytes
851 * to the network than we are allowed to and we don't know
852 * the originator (any more). The "old" behaviour of blaming
853 * the receiver ("next hop") is a bad idea (it could be just
854 * an other server only routing the message!), so the only
855 * option left is to shorten the string and to hope that the
856 * result is still somewhat useful ...
860 strcpy (buffer + sizeof(buffer) - strlen(CUT_TXTSUFFIX) - 2 - 1,
866 Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
869 len = strlcat( buffer, "\r\n", sizeof( buffer ));
870 ok = Conn_Write(Idx, buffer, len);
871 My_Connections[Idx].msg_out++;
875 } /* Conn_WriteStr */
879 * Append Data to the outbound write buffer of a connection.
880 * @param Idx Index of the connection.
881 * @param Data pointer to the data.
882 * @param Len length of Data.
883 * @return true on success, false otherwise.
886 Conn_Write( CONN_ID Idx, char *Data, size_t Len )
889 size_t writebuf_limit = WRITEBUFFER_LEN;
890 assert( Idx > NONE );
891 assert( Data != NULL );
894 c = Conn_GetClient(Idx);
897 /* Servers do get special write buffer limits, so they can generate
898 * all the messages that are required while peering. */
899 if (Client_Type(c) == CLIENT_SERVER)
900 writebuf_limit = WRITEBUFFER_SLINK_LEN;
902 /* Is the socket still open? A previous call to Conn_Write()
903 * may have closed the connection due to a fatal error.
904 * In this case it is sufficient to return an error, as well. */
905 if( My_Connections[Idx].sock <= NONE ) {
906 LogDebug("Skipped write on closed socket (connection %d).", Idx);
911 if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
913 * Zip_Buffer() does all the dirty work for us: it flushes
914 * the (pre-)compression buffers if required and handles
915 * all error conditions. */
916 if (!Zip_Buffer(Idx, Data, Len))
922 /* Uncompressed link:
923 * Check if outbound buffer has enough space for the data. */
924 if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
926 /* Buffer is full, flush it. Handle_Write deals with
927 * low-level errors, if any. */
928 if (!Handle_Write(Idx))
932 /* When the write buffer is still too big after flushing it,
933 * the connection will be killed. */
934 if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
937 "Write buffer overflow (connection %d, size %lu byte)!",
939 (unsigned long)array_bytes(&My_Connections[Idx].wbuf));
940 Conn_Close(Idx, "Write buffer overflow!", NULL, false);
944 /* Copy data to write buffer */
945 if (!array_catb(&My_Connections[Idx].wbuf, Data, Len))
948 My_Connections[Idx].bytes_out += Len;
951 /* Adjust global write counter */
959 Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient )
961 /* Close connection. Open pipes of asyncronous resolver
962 * sub-processes are closed down. */
968 double in_z_k, out_z_k;
972 assert( Idx > NONE );
974 /* Is this link already shutting down? */
975 if( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ISCLOSING )) {
976 /* Conn_Close() has been called recursively for this link;
977 * probabe reason: Handle_Write() failed -- see below. */
978 LogDebug("Recursive request to close connection: %d", Idx );
982 assert( My_Connections[Idx].sock > NONE );
984 /* Mark link as "closing" */
985 Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
987 port = ng_ipaddr_getport(&My_Connections[Idx].addr);
988 Log(LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx,
989 LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, port);
991 /* Search client, if any */
992 c = Conn_GetClient( Idx );
994 /* Should the client be informed? */
997 /* Send statistics to client if registered as user: */
998 if ((c != NULL) && (Client_Type(c) == CLIENT_USER)) {
1000 ":%s NOTICE %s :%sConnection statistics: client %.1f kb, server %.1f kb.",
1001 Client_ID(Client_ThisServer()), Client_ID(c),
1003 (double)My_Connections[Idx].bytes_in / 1024,
1004 (double)My_Connections[Idx].bytes_out / 1024);
1007 /* Send ERROR to client (see RFC 2812, section 3.1.7) */
1009 Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
1011 Conn_WriteStr(Idx, "ERROR :Closing connection.");
1014 /* Try to write out the write buffer. Note: Handle_Write() eventually
1015 * removes the CLIENT structure associated with this connection if an
1016 * error occurs! So we have to re-check if there is still an valid
1017 * CLIENT structure after calling Handle_Write() ...*/
1018 (void)Handle_Write( Idx );
1020 /* Search client, if any (re-check!) */
1021 c = Conn_GetClient( Idx );
1023 if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
1024 Log(LOG_INFO, "SSL connection %d shutting down ...", Idx);
1025 ConnSSL_Free(&My_Connections[Idx]);
1028 /* Shut down socket */
1029 if (! io_close(My_Connections[Idx].sock)) {
1030 /* Oops, we can't close the socket!? This is ... ugly! */
1032 "Error closing connection %d (socket %d) with %s:%d - %s! (ignored)",
1033 Idx, My_Connections[Idx].sock, My_Connections[Idx].host,
1034 port, strerror(errno));
1037 /* Mark socket as invalid: */
1038 My_Connections[Idx].sock = NONE;
1040 /* If there is still a client, unregister it now */
1042 Client_Destroy(c, LogMsg, FwdMsg, true);
1044 /* Calculate statistics and log information */
1045 in_k = (double)My_Connections[Idx].bytes_in / 1024;
1046 out_k = (double)My_Connections[Idx].bytes_out / 1024;
1048 if (Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP)) {
1049 in_z_k = (double)My_Connections[Idx].zip.bytes_in / 1024;
1050 out_z_k = (double)My_Connections[Idx].zip.bytes_out / 1024;
1051 /* Make sure that no division by zero can occur during
1052 * the calculation of in_p and out_p: in_z_k and out_z_k
1053 * are non-zero, that's guaranteed by the protocol until
1054 * compression can be enabled. */
1059 in_p = (int)(( in_k * 100 ) / in_z_k );
1060 out_p = (int)(( out_k * 100 ) / out_z_k );
1062 "Connection %d with %s:%d closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).",
1063 Idx, My_Connections[Idx].host, port,
1064 in_k, in_z_k, in_p, out_k, out_z_k, out_p);
1070 "Connection %d with %s:%d closed (in: %.1fk, out: %.1fk).",
1071 Idx, My_Connections[Idx].host, port,
1075 /* cancel running resolver */
1076 if (Resolve_INPROGRESS(&My_Connections[Idx].res_stat))
1077 Resolve_Shutdown(&My_Connections[Idx].res_stat);
1079 /* Servers: Modify time of next connect attempt? */
1080 Conf_UnsetServer( Idx );
1083 /* Clean up zlib, if link was compressed */
1084 if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
1085 inflateEnd( &My_Connections[Idx].zip.in );
1086 deflateEnd( &My_Connections[Idx].zip.out );
1087 array_free(&My_Connections[Idx].zip.rbuf);
1088 array_free(&My_Connections[Idx].zip.wbuf);
1092 array_free(&My_Connections[Idx].rbuf);
1093 array_free(&My_Connections[Idx].wbuf);
1095 /* Clean up connection structure (=free it) */
1096 Init_Conn_Struct( Idx );
1098 assert(NumConnections > 0);
1101 LogDebug("Shutdown of connection %d completed, %ld connection%s left.",
1102 Idx, NumConnections, NumConnections != 1 ? "s" : "");
1107 Conn_SyncServerStruct( void )
1109 /* Synchronize server structures (connection IDs):
1110 * connections <-> configuration */
1116 for( i = 0; i < Pool_Size; i++ ) {
1117 /* Established connection? */
1118 if (My_Connections[i].sock < 0)
1121 /* Server connection? */
1122 client = Conn_GetClient( i );
1123 if(( ! client ) || ( Client_Type( client ) != CLIENT_SERVER )) continue;
1125 for( c = 0; c < MAX_SERVERS; c++ )
1127 /* Configured server? */
1128 if( ! Conf_Server[c].host[0] ) continue;
1131 if( strcmp( Conf_Server[c].name, Client_ID( client )) == 0 )
1132 Conf_Server[c].conn_id = i;
1135 } /* SyncServerStruct */
1139 * Send out data of write buffer; connect new sockets.
1142 Handle_Write( CONN_ID Idx )
1147 assert( Idx > NONE );
1148 if ( My_Connections[Idx].sock < 0 ) {
1149 LogDebug("Handle_Write() on closed socket, connection %d", Idx);
1152 assert( My_Connections[Idx].sock > NONE );
1154 wdatalen = array_bytes(&My_Connections[Idx].wbuf );
1157 if (wdatalen == 0) {
1158 /* Write buffer is empty, so we try to flush the compression
1159 * buffer and get some data to work with from there :-) */
1160 if (!Zip_Flush(Idx))
1163 /* Now the write buffer most probably has changed: */
1164 wdatalen = array_bytes(&My_Connections[Idx].wbuf);
1168 if (wdatalen == 0) {
1169 /* Still no data, fine. */
1170 io_event_del(My_Connections[Idx].sock, IO_WANTWRITE );
1175 ("Handle_Write() called for connection %d, %ld bytes pending ...",
1179 if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
1180 len = ConnSSL_Write(&My_Connections[Idx], array_start(&My_Connections[Idx].wbuf), wdatalen);
1184 len = write(My_Connections[Idx].sock,
1185 array_start(&My_Connections[Idx].wbuf), wdatalen );
1188 if (errno == EAGAIN || errno == EINTR)
1191 Log(LOG_ERR, "Write error on connection %d (socket %d): %s!",
1192 Idx, My_Connections[Idx].sock, strerror(errno));
1193 Conn_Close(Idx, "Write error!", NULL, false);
1197 /* move any data not yet written to beginning */
1198 array_moveleft(&My_Connections[Idx].wbuf, 1, (size_t)len);
1201 } /* Handle_Write */
1205 Count_Connections(ng_ipaddr_t *a)
1210 for (i = 0; i < Pool_Size; i++) {
1211 if (My_Connections[i].sock <= NONE)
1213 if (ng_ipaddr_ipequal(&My_Connections[i].addr, a))
1217 } /* Count_Connections */
1221 * Initialize new client connection on a listening socket.
1222 * @param Sock Listening socket descriptor
1223 * @return Accepted socket descriptor or -1 on error
1226 New_Connection(int Sock)
1229 struct request_info req;
1231 ng_ipaddr_t new_addr;
1232 char ip_str[NG_INET_ADDRSTRLEN];
1233 int new_sock, new_sock_len, identsock;
1237 assert(Sock > NONE);
1239 new_sock_len = (int)sizeof(new_addr);
1240 new_sock = accept(Sock, (struct sockaddr *)&new_addr,
1241 (socklen_t *)&new_sock_len);
1243 Log(LOG_CRIT, "Can't accept connection: %s!", strerror(errno));
1247 if (!ng_ipaddr_tostr_r(&new_addr, ip_str)) {
1248 Log(LOG_CRIT, "fd %d: Can't convert IP address!", new_sock);
1249 Simple_Message(new_sock, "ERROR :Internal Server Error");
1255 /* Validate socket using TCP Wrappers */
1256 request_init(&req, RQ_DAEMON, PACKAGE_NAME, RQ_FILE, new_sock,
1257 RQ_CLIENT_SIN, &new_addr, NULL);
1259 if (!hosts_access(&req)) {
1261 "Refused connection from %s (by TCP Wrappers)!", ip_str);
1262 Simple_Message(new_sock, "ERROR :Connection refused");
1268 if (!Init_Socket(new_sock))
1271 /* Check global connection limit */
1272 if ((Conf_MaxConnections > 0) &&
1273 (NumConnections >= (size_t) Conf_MaxConnections)) {
1274 Log(LOG_ALERT, "Can't accept connection: limit (%d) reached!",
1275 Conf_MaxConnections);
1276 Simple_Message(new_sock, "ERROR :Connection limit reached");
1281 /* Check IP-based connection limit */
1282 cnt = Count_Connections(&new_addr);
1283 if ((Conf_MaxConnectionsIP > 0) && (cnt >= Conf_MaxConnectionsIP)) {
1284 /* Access denied, too many connections from this IP address! */
1286 "Refused connection from %s: too may connections (%ld) from this IP address!",
1288 Simple_Message(new_sock,
1289 "ERROR :Connection refused, too many connections from your IP address!");
1294 if (new_sock >= Pool_Size) {
1295 if (!array_alloc(&My_ConnArray, sizeof(CONNECTION),
1296 (size_t) new_sock)) {
1298 "Can't allocate memory! [New_Connection]");
1299 Simple_Message(new_sock, "ERROR: Internal error");
1303 LogDebug("Bumped connection pool to %ld items (internal: %ld items, %ld bytes)",
1304 new_sock, array_length(&My_ConnArray,
1305 sizeof(CONNECTION)), array_bytes(&My_ConnArray));
1307 /* Adjust pointer to new block */
1308 My_Connections = array_start(&My_ConnArray);
1309 while (Pool_Size <= new_sock)
1310 Init_Conn_Struct(Pool_Size++);
1313 /* register callback */
1314 if (!io_event_create(new_sock, IO_WANTREAD, cb_clientserver)) {
1316 "Can't accept connection: io_event_create failed!");
1317 Simple_Message(new_sock, "ERROR :Internal error");
1322 c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false);
1325 "Can't accept connection: can't create client structure!");
1326 Simple_Message(new_sock, "ERROR :Internal error");
1331 Init_Conn_Struct(new_sock);
1332 My_Connections[new_sock].sock = new_sock;
1333 My_Connections[new_sock].addr = new_addr;
1334 My_Connections[new_sock].client = c;
1336 /* Set initial hostname to IP address. This becomes overwritten when
1337 * the DNS lookup is enabled and succeeds, but is used otherwise. */
1338 if (ng_ipaddr_af(&new_addr) != AF_INET)
1339 snprintf(My_Connections[new_sock].host,
1340 sizeof(My_Connections[new_sock].host), "[%s]", ip_str);
1342 strlcpy(My_Connections[new_sock].host, ip_str,
1343 sizeof(My_Connections[new_sock].host));
1345 Client_SetHostname(c, My_Connections[new_sock].host);
1347 Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
1348 new_sock, My_Connections[new_sock].host,
1349 ng_ipaddr_getport(&new_addr), Sock);
1351 identsock = new_sock;
1357 Resolve_Addr(&My_Connections[new_sock].res_stat, &new_addr,
1358 identsock, cb_Read_Resolver_Result);
1360 /* ngIRCd waits up to 4 seconds for the result of the asynchronous
1361 * DNS and IDENT resolver subprocess using the "penalty" mechanism.
1362 * If there are results earlier, the delay is aborted. */
1363 Conn_SetPenalty(new_sock, 4);
1365 } /* New_Connection */
1369 Socket2Index( int Sock )
1371 assert( Sock >= 0 );
1373 if( Sock >= Pool_Size || My_Connections[Sock].sock != Sock ) {
1374 /* the Connection was already closed again, likely due to
1376 LogDebug("Socket2Index: can't get connection for socket %d!", Sock);
1380 } /* Socket2Index */
1384 * Read data from the network to the read buffer. If an error occures,
1385 * the socket of this connection will be shut down.
1388 Read_Request( CONN_ID Idx )
1391 static const unsigned int maxbps = COMMAND_LEN / 2;
1392 char readbuf[READBUFFER_LEN];
1395 assert( Idx > NONE );
1396 assert( My_Connections[Idx].sock > NONE );
1399 if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) ||
1400 (array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN))
1402 if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN)
1405 /* Read buffer is full */
1407 "Receive buffer overflow (connection %d): %d bytes!",
1408 Idx, array_bytes(&My_Connections[Idx].rbuf));
1409 Conn_Close( Idx, "Receive buffer overflow!", NULL, false );
1414 if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL))
1415 len = ConnSSL_Read( &My_Connections[Idx], readbuf, sizeof(readbuf));
1418 len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
1420 Log(LOG_INFO, "%s:%u (%s) is closing the connection ...",
1421 My_Connections[Idx].host,
1422 (unsigned int) ng_ipaddr_getport(&My_Connections[Idx].addr),
1423 ng_ipaddr_tostr(&My_Connections[Idx].addr));
1425 "Socket closed!", "Client closed connection",
1431 if( errno == EAGAIN ) return;
1432 Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
1433 Idx, My_Connections[Idx].sock, strerror(errno));
1434 Conn_Close(Idx, "Read error!", "Client closed connection",
1439 if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
1440 if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf,
1443 "Could not append recieved data to zip input buffer (connn %d): %d bytes!",
1445 Conn_Close(Idx, "Receive buffer overflow!", NULL,
1452 if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
1453 Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len );
1454 Conn_Close( Idx, "Receive buffer overflow!", NULL, false );
1458 /* Update connection statistics */
1459 My_Connections[Idx].bytes_in += len;
1461 /* Update timestamp of last data received if this connection is
1462 * registered as a user, server or service connection. Don't update
1463 * otherwise, so users have at least Conf_PongTimeout seconds time to
1464 * register with the IRC server -- see Check_Connections().
1465 * Set "lastping", too, so we can handle time shifts backwards ... */
1466 c = Conn_GetClient(Idx);
1467 if (c && (Client_Type(c) == CLIENT_USER
1468 || Client_Type(c) == CLIENT_SERVER
1469 || Client_Type(c) == CLIENT_SERVICE)) {
1471 if (My_Connections[Idx].lastdata != t)
1472 My_Connections[Idx].bps = 0;
1474 My_Connections[Idx].lastdata = t;
1475 My_Connections[Idx].lastping = My_Connections[Idx].lastdata;
1478 /* Look at the data in the (read-) buffer of this connection */
1479 My_Connections[Idx].bps += Handle_Buffer(Idx);
1480 if (Client_Type(c) != CLIENT_SERVER
1481 && My_Connections[Idx].bps >= maxbps) {
1482 LogDebug("Throttling connection %d: BPS exceeded! (%u >= %u)",
1483 Idx, My_Connections[Idx].bps, maxbps);
1484 Conn_SetPenalty(Idx, 1);
1486 } /* Read_Request */
1490 * Handle all data in the connection read-buffer.
1491 * Data is processed until no complete command is left in the read buffer,
1492 * or MAX_COMMANDS[_SERVER] commands were processed.
1493 * When a fatal error occurs, the connection is shut down.
1494 * @param Idx Index of the connection.
1495 * @return number of bytes processed.
1498 Handle_Buffer(CONN_ID Idx)
1501 char *ptr1, *ptr2, *first_eol;
1509 unsigned int i, maxcmd = MAX_COMMANDS, len_processed = 0;
1512 c = Conn_GetClient(Idx);
1515 /* Servers do get special command limits, so they can process
1516 * all the messages that are required while peering. */
1517 if (Client_Type(c) == CLIENT_SERVER)
1518 maxcmd = MAX_COMMANDS_SERVER;
1520 starttime = time(NULL);
1521 for (i=0; i < maxcmd; i++) {
1523 if (My_Connections[Idx].delaytime > starttime)
1526 /* Unpack compressed data, if compression is in use */
1527 if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
1528 /* When unzipping fails, Unzip_Buffer() shuts
1529 * down the connection itself */
1530 if (!Unzip_Buffer(Idx))
1535 if (0 == array_bytes(&My_Connections[Idx].rbuf))
1538 /* Make sure that the buffer is NULL terminated */
1539 if (!array_cat0_temporary(&My_Connections[Idx].rbuf)) {
1540 Conn_Close(Idx, NULL,
1541 "Can't allocate memory [Handle_Buffer]",
1546 /* RFC 2812, section "2.3 Messages", 5th paragraph:
1547 * "IRC messages are always lines of characters terminated
1548 * with a CR-LF (Carriage Return - Line Feed) pair [...]". */
1550 ptr = strstr(array_start(&My_Connections[Idx].rbuf), "\r\n");
1553 /* Check for non-RFC-compliant request (only CR or LF)?
1554 * Unfortunately, there are quite a few clients out there
1555 * that do this -- e. g. mIRC, BitchX, and Trillian :-( */
1556 ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r');
1557 ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n');
1559 /* Check if there is a single CR or LF _before_ the
1560 * corerct CR+LF line terminator: */
1561 first_eol = ptr1 < ptr2 ? ptr1 : ptr2;
1562 if (first_eol < ptr) {
1563 /* Single CR or LF before CR+LF found */
1567 } else if (ptr1 || ptr2) {
1568 /* No CR+LF terminated command found, but single
1569 * CR or LF found ... */
1571 ptr = ptr1 < ptr2 ? ptr1 : ptr2;
1573 ptr = ptr1 ? ptr1 : ptr2;
1581 /* Complete (=line terminated) request found, handle it! */
1584 len = ptr - (char *)array_start(&My_Connections[Idx].rbuf) + delta;
1586 if (len > (COMMAND_LEN - 1)) {
1587 /* Request must not exceed 512 chars (incl. CR+LF!),
1588 * see RFC 2812. Disconnect Client if this happens. */
1590 "Request too long (connection %d): %d bytes (max. %d expected)!",
1591 Idx, array_bytes(&My_Connections[Idx].rbuf),
1593 Conn_Close(Idx, NULL, "Request too long", true);
1597 len_processed += (unsigned int)len;
1599 /* Request is empty (only '\r\n', '\r' or '\n');
1600 * delta is 2 ('\r\n') or 1 ('\r' or '\n'), see above */
1601 array_moveleft(&My_Connections[Idx].rbuf, 1, len);
1605 /* remember if stream is already compressed */
1606 old_z = My_Connections[Idx].options & CONN_ZIP;
1609 My_Connections[Idx].msg_in++;
1611 (Idx, (char *)array_start(&My_Connections[Idx].rbuf)))
1612 return 0; /* error -> connection has been closed */
1614 array_moveleft(&My_Connections[Idx].rbuf, 1, len);
1615 LogDebug("Connection %d: %d bytes left in read buffer.",
1616 Idx, array_bytes(&My_Connections[Idx].rbuf));
1618 if ((!old_z) && (My_Connections[Idx].options & CONN_ZIP) &&
1619 (array_bytes(&My_Connections[Idx].rbuf) > 0)) {
1620 /* The last command activated socket compression.
1621 * Data that was read after that needs to be copied
1622 * to the unzip buffer for decompression: */
1624 (&My_Connections[Idx].zip.rbuf,
1625 &My_Connections[Idx].rbuf)) {
1626 Conn_Close(Idx, NULL,
1627 "Can't allocate memory [Handle_Buffer]",
1632 array_trunc(&My_Connections[Idx].rbuf);
1634 ("Moved already received data (%u bytes) to uncompression buffer.",
1635 array_bytes(&My_Connections[Idx].zip.rbuf));
1639 return len_processed;
1640 } /* Handle_Buffer */
1644 Check_Connections(void)
1646 /* check if connections are alive. if not, play PING-PONG first.
1647 * if this doesn't help either, disconnect client. */
1652 for (i = 0; i < Pool_Size; i++) {
1653 if (My_Connections[i].sock < 0)
1656 c = Conn_GetClient(i);
1657 if (c && ((Client_Type(c) == CLIENT_USER)
1658 || (Client_Type(c) == CLIENT_SERVER)
1659 || (Client_Type(c) == CLIENT_SERVICE))) {
1660 /* connected User, Server or Service */
1661 if (My_Connections[i].lastping >
1662 My_Connections[i].lastdata) {
1663 /* We already sent a ping */
1664 if (My_Connections[i].lastping <
1665 time(NULL) - Conf_PongTimeout) {
1668 ("Connection %d: Ping timeout: %d seconds.",
1669 i, Conf_PongTimeout);
1670 snprintf(msg, sizeof(msg), "Ping timeout: %d seconds", Conf_PongTimeout);
1671 Conn_Close(i, NULL, msg, true);
1673 } else if (My_Connections[i].lastdata <
1674 time(NULL) - Conf_PingTimeout) {
1675 /* We need to send a PING ... */
1676 LogDebug("Connection %d: sending PING ...", i);
1677 My_Connections[i].lastping = time(NULL);
1678 Conn_WriteStr(i, "PING :%s",
1679 Client_ID(Client_ThisServer()));
1682 /* The connection is not fully established yet, so
1683 * we don't do the PING-PONG game here but instead
1684 * disconnect the client after "a short time" if it's
1685 * still not registered. */
1687 if (My_Connections[i].lastdata <
1688 time(NULL) - Conf_PongTimeout) {
1690 ("Unregistered connection %d timed out ...",
1692 Conn_Close(i, NULL, "Timeout", false);
1696 } /* Check_Connections */
1700 Check_Servers( void )
1702 /* Check if we can establish further server links */
1707 /* Check all configured servers */
1708 for( i = 0; i < MAX_SERVERS; i++ ) {
1709 /* Valid outgoing server which isn't already connected or disabled? */
1710 if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 ) ||
1711 ( Conf_Server[i].conn_id > NONE ) || ( Conf_Server[i].flags & CONF_SFLAG_DISABLED ))
1714 /* Is there already a connection in this group? */
1715 if( Conf_Server[i].group > NONE ) {
1716 for (n = 0; n < MAX_SERVERS; n++) {
1717 if (n == i) continue;
1718 if ((Conf_Server[n].conn_id != NONE) &&
1719 (Conf_Server[n].group == Conf_Server[i].group))
1722 if (n < MAX_SERVERS) continue;
1725 /* Check last connect attempt? */
1726 time_now = time(NULL);
1727 if( Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry))
1730 /* Okay, try to connect now */
1731 Conf_Server[i].lasttry = time_now;
1732 Conf_Server[i].conn_id = SERVER_WAIT;
1733 assert(Resolve_Getfd(&Conf_Server[i].res_stat) < 0);
1734 Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host, cb_Connect_to_Server);
1736 } /* Check_Servers */
1740 New_Server( int Server , ng_ipaddr_t *dest)
1742 /* Establish new server link */
1743 char ip_str[NG_INET_ADDRSTRLEN];
1744 int af_dest, res, new_sock;
1747 assert( Server > NONE );
1749 if (!ng_ipaddr_tostr_r(dest, ip_str)) {
1750 Log(LOG_WARNING, "New_Server: Could not convert IP to string");
1754 Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d ... ",
1755 Conf_Server[Server].host, ip_str, Conf_Server[Server].port );
1757 af_dest = ng_ipaddr_af(dest);
1758 new_sock = socket(af_dest, SOCK_STREAM, 0);
1760 Log( LOG_CRIT, "Can't create socket (af %d) : %s!", af_dest, strerror( errno ));
1764 if (!Init_Socket(new_sock))
1767 /* is a bind address configured? */
1768 res = ng_ipaddr_af(&Conf_Server[Server].bind_addr);
1769 /* if yes, bind now. If it fails, warn and let connect() pick a source address */
1770 if (res && bind(new_sock, (struct sockaddr *) &Conf_Server[Server].bind_addr,
1771 ng_ipaddr_salen(&Conf_Server[Server].bind_addr)))
1773 ng_ipaddr_tostr_r(&Conf_Server[Server].bind_addr, ip_str);
1774 Log(LOG_WARNING, "Can't bind socket to %s: %s!", ip_str, strerror(errno));
1776 ng_ipaddr_setport(dest, Conf_Server[Server].port);
1777 res = connect(new_sock, (struct sockaddr *) dest, ng_ipaddr_salen(dest));
1778 if(( res != 0 ) && ( errno != EINPROGRESS )) {
1779 Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno ));
1784 if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)new_sock)) {
1786 "Cannot allocate memory for server connection (socket %d)",
1792 My_Connections = array_start(&My_ConnArray);
1794 assert(My_Connections[new_sock].sock <= 0);
1796 Init_Conn_Struct(new_sock);
1798 ng_ipaddr_tostr_r(dest, ip_str);
1799 c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWNSERVER, false);
1801 Log( LOG_ALERT, "Can't establish connection: can't create client structure!" );
1806 /* Conn_Close() decrements this counter again */
1808 Client_SetIntroducer( c, c );
1809 Client_SetToken( c, TOKEN_OUTBOUND );
1811 /* Register connection */
1812 Conf_Server[Server].conn_id = new_sock;
1813 My_Connections[new_sock].sock = new_sock;
1814 My_Connections[new_sock].addr = *dest;
1815 My_Connections[new_sock].client = c;
1816 strlcpy( My_Connections[new_sock].host, Conf_Server[Server].host,
1817 sizeof(My_Connections[new_sock].host ));
1819 /* Register new socket */
1820 if (!io_event_create( new_sock, IO_WANTWRITE, cb_connserver)) {
1821 Log( LOG_ALERT, "io_event_create(): could not add fd %d", strerror(errno));
1822 Conn_Close( new_sock, "io_event_create() failed", NULL, false );
1823 Init_Conn_Struct( new_sock );
1824 Conf_Server[Server].conn_id = NONE;
1827 if (Conf_Server[Server].SSLConnect && !ConnSSL_PrepareConnect( &My_Connections[new_sock],
1828 &Conf_Server[Server] ))
1830 Log(LOG_ALERT, "Could not initialize SSL for outgoing connection");
1831 Conn_Close( new_sock, "Could not initialize SSL for outgoing connection", NULL, false );
1832 Init_Conn_Struct( new_sock );
1833 Conf_Server[Server].conn_id = NONE;
1837 LogDebug("Registered new connection %d on socket %d (%ld in total).",
1838 new_sock, My_Connections[new_sock].sock, NumConnections);
1839 Conn_OPTION_ADD( &My_Connections[new_sock], CONN_ISCONNECTING );
1844 * Initialize connection structure.
1847 Init_Conn_Struct(CONN_ID Idx)
1849 time_t now = time(NULL);
1851 memset(&My_Connections[Idx], 0, sizeof(CONNECTION));
1852 My_Connections[Idx].sock = -1;
1853 My_Connections[Idx].signon = now;
1854 My_Connections[Idx].lastdata = now;
1855 My_Connections[Idx].lastprivmsg = now;
1856 Resolve_Init(&My_Connections[Idx].res_stat);
1857 } /* Init_Conn_Struct */
1861 Init_Socket( int Sock )
1863 /* Initialize socket (set options) */
1867 if (!io_setnonblock(Sock)) {
1868 Log( LOG_CRIT, "Can't enable non-blocking mode for socket: %s!", strerror( errno ));
1873 /* Don't block this port after socket shutdown */
1875 if( setsockopt( Sock, SOL_SOCKET, SO_REUSEADDR, &value, (socklen_t)sizeof( value )) != 0 )
1877 Log( LOG_ERR, "Can't set socket option SO_REUSEADDR: %s!", strerror( errno ));
1878 /* ignore this error */
1881 /* Set type of service (TOS) */
1882 #if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
1883 value = IPTOS_LOWDELAY;
1884 LogDebug("Setting option IP_TOS on socket %d to IPTOS_LOWDELAY (%d).", Sock, value );
1885 if( setsockopt( Sock, SOL_IP, IP_TOS, &value, (socklen_t)sizeof( value )) != 0 )
1887 Log( LOG_ERR, "Can't set socket option IP_TOS: %s!", strerror( errno ));
1888 /* ignore this error */
1897 cb_Connect_to_Server(int fd, UNUSED short events)
1899 /* Read result of resolver sub-process from pipe and start connection */
1902 ng_ipaddr_t dest_addrs[4]; /* we can handle at most 3; but we read up to
1903 four so we can log the 'more than we can handle'
1904 condition. First result is tried immediately, rest
1905 is saved for later if needed. */
1907 LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events);
1909 for (i=0; i < MAX_SERVERS; i++) {
1910 if (Resolve_Getfd(&Conf_Server[i].res_stat) == fd )
1914 if( i >= MAX_SERVERS) {
1915 /* Ops, no matching server found?! */
1917 LogDebug("Resolver: Got Forward Lookup callback for unknown server!?");
1921 /* Read result from pipe */
1922 len = Resolve_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
1926 assert((len % sizeof(ng_ipaddr_t)) == 0);
1928 LogDebug("Got result from resolver: %u structs (%u bytes).", len/sizeof(ng_ipaddr_t), len);
1930 memset(&Conf_Server[i].dst_addr, 0, sizeof(Conf_Server[i].dst_addr));
1931 if (len > sizeof(ng_ipaddr_t)) {
1932 /* more than one address for this hostname, remember them
1933 * in case first address is unreachable/not available */
1934 len -= sizeof(ng_ipaddr_t);
1935 if (len > sizeof(Conf_Server[i].dst_addr)) {
1936 len = sizeof(Conf_Server[i].dst_addr);
1938 "Notice: Resolver returned more IP Addresses for host than we can handle, additional addresses dropped.");
1940 memcpy(&Conf_Server[i].dst_addr, &dest_addrs[1], len);
1943 New_Server(i, dest_addrs);
1944 } /* cb_Read_Forward_Lookup */
1948 cb_Read_Resolver_Result( int r_fd, UNUSED short events )
1950 /* Read result of resolver sub-process from pipe and update the
1951 * apropriate connection/client structure(s): hostname and/or
1952 * IDENT user name.*/
1959 char readbuf[HOST_LEN + 2 + CLIENT_USER_LEN];
1961 char readbuf[HOST_LEN + 1];
1964 LogDebug("Resolver: Got callback on fd %d, events %d", r_fd, events );
1966 /* Search associated connection ... */
1967 for( i = 0; i < Pool_Size; i++ ) {
1968 if(( My_Connections[i].sock != NONE )
1969 && ( Resolve_Getfd(&My_Connections[i].res_stat) == r_fd ))
1972 if( i >= Pool_Size ) {
1973 /* Ops, none found? Probably the connection has already
1974 * been closed!? We'll ignore that ... */
1976 LogDebug("Resolver: Got callback for unknown connection!?");
1980 /* Read result from pipe */
1981 len = Resolve_Read(&My_Connections[i].res_stat, readbuf, sizeof readbuf -1);
1985 readbuf[len] = '\0';
1986 identptr = strchr(readbuf, '\n');
1987 assert(identptr != NULL);
1989 Log( LOG_CRIT, "Resolver: Got malformed result!");
1994 LogDebug("Got result from resolver: \"%s\" (%u bytes read).", readbuf, len);
1995 /* Okay, we got a complete result: this is a host name for outgoing
1996 * connections and a host name and IDENT user name (if enabled) for
1997 * incoming connections.*/
1998 assert ( My_Connections[i].sock >= 0 );
1999 /* Incoming connection. Search client ... */
2000 c = Conn_GetClient( i );
2001 assert( c != NULL );
2003 /* Only update client information of unregistered clients */
2004 if( Client_Type( c ) == CLIENT_UNKNOWN ) {
2005 strlcpy(My_Connections[i].host, readbuf, sizeof( My_Connections[i].host));
2006 Client_SetHostname( c, readbuf);
2010 Log(LOG_INFO, "IDENT lookup for connection %d: \"%s\".", i, identptr);
2011 Client_SetUser(c, identptr, true);
2013 Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
2018 else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
2020 /* Reset penalty time */
2021 Conn_ResetPenalty( i );
2022 } /* cb_Read_Resolver_Result */
2026 Simple_Message( int Sock, const char *Msg )
2028 char buf[COMMAND_LEN];
2030 /* Write "simple" message to socket, without using compression
2031 * or even the connection write buffers. Used e.g. for error
2032 * messages by New_Connection(). */
2033 assert( Sock > NONE );
2034 assert( Msg != NULL );
2036 strlcpy( buf, Msg, sizeof buf - 2);
2037 len = strlcat( buf, "\r\n", sizeof buf);
2038 (void)write(Sock, buf, len);
2039 } /* Simple_Error */
2043 * Get CLIENT structure that belongs to a local connection identified by its
2044 * index number. Each connection belongs to a client by definition, so it is
2045 * not required that the caller checks for NULL return values.
2046 * @param Idx Connection index number
2047 * @return Pointer to CLIENT structure
2050 Conn_GetClient( CONN_ID Idx )
2055 c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
2057 return c ? c->client : NULL;
2064 * Get information about used SSL chiper.
2065 * @param Idx Connection index number
2066 * @param buf Buffer for returned information text
2067 * @param len Size of return buffer "buf"
2068 * @return true on success, false otherwise
2071 Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len)
2075 assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
2076 return ConnSSL_GetCipherInfo(&My_Connections[Idx], buf, len);
2081 * Check if a connection is SSL-enabled or not.
2082 * @param Idx Connection index number
2083 * @return true if connection is SSL-enabled, false otherwise.
2086 Conn_UsesSSL(CONN_ID Idx)
2090 assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
2091 return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);