]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
make needlesly global function Conn_Write static.
[ngircd-alex.git] / src / ngircd / conn.c
index 4d5afa6c9a29722e48cfb310af690dd4190e82fc..051309739c9a8495cf5f3889430be98814adb09a 100644 (file)
@@ -17,7 +17,7 @@
 #include "portab.h"
 #include "io.h"
 
-static char UNUSED id[] = "$Id: conn.c,v 1.200 2006/12/17 23:04:45 fw Exp $";
+static char UNUSED id[] = "$Id: conn.c,v 1.207 2007/05/09 13:21:11 fw Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -83,6 +83,7 @@ static char UNUSED id[] = "$Id: conn.c,v 1.200 2006/12/17 23:04:45 fw Exp $";
 
 
 static bool Handle_Write PARAMS(( CONN_ID Idx ));
+static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
 static int New_Connection PARAMS(( int Sock ));
 static CONN_ID Socket2Index PARAMS(( int Sock ));
 static void Read_Request PARAMS(( CONN_ID Idx ));
@@ -123,7 +124,6 @@ cb_connserver(int sock, UNUSED short what)
 {
        int res, err;
        socklen_t sock_len;
-       CLIENT *c;
        CONN_ID idx = Socket2Index( sock );
        if (idx <= NONE) {
                LogDebug("cb_connserver wants to write on unknown socket?!");
@@ -150,14 +150,7 @@ cb_connserver(int sock, UNUSED short what)
                            Conf_Server[Conf_GetServer(idx)].port,
                            idx, strerror(err));
 
-               /* Clean up the CLIENT structure (to avoid silly log
-                * messages) and call Conn_Close() to do the rest. */
-               c = Conn_GetClient(idx);
-               if (c)
-                       Client_DestroyNow(c);
-               Conn_Close(idx, "Can't connect!", NULL, false);
+               Conn_Close(idx, "Can't connect!", NULL, false);
                return;
        }
 
@@ -267,10 +260,10 @@ Conn_Exit( void )
 } /* Conn_Exit */
 
 
-static int
+static unsigned int
 ports_initlisteners(array *a, void (*func)(int,short))
 {
-       int created = 0;
+       unsigned int created = 0;
        size_t len;
        int fd;
        UINT16 *port;
@@ -298,12 +291,12 @@ ports_initlisteners(array *a, void (*func)(int,short))
 }
 
 
-GLOBAL int
+GLOBAL unsigned int
 Conn_InitListeners( void )
 {
        /* Initialize ports on which the server should accept connections */
 
-       int created;
+       unsigned int created;
 
        if (!io_library_init(CONNECTION_POOL)) {
                Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno));
@@ -384,7 +377,7 @@ NewListener( const UINT16 Port )
        if( ! Init_Socket( sock )) return -1;
 
        if (bind(sock, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)) != 0) {
-               Log( LOG_CRIT, "Can't bind socket: %s!", strerror( errno ));
+               Log( LOG_CRIT, "Can't bind socket (port %d) : %s!", Port, strerror( errno ));
                close( sock );
                return -1;
        }
@@ -615,36 +608,45 @@ va_dcl
 } /* Conn_WriteStr */
 
 
