* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
*
- * $Id: conn.c,v 1.92 2002/11/22 16:35:19 alex Exp $
+ * $Id: conn.c,v 1.95 2002/11/23 17:04:07 alex Exp $
*
* connect.h: Verwaltung aller Netz-Verbindungen ("connections")
*/
LOCAL CONN_ID Socket2Index PARAMS(( INT Sock ));
LOCAL VOID Read_Request PARAMS(( CONN_ID Idx ));
LOCAL BOOLEAN Try_Write PARAMS(( CONN_ID Idx ));
-LOCAL VOID Handle_Buffer PARAMS(( CONN_ID Idx ));
+LOCAL BOOLEAN Handle_Buffer PARAMS(( CONN_ID Idx ));
LOCAL VOID Check_Connections PARAMS(( VOID ));
LOCAL VOID Check_Servers PARAMS(( VOID ));
LOCAL VOID Init_Conn_Struct PARAMS(( LONG Idx ));
} /* Conn_Exit */
+GLOBAL INT
+Conn_InitListeners( VOID )
+{
+ /* Ports, auf denen der Server Verbindungen entgegennehmen
+ * soll, initialisieren */
+
+ INT created, i;
+
+ created = 0;
+ for( i = 0; i < Conf_ListenPorts_Count; i++ )
+ {
+ if( Conn_NewListener( Conf_ListenPorts[i] )) created++;
+ else Log( LOG_ERR, "Can't listen on port %u!", Conf_ListenPorts[i] );
+ }
+ return created;
+} /* Conn_InitListeners */
+
+
+GLOBAL VOID
+Conn_ExitListeners( VOID )
+{
+ /* Alle "Listen-Sockets" schliessen */
+
+ INT i;
+
+ Log( LOG_INFO, "Shutting down all listening sockets ..." );
+ for( i = 0; i < Conn_MaxFD + 1; i++ )
+ {
+ if( FD_ISSET( i, &My_Sockets ) && FD_ISSET( i, &My_Listeners ))
+ {
+ close( i );
+ Log( LOG_DEBUG, "Listening socket %d closed.", i );
+ }
+ }
+} /* Conn_ExitListeners */
+
+
GLOBAL BOOLEAN
Conn_NewListener( CONST UINT Port )
{
struct timeval tv;
time_t start, t;
LONG i, idx;
+ BOOLEAN timeout;
start = time( NULL );
while(( ! NGIRCd_Quit ) && ( ! NGIRCd_Restart ))
{
+ timeout = TRUE;
+
Check_Servers( );
Check_Connections( );
if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].rdatalen > 0 ))
{
/* Kann aus dem Buffer noch ein Befehl extrahiert werden? */
- Handle_Buffer( i );
+ if( Handle_Buffer( i )) timeout = FALSE;
}
}
}
/* Timeout initialisieren */
- tv.tv_sec = 1;
tv.tv_usec = 0;
+ if( timeout ) tv.tv_sec = TIME_RES;
+ else tv.tv_sec = 0;
/* Auf Aktivitaet warten */
i = select( Conn_MaxFD + 1, &read_sockets, &write_sockets, NULL, &tv );
* Socket zu schreiben. */
fd_set write_socket;
+ struct timeval tv;
assert( Idx > NONE );
assert( My_Connections[Idx].sock > NONE );
assert( My_Connections[Idx].wdatalen > 0 );
+ /* Timeout initialisieren: 0 Sekunden, also nicht blockieren */
+ tv.tv_sec = 0; tv.tv_usec = 0;
+
FD_ZERO( &write_socket );
FD_SET( My_Connections[Idx].sock, &write_socket );
- if( select( My_Connections[Idx].sock + 1, NULL, &write_socket, NULL, 0 ) == -1 )
+ if( select( My_Connections[Idx].sock + 1, NULL, &write_socket, NULL, &tv ) == -1 )
{
/* Fehler! */
if( errno != EINTR )
} /* Read_Request */
-LOCAL VOID
+LOCAL BOOLEAN
Handle_Buffer( CONN_ID Idx )
{
- /* Daten im Lese-Puffer einer Verbindung verarbeiten. */
+ /* Daten im Lese-Puffer einer Verbindung verarbeiten.
+ * Wurde ein Request verarbeitet, so wird TRUE geliefert,
+ * ansonsten FALSE (auch bei Fehlern). */
#ifndef STRICT_RFC
CHAR *ptr1, *ptr2;
#endif
CHAR *ptr;
INT len, delta;
+ BOOLEAN action;
/* Eine komplette Anfrage muss mit CR+LF enden, vgl.
* RFC 2812. Haben wir eine? */
}
#endif
+ action = FALSE;
if( ptr )
{
/* Ende der Anfrage wurde gefunden */
if( len > ( COMMAND_LEN - 1 ))
{
/* Eine Anfrage darf(!) nicht laenger als 512 Zeichen
- * (incl. CR+LF!) werden; vgl. RFC 2812. Wenn soetwas
- * empfangen wird, wird der Client disconnectiert. */
+ * (incl. CR+LF!) werden; vgl. RFC 2812. Wenn soetwas
+ * empfangen wird, wird der Client disconnectiert. */
Log( LOG_ERR, "Request too long (connection %d): %d bytes (max. %d expected)!", Idx, My_Connections[Idx].rdatalen, COMMAND_LEN - 1 );
Conn_Close( Idx, NULL, "Request too long", TRUE );
- return;
+ return FALSE;
}
if( len > delta )
{
/* Es wurde ein Request gelesen */
- if( ! Parse_Request( Idx, My_Connections[Idx].rbuf )) return;
+ if( ! Parse_Request( Idx, My_Connections[Idx].rbuf )) return FALSE;
+ else action = TRUE;
}
/* Puffer anpassen */
My_Connections[Idx].rdatalen -= len;
memmove( My_Connections[Idx].rbuf, My_Connections[Idx].rbuf + len, My_Connections[Idx].rdatalen );
}
+
+ return action;
} /* Handle_Buffer */