]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Fixed resolver when using IDENT lookups, cleaned up code.
authorAlexander Barton <alex@barton.de>
Tue, 11 May 2004 00:01:11 +0000 (00:01 +0000)
committerAlexander Barton <alex@barton.de>
Tue, 11 May 2004 00:01:11 +0000 (00:01 +0000)
src/ngircd/conn.c
src/ngircd/irc-server.c
src/ngircd/ngircd.c
src/ngircd/resolve.c
src/ngircd/resolve.h

index d548efc26b6fe48002b1bc4e7dfcc09dae0921d9..c1e21fb2c194a381a51bd1a9e24df193b6e11111 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: conn.c,v 1.134 2004/04/25 14:06:12 alex Exp $";
+static char UNUSED id[] = "$Id: conn.c,v 1.135 2004/05/11 00:01:11 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -1600,35 +1600,28 @@ Init_Socket( INT Sock )
 LOCAL VOID
 Read_Resolver_Result( INT r_fd )
 {
-       /* Ergebnis von Resolver Sub-Prozess aus Pipe lesen
-        * und entsprechende Connection aktualisieren */
+       /* Read result of resolver sub-process from pipe and update the
+        * apropriate connection/client structure(s): hostname and/or
+        * IDENT user name.*/
 
-       CHAR result[HOST_LEN];
        CLIENT *c;
        INT len, i, n;
-
-       FD_CLR( r_fd, &Resolver_FDs );
-
-       /* Read result from pipe */
-       len = read( r_fd, result, HOST_LEN - 1 );
-       if( len < 0 )
-       {
-               /* Error! */
-               close( r_fd );
-               Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror( errno ));
-               return;
-       }
-       result[len] = '\0';
+       RES_STAT *s;
+       CHAR *ptr;
 
        /* Search associated connection ... */
        for( i = 0; i < Pool_Size; i++ )
        {
-               if(( My_Connections[i].sock != NONE ) && ( My_Connections[i].res_stat ) && ( My_Connections[i].res_stat->pipe[0] == r_fd )) break;
+               if(( My_Connections[i].sock != NONE )
+                 && ( My_Connections[i].res_stat != NULL )
+                 && ( My_Connections[i].res_stat->pipe[0] == r_fd ))
+                       break;
        }
        if( i >= Pool_Size )
        {
                /* Ops, none found? Probably the connection has already
-                * been closed. */
+                * been closed!? We'll ignore that ... */
+               FD_CLR( r_fd, &Resolver_FDs );
                close( r_fd );
 #ifdef DEBUG
                Log( LOG_DEBUG, "Resolver: Got result for unknown connection!?" );
@@ -1636,61 +1629,100 @@ Read_Resolver_Result( INT r_fd )
                return;
        }
 
+       /* Get resolver structure */
+       s = My_Connections[i].res_stat;
+       assert( s != NULL );
+
+       /* Read result from pipe */
+       len = read( r_fd, s->buffer + s->bufpos, sizeof( s->buffer ) - HOST_LEN - 1 );
+       if( len < 0 )
+       {
+               /* Error! */
+               close( r_fd );
+               Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror( errno ));
+               return;
+       }
+       s->bufpos += len;
+       s->buffer[s->bufpos] = '\0';
+
+       /* If the result string is incomplete, return to main loop and
+        * wait until we can read in more bytes. */
+try_resolve:
+       ptr = strchr( s->buffer, '\n' );
+       if( ! ptr ) return;
+       *ptr = '\0';
+
 #ifdef DEBUG
-       Log( LOG_DEBUG, "Resolver: %s is \"%s\".", My_Connections[i].host, result );
+       Log( LOG_DEBUG, "Got result from resolver: \"%s\" (%d bytes), stage %d.", s->buffer, len, s->stage );
 #endif
 