-GLOBAL bool
+/**
+ * Append Data to outbound write buf.
+ * @param Idx Index fo the connection.
+ * @param Data pointer to data
+ * @param Len length of Data
+ * @return true on success, false otherwise.
+ */
+static bool
 Conn_Write( CONN_ID Idx, char *Data, size_t Len )
 {
-       /* Daten in Socket schreiben. Bei "fatalen" Fehlern wird
-        * der Client disconnectiert und false geliefert. */
-
+       CLIENT *c;
+       size_t writebuf_limit = WRITEBUFFER_LEN;
        assert( Idx > NONE );
        assert( Data != NULL );
        assert( Len > 0 );
 
-       /* Ist der entsprechende Socket ueberhaupt noch offen? In einem
-        * "Handler-Durchlauf" kann es passieren, dass dem nicht mehr so
-        * ist, wenn einer von mehreren Conn_Write()'s fehlgeschlagen ist.
-        * In diesem Fall wird hier einfach ein Fehler geliefert. */
+       c = Conn_GetClient(Idx);
+       assert( c != NULL);
+       if (Client_Type(c) == CLIENT_SERVER)
+               writebuf_limit = WRITEBUFFER_LEN * 10;
+       /* Is the socket still open? A previous call to Conn_Write()
+        * may have closed the connection due to a fatal error.
+        * In this case it is sufficient to return an error */
        if( My_Connections[Idx].sock <= NONE ) {
                LogDebug("Skipped write on closed socket (connection %d).", Idx );
                return false;
        }
 
-       /* Pruefen, ob im Schreibpuffer genuegend Platz ist. Ziel ist es,
-        * moeglichts viel im Puffer zu haben und _nicht_ gleich alles auf den
-        * Socket zu schreiben (u.a. wg. Komprimierung). */
-       if( array_bytes(&My_Connections[Idx].wbuf) >= WRITEBUFFER_LEN) {
-               /* Der Puffer ist dummerweise voll. Jetzt versuchen, den Puffer
-                * zu schreiben, wenn das nicht klappt, haben wir ein Problem ... */
+       /* check if outbound buffer has enough space for data.
+        * the idea is to keep data buffered  before sending, e.g. to improve
+        * compression */
+       if (array_bytes(&My_Connections[Idx].wbuf) >= writebuf_limit) {
+               /* Buffer is full, flush. Handle_Write deals with low-level errors, if any. */
                if( ! Handle_Write( Idx )) return false;
 
                /* check again: if our writebuf is twice als large as the initial limit: Kill connection */
-               if( array_bytes(&My_Connections[Idx].wbuf) >= (WRITEBUFFER_LEN*2)) {
-                       Log( LOG_NOTICE, "Write buffer overflow (connection %d)!", Idx );
+               if (array_bytes(&My_Connections[Idx].wbuf) >= (writebuf_limit*2)) {
+                       Log(LOG_NOTICE, "Write buffer overflow (connection %d, size %lu byte)!", Idx,
+                                       (unsigned long) array_bytes(&My_Connections[Idx].wbuf));
                        Conn_Close( Idx, "Write buffer overflow!", NULL, false );
                        return false;
                }
@@ -652,13 +654,13 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len )
 
 #ifdef ZLIB
        if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
-               /* Daten komprimieren und in Puffer kopieren */
+               /* compress and move data to write buffer */
                if( ! Zip_Buffer( Idx, Data, Len )) return false;
        }
        else
 #endif
        {
-               /* Daten in Puffer kopieren */
+               /* copy data to write buffer */
                if (!array_catb( &My_Connections[Idx].wbuf, Data, Len ))
                        return false;
 
@@ -700,7 +702,7 @@ Conn_Close( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )
 
        /* Mark link as "closing" */
        Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
-               
+
        if (LogMsg)
                txt = LogMsg;
        else
@@ -728,7 +730,6 @@ Conn_Close( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )
                         (double)My_Connections[Idx].bytes_out / 1024);
                }
 #endif
-
                /* Send ERROR to client (see RFC!) */
                if (FwdMsg)
                        Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
@@ -995,11 +996,19 @@ New_Connection( int Sock )
                        Init_Conn_Struct(Pool_Size++);
        }
 
+       /* register callback */
+       if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) {
+               Log(LOG_ALERT, "Can't accept connection: io_event_create failed!");
+               Simple_Message(new_sock, "ERROR :Internal error");
+               close(new_sock);
+               return -1;
+       }
+
        c = Client_NewLocal( new_sock, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWN, false );
        if( ! c ) {
-               Log( LOG_ALERT, "Can't accept connection: can't create client structure!" );
-               Simple_Message( new_sock, "ERROR :Internal error" );
-               close( new_sock );
+               Log(LOG_ALERT, "Can't accept connection: can't create client structure!");
+               Simple_Message(new_sock, "ERROR :Internal error");
+               io_close(new_sock);
                return -1;
        }
 
