]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
- Loglevel (nochmal) angepasst.
[ngircd-alex.git] / src / ngircd / conn.c
index af12162c272f1c2c8c3254bcf5f8cce447562c8f..dccdb6a606cae7186a090345262b9f153a825344 100644 (file)
@@ -9,11 +9,29 @@
  * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
  * der an comBase beteiligten Autoren finden Sie in der Datei AUTHORS.
  *
- * $Id: conn.c,v 1.11 2001/12/25 23:15:16 alex Exp $
+ * $Id: conn.c,v 1.17 2001/12/29 03:06:16 alex Exp $
  *
  * connect.h: Verwaltung aller Netz-Verbindungen ("connections")
  *
  * $Log: conn.c,v $
+ * Revision 1.17  2001/12/29 03:06:16  alex
+ * - Loglevel (nochmal) angepasst.
+ *
+ * Revision 1.16  2001/12/27 19:32:44  alex
+ * - bei "Null-Requests" wird nichts mehr geloggt. Uberfluessig, da normal.
+ *
+ * Revision 1.15  2001/12/27 16:35:04  alex
+ * - vergessene Variable bei Ping-Timeout-Logmeldung ergaenzt. Opsa.
+ *
+ * Revision 1.14  2001/12/26 14:45:37  alex
+ * - "Code Cleanups".
+ *
+ * Revision 1.13  2001/12/26 03:36:57  alex
+ * - Verbindungen mit Lesefehlern werden nun korrekt terminiert.
+ *
+ * Revision 1.12  2001/12/26 03:20:53  alex
+ * - PING/PONG-Timeout implementiert.
+ *
  * Revision 1.11  2001/12/25 23:15:16  alex
  * - buffer werden nun periodisch geprueft, keine haengenden Clients mehr.
  *
@@ -72,6 +90,7 @@
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <time.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
 
 #include "ngircd.h"
 #include "client.h"
+#include "conf.h"
 #include "log.h"
 #include "parse.h"
 #include "tool.h"
@@ -105,6 +125,8 @@ typedef struct _Connection
        INT rdatalen;                   /* Laenge der Daten im Lesepuffer */
        CHAR wbuf[WRITEBUFFER_LEN + 1]; /* Schreibpuffer */
        INT wdatalen;                   /* Laenge der Daten im Schreibpuffer */
+       time_t lastdata;                /* Letzte Aktivitaet */
+       time_t lastping;                /* Letzter PING */
 } CONNECTION;
 
 
@@ -115,6 +137,7 @@ LOCAL CONN_ID Socket2Index( INT Sock );
 LOCAL VOID Read_Request( CONN_ID Idx );
 LOCAL BOOLEAN Try_Write( CONN_ID Idx );
 LOCAL VOID Handle_Buffer( CONN_ID Idx );
+LOCAL VOID Check_Connections( VOID );
 
 
 LOCAL fd_set My_Listener;
@@ -170,7 +193,7 @@ GLOBAL VOID Conn_Exit( VOID )
 } /* Conn_Exit */
 
 
-GLOBAL BOOLEAN Conn_New_Listener( CONST INT Port )
+GLOBAL BOOLEAN Conn_NewListener( CONST INT Port )
 {
        /* Neuen Listen-Socket erzeugen: der Server wartet dann
         * auf dem angegebenen Port auf Verbindungen. */
@@ -230,7 +253,7 @@ GLOBAL BOOLEAN Conn_New_Listener( CONST INT Port )
        Log( LOG_INFO, "Now listening on port %d, socket %d.", Port, sock );
 
        return TRUE;
-} /* Conn_New_Listener */
+} /* Conn_NewListener */
 
 
 GLOBAL VOID Conn_Handler( INT Timeout )
@@ -240,34 +263,36 @@ GLOBAL VOID Conn_Handler( INT Timeout )
        time_t start;
        INT i;
 
-       /* Timeout initialisieren */
-       tv.tv_sec = 0;
-       tv.tv_usec = 50000;
-
        start = time( NULL );
-       while( time( NULL ) - start < Timeout )
+       while(( time( NULL ) - start < Timeout ) && ( ! NGIRCd_Quit ))
        {
-               /* noch volle Schreib-Puffer suchen */
-               FD_ZERO( &write_sockets );
+               Check_Connections( );
+
+               /* Timeout initialisieren */
+               tv.tv_sec = 0;
+               tv.tv_usec = 50000;
+
+               /* noch volle Lese-Buffer suchen */
                for( i = 0; i < MAX_CONNECTIONS; i++ )
                {
-                       if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].wdatalen > 0 ))
+                       if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].rdatalen > 0 ))
                        {
-                               /* Socket der Verbindung in Set aufnehmen */
-                               FD_SET( My_Connections[i].sock, &write_sockets );
+                               /* Kann aus dem Buffer noch ein Befehl extrahiert werden? */
+                               Handle_Buffer( i );
                        }
                }
                