-       /* Clean up ... */
-       close( My_Connections[i].res_stat->pipe[0] );
-       close( My_Connections[i].res_stat->pipe[1] );
-       free( My_Connections[i].res_stat );
-       My_Connections[i].res_stat = NULL;
-
+       /* Okay, we got a complete result: this is a host name for outgoing
+        * connections and a host name or IDENT user name (if enabled) for
+        * incoming conneciions.*/
        if( My_Connections[i].sock > NONE )
        {
                /* Incoming connection */
-#ifdef IDENTAUTH
-               CHAR *ident;
-#endif
 
                /* Search client ... */
                c = Client_GetFromConn( i );
                assert( c != NULL );
 
                /* Only update client information of unregistered clients */
-               if( Client_Type( c ) != CLIENT_UNKNOWN )
+               if( Client_Type( c ) == CLIENT_UNKNOWN )
                {
-#ifdef DEBUG
-                       Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
-#endif
-                       return;
-               }               
-
-               /* Set hostname */
-               strlcpy( My_Connections[i].host, result, sizeof( My_Connections[i].host ));
-               Client_SetHostname( c, result );
+                       if( s->stage == 0 )
+                       {
+                               /* host name */
+                               strlcpy( My_Connections[i].host, s->buffer, sizeof( My_Connections[i].host ));
+                               Client_SetHostname( c, s->buffer );
 
 #ifdef IDENTAUTH
-               ident = strchr( result, 0 );
-               ident++;
-
-               /* Do we have a result of the IDENT lookup? If so, set it as the user name */
-               if( *ident )
-               {
-                       Log( LOG_INFO, "IDENT lookup for connection %ld: \"%s\".", i, ident );
-                       Client_SetUser( c, ident, TRUE );
+                               /* clean up buffer for IDENT result */
+                               len = strlen( s->buffer ) + 1;
+                               memmove( s->buffer, s->buffer + len, sizeof( s->buffer ) - len );
+                               s->bufpos -= len;
+
+                               /* Don't close pipe and clean up, but
+                                * instead wait for IDENT result */
+                               s->stage = 1;
+                               goto try_resolve;
+                       }
+                       else if( s->stage == 1 )
+                       {
+                               /* IDENT user name */
+                               if( s->buffer[0] )
+                               {
+                                       Log( LOG_INFO, "IDENT lookup for connection %ld: \"%s\".", i, s->buffer );
+                                       Client_SetUser( c, s->buffer, TRUE );
+                               }
+                               else Log( LOG_INFO, "IDENT lookup for connection %ld: no result.", i );
+#endif
+                       }
+                       else Log( LOG_ERR, "Resolver: got result for unknown stage %d!?", s->stage );
                }
-               else Log( LOG_INFO, "IDENT lookup for connection %ld: no result.", i );
+#ifdef DEBUG
+               else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
 #endif
        }
        else
        {
-               /* Outgoing connection (server link!): set IP address */
+               /* Outgoing connection (server link): set the IP address
+                * so that we can connect to it in the main loop. */
+
+               /* Search server ... */
                n = Conf_GetServer( i );
                assert( n > NONE );
-               strlcpy( Conf_Server[n].ip, result, sizeof( Conf_Server[n].ip ));
+
+               strlcpy( Conf_Server[n].ip, s->buffer, sizeof( Conf_Server[n].ip ));
        }
 
+       /* Clean up ... */
+       FD_CLR( r_fd, &Resolver_FDs );
+       close( My_Connections[i].res_stat->pipe[0] );
+       close( My_Connections[i].res_stat->pipe[1] );
+       free( My_Connections[i].res_stat );
+       My_Connections[i].res_stat = NULL;
+
        /* Reset penalty time */
        Conn_ResetPenalty( i );
 } /* Read_Resolver_Result */
index d230c75563d8509b183482a63a871ae7c70b07cd..72ca92bbcb28df7a802850dfe090a7d1d0780fa2 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: irc-server.c,v 1.36 2004/04/25 15:43:18 alex Exp $";
+static char UNUSED id[] = "$Id: irc-server.c,v 1.37 2004/05/11 00:01:11 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -23,6 +23,7 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.36 2004/04/25 15:43:18 alex Exp
 #include <string.h>
 #include <strings.h>
 
+#include "defines.h"
 #include "resolve.h"
 #include "conn.h"
 #include "conn-zip.h"
index 8ced6e3f8903c8698e2aa505c8c558a15798b539..94d323ed91c241413ffde6a081746f352a3eb70e 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: ngircd.c,v 1.84 2004/05/07 11:19:21 alex Exp $";
+static char UNUSED id[] = "$Id: ngircd.c,v 1.85 2004/05/11 00:01:11 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -31,13 +31,13 @@ static char UNUSED id[] = "$Id: ngircd.c,v 1.84 2004/05/07 11:19:21 alex Exp $";
 #include <pwd.h>
 #include <grp.h>
 
+#include "defines.h"
 #include "resolve.h"
 #include "conn.h"
 #include "client.h"
 #include "channel.h"
 #include "conf.h"
 #include "cvs-version.h"
-#include "defines.h"
 #include "lists.h"
 #include "log.h"
 #include "parse.h"
index c8cf7621c506c01e0cbe8d30248d843e49eb313e..36e16e56a9dad85a477f4f089acb9d263089c276 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: resolve.c,v 1.8 2004/03/11 22:16:31 alex Exp $";
+static char UNUSED id[] = "$Id: resolve.c,v 1.9 2004/05/11 00:01:11 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -102,6 +102,8 @@ Resolve_Addr( struct sockaddr_in *Addr )
                FD_SET( s->pipe[0], &Resolver_FDs );
                if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0];
                s->pid = pid;
+               s->stage = 0;
+               s->bufpos = 0;
                return s;
        }
        else if( pid == 0 )
@@ -160,6 +162,8 @@ Resolve_Name( CHAR *Host )
                FD_SET( s->pipe[0], &Resolver_FDs );
                if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0];
                s->pid = pid;
+               s->stage = 0;
+               s->bufpos = 0;
                return s;
        }
        else if( pid == 0 )
@@ -193,13 +197,13 @@ Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd )
 
        CHAR hostname[HOST_LEN];
        struct hostent *h;