@@ -1008,13 +1017,6 @@ New_Connection( int Sock )
        My_Connections[new_sock].addr = new_addr;
        My_Connections[new_sock].client = c;
 
-       /* register callback */
-       if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) {
-               Simple_Message( new_sock, "ERROR :Internal error" );
-               Conn_Close( new_sock, "io_event_create() failed", NULL, false );
-               return -1;
-       }
-
        Log( LOG_INFO, "Accepted connection %d from %s:%d on socket %d.", new_sock,
                        inet_ntoa( new_addr.sin_addr ), ntohs( new_addr.sin_port), Sock );
 
@@ -1056,18 +1058,22 @@ Read_Request( CONN_ID Idx )
        /* Daten von Socket einlesen und entsprechend behandeln.
         * Tritt ein Fehler auf, so wird der Socket geschlossen. */
 
+       size_t readbuf_limit = READBUFFER_LEN;
        ssize_t len;
-       char readbuf[1024];
+       char readbuf[READBUFFER_LEN];
        CLIENT *c;
-
        assert( Idx > NONE );
        assert( My_Connections[Idx].sock > NONE );
 
+       c = Conn_GetClient(Idx);
+       assert ( c != NULL);
+       if (Client_Type(c) == CLIENT_SERVER)
+               readbuf_limit = READBUFFER_LEN * 10;
 #ifdef ZLIB
-       if (( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN ) ||
-               ( array_bytes(&My_Connections[Idx].zip.rbuf) >= ZREADBUFFER_LEN ))
+       if ((array_bytes(&My_Connections[Idx].rbuf) >= readbuf_limit) ||
+               (array_bytes(&My_Connections[Idx].zip.rbuf) >= readbuf_limit))
 #else
-       if ( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN )
+       if (array_bytes(&My_Connections[Idx].rbuf) >= readbuf_limit)
 #endif
        {
                /* Der Lesepuffer ist voll */
@@ -1077,7 +1083,7 @@ Read_Request( CONN_ID Idx )
                return;
        }
 
-       len = read( My_Connections[Idx].sock, readbuf, sizeof readbuf -1 );
+       len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
        if( len == 0 ) {
                Log( LOG_INFO, "%s:%d (%s) is closing the connection ...",
                        My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port),
@@ -1107,8 +1113,7 @@ Read_Request( CONN_ID Idx )
        } else
 #endif
        {
-               readbuf[len] = 0;
-               if (!array_cats( &My_Connections[Idx].rbuf, readbuf )) {
+               if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
                        Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len );
                        Conn_Close( Idx, "Receive buffer overflow!", NULL, false );
                }
@@ -1227,11 +1232,6 @@ Handle_Buffer( CONN_ID Idx )
                        /* The last Command activated Socket-Compression.
                         * Data that was read after that needs to be copied to Unzip-buf
                         * for decompression */
-                       if( array_bytes(&My_Connections[Idx].rbuf)> ZREADBUFFER_LEN ) {
-                               Log( LOG_ALERT, "Connection %d: No space left in unzip buf (need %u bytes)!",
-                                                               Idx, array_bytes(&My_Connections[Idx].rbuf ));
-                               return false;
-                       }
                        if (!array_copy( &My_Connections[Idx].zip.rbuf, &My_Connections[Idx].rbuf ))
                                return false;
 
@@ -1639,9 +1639,9 @@ Conn_GetClient( CONN_ID Idx )
        assert( Idx >= 0 );
 
        c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
-       
+
        assert(c != NULL);
-       
+
        return c ? c->client : NULL;
 }