-               /* noch volle Lese-Buffer suchen */
+               /* noch volle Schreib-Puffer suchen */
+               FD_ZERO( &write_sockets );
                for( i = 0; i < MAX_CONNECTIONS; i++ )
                {
-                       if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].rdatalen > 0 ))
+                       if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].wdatalen > 0 ))
                        {
-                               /* Kann aus dem Buffer noch ein Befehl extrahiert werden? */
-                               Handle_Buffer( i );
+                               /* Socket der Verbindung in Set aufnehmen */
+                               FD_SET( My_Connections[i].sock, &write_sockets );
                        }
                }
-
+               
                read_sockets = My_Sockets;
                if( select( My_Max_Fd + 1, &read_sockets, &write_sockets, NULL, &tv ) == -1 )
                {
@@ -497,7 +522,7 @@ LOCAL VOID New_Connection( INT Sock )
        }
 
        /* Client-Struktur initialisieren */
-       if( ! Client_New_Local( idx, inet_ntoa( new_addr.sin_addr )))
+       if( ! Client_NewLocal( idx, inet_ntoa( new_addr.sin_addr )))
        {
                Log( LOG_ALERT, "Can't accept connection: can't create client structure!" );
                close( new_sock );
@@ -509,6 +534,8 @@ LOCAL VOID New_Connection( INT Sock )
        My_Connections[idx].addr = new_addr;
        My_Connections[idx].rdatalen = 0;
        My_Connections[idx].wdatalen = 0;
+       My_Connections[idx].lastdata = time( NULL );
+       My_Connections[idx].lastping = 0;
 
        /* Neuen Socket registrieren */
        FD_SET( new_sock, &My_Sockets );
@@ -559,10 +586,11 @@ LOCAL VOID Read_Request( CONN_ID Idx )
        {
                /* Fehler beim Lesen */
                Log( LOG_ALERT, "Read error on connection %d: %s!", Idx, strerror( errno ));
-               Conn_Close( Idx, "Read error!" );
+               Conn_Close( Idx, NULL );
                return;
        }
 
+       /* Lesebuffer updaten */
        My_Connections[Idx].rdatalen += len;
        assert( My_Connections[Idx].rdatalen <= READBUFFER_LEN );
        My_Connections[Idx].rbuf[My_Connections[Idx].rdatalen] = '\0';
@@ -577,6 +605,9 @@ LOCAL VOID Read_Request( CONN_ID Idx )
                return;
        }
 
+       /* Timestamp aktualisieren */
+       My_Connections[Idx].lastdata = time( NULL );
+
        Handle_Buffer( Idx );
 } /* Read_Request */
 
@@ -613,7 +644,6 @@ LOCAL VOID Handle_Buffer( CONN_ID Idx )
                        /* Es wurde ein Request gelesen */
                        if( ! Parse_Request( Idx, My_Connections[Idx].rbuf )) return;
                }
-               else Log( LOG_DEBUG, "Got null-request (connection %d).", Idx );
 
                /* Puffer anpassen */
                My_Connections[Idx].rdatalen -= len;
@@ -622,4 +652,36 @@ LOCAL VOID Handle_Buffer( CONN_ID Idx )
 } /* Handle_Buffer */
 
 
+LOCAL VOID Check_Connections( VOID )
+{
+       /* Pruefen, ob Verbindungen noch "alive" sind */
+
+       INT i;
+
+       for( i = 0; i < MAX_CONNECTIONS; i++ )
+       {
+               if( My_Connections[i].sock != NONE )
+               {
+                       if( My_Connections[i].lastping > My_Connections[i].lastdata )
+                       {
+                               /* es wurde bereits ein PING gesendet */
+                               if( My_Connections[i].lastping < time( NULL ) - Conf_PongTimeout )
+                               {
+                                       /* Timeout */
+                                       Log( LOG_INFO, "Connection %d: Ping timeout.", i );
+                                       Conn_Close( i, "Ping timeout" );
+                               }
+                       }
+                       else if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout )
+                       {
+                               /* es muss ein PING gesendet werden */
+                               Log( LOG_DEBUG, "Connection %d: sending PING ...", i );
+                               My_Connections[i].lastping = time( NULL );
+                               Conn_WriteStr( i, "PING :%s", This_Server->nick );
+                       }
+               }
+       }
+} /* Conn_Check */
+
+
 /* -eof- */