+       INT len;
 #ifdef IDENTAUTH
        CHAR *res;
 #endif
 
-       Log_Resolver( LOG_DEBUG, "Now resolving %s ...", inet_ntoa( Addr->sin_addr ));
-
        /* Resolve IP address */
+       Log_Resolver( LOG_DEBUG, "Now resolving %s ...", inet_ntoa( Addr->sin_addr ));
        h = gethostbyaddr( (CHAR *)&Addr->sin_addr, sizeof( Addr->sin_addr ), AF_INET );
        if( h ) strlcpy( hostname, h->h_name, sizeof( hostname ));
        else
@@ -211,33 +215,35 @@ Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd )
 #endif 
                strlcpy( hostname, inet_ntoa( Addr->sin_addr ), sizeof( hostname ));
        }
+       Log_Resolver( LOG_DEBUG, "Ok, translated %s to \"%s\".", inet_ntoa( Addr->sin_addr ), hostname );
 
-#ifdef IDENTAUTH
-       /* Do "IDENT" (aka "AUTH") lookup and write result to parent */
-       Log_Resolver( LOG_DEBUG, "Doing IDENT lookup on socket %d ...", Sock );
-       res = ident_id( Sock, 10 );
-       Log_Resolver( LOG_DEBUG, "IDENT lookup on socket %d done.", Sock );
-#endif
-
-       /* Write result into pipe to parent */
-       if( (size_t)write( w_fd, hostname, strlen( hostname ) + 1 ) != (size_t)( strlen( hostname ) + 1 ))
+       /* Write resolver result into pipe to parent */
+       len = strlen( hostname ); 
+       hostname[len] = '\n'; len++;
+       if( (size_t)write( w_fd, hostname, len ) != (size_t)len )
        {
                Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!", strerror( errno ));
                close( w_fd );
                return;
        }
+
 #ifdef IDENTAUTH
-       if( (size_t)write( w_fd, res ? res : "", strlen( res ? res : "" ) + 1 ) != (size_t)( strlen( res ? res : "" ) + 1 ))
+       /* Do "IDENT" (aka "AUTH") lookup and write result to parent */
+       Log_Resolver( LOG_DEBUG, "Doing IDENT lookup on socket %d ...", Sock );
+       res = ident_id( Sock, 10 );
+       Log_Resolver( LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"", Sock, res ? res : "" );
+
+       /* Write IDENT result into pipe to parent */
+       len = strlen( res ? res : "" );
+       if( res != NULL ) res[len] = '\n';
+       len++;
+       if( (size_t)write( w_fd, res ? res : "\n", len ) != (size_t)len )
        {
                Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent (IDENT): %s!", strerror( errno ));
                close( w_fd );
-               free( res );
-               return;
        }
        free( res );
 #endif
-
-       Log_Resolver( LOG_DEBUG, "Ok, translated %s to \"%s\".", inet_ntoa( Addr->sin_addr ), hostname );
 } /* Do_ResolveAddr */
 
 
@@ -250,6 +256,7 @@ Do_ResolveName( CHAR *Host, INT w_fd )
        CHAR ip[16];
        struct hostent *h;
        struct in_addr *addr;
+       INT len;
 
        Log_Resolver( LOG_DEBUG, "Now resolving \"%s\" ...", Host );
 
@@ -269,16 +276,16 @@ Do_ResolveName( CHAR *Host, INT w_fd )
 #endif
                strcpy( ip, "" );
        }
+       if( ip[0] ) Log_Resolver( LOG_DEBUG, "Ok, translated \"%s\" to %s.", Host, ip );
 
        /* Write result into pipe to parent */
-       if( (size_t)write( w_fd, ip, strlen( ip ) + 1 ) != (size_t)( strlen( ip ) + 1 ))
+       len = strlen( ip );
+       ip[len] = '\n'; len++;
+       if( (size_t)write( w_fd, ip, len ) != (size_t)len )
        {
                Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!", strerror( errno ));
                close( w_fd );
-               return;
        }
-
-       if( ip[0] ) Log_Resolver( LOG_DEBUG, "Ok, translated \"%s\" to %s.", Host, ip );
 } /* Do_ResolveName */
 
 
index 716dd51f4f5b6d6b3862dfa1f34144dd0aedfb9a..2956fac14b07b68160cebe7feb9c66c1c6261900 100644 (file)
@@ -8,7 +8,7 @@
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
- * $Id: resolve.h,v 1.6 2003/12/27 13:01:12 alex Exp $
+ * $Id: resolve.h,v 1.7 2004/05/11 00:01:11 alex Exp $
  *
  * Asynchronous resolver (header)
  */
@@ -29,6 +29,9 @@ typedef struct _Res_Stat
 {
        INT pid;                        /* PID des Child-Prozess */
        INT pipe[2];                    /* Pipe fuer IPC */
+       INT stage;                      /* Hostname/IP(0) or IDENT(1)? */
+       INT bufpos;                     /* Position in buffer */
+       CHAR buffer[HOST_LEN];          /* Buffer */
 } RES_STAT;