X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fresolve.c;h=ce1bf0d5ba45fefd80eb6900792c60100ea97816;hp=37d1c51c9fd79a2d538381fe3b2be695e98b1797;hb=03628dbeaf40a9de34b3eb6d5bf6dd34eed8248c;hpb=75dabcaae52eb9f2dcfbccc19743670962dbafb3 diff --git a/src/ngircd/resolve.c b/src/ngircd/resolve.c index 37d1c51c..ce1bf0d5 100644 --- a/src/ngircd/resolve.c +++ b/src/ngircd/resolve.c @@ -7,13 +7,18 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. - * - * Asynchronous resolver */ +#define RESOLVER_TIMEOUT (Conf_PongTimeout*3)/4 + #include "portab.h" +/** + * @file + * Asynchronous resolver + */ + #include "imp.h" #include #include @@ -23,6 +28,7 @@ #include #include #include +#include #ifdef IDENTAUTH #ifdef HAVE_IDENT_H @@ -30,9 +36,12 @@ #endif #endif +#include "array.h" #include "conn.h" +#include "conf.h" #include "defines.h" #include "log.h" +#include "ng_ipaddr.h" #include "exp.h" #include "resolve.h" @@ -41,46 +50,18 @@ static void Do_ResolveAddr PARAMS(( const ng_ipaddr_t *Addr, int Sock, int w_fd )); static void Do_ResolveName PARAMS(( const char *Host, int w_fd )); -static bool register_callback PARAMS((RES_STAT *s, void (*cbfunc)(int, short))); #ifdef WANT_IPV6 extern bool Conf_ConnectIPv4; extern bool Conf_ConnectIPv6; #endif -static pid_t -Resolver_fork(int *pipefds) -{ - pid_t pid; - - if (pipe(pipefds) != 0) { - Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno )); - return -1; - } - - pid = fork(); - switch(pid) { - case -1: - Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); - close(pipefds[0]); - close(pipefds[1]); - return -1; - case 0: /* child */ - close(pipefds[0]); - Log_Init_Resolver( ); - return 0; - } - /* parent */ - close(pipefds[1]); - return pid; -} - /** * Resolve IP (asynchronous!). */ GLOBAL bool -Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock, +Resolve_Addr(PROC_STAT * s, const ng_ipaddr_t *Addr, int identsock, void (*cbfunc) (int, short)) { int pipefd[2]; @@ -88,17 +69,15 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock, assert(s != NULL); - pid = Resolver_fork(pipefd); + pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT); if (pid > 0) { LogDebug("Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid); - - s->pid = pid; - s->resolver_fd = pipefd[0]; - return register_callback(s, cbfunc); + return true; } else if( pid == 0 ) { /* Sub process */ + Log_Init_Subprocess("Resolver"); Do_ResolveAddr( Addr, identsock, pipefd[1]); - Log_Exit_Resolver( ); + Log_Exit_Subprocess("Resolver"); exit(0); } return false; @@ -109,43 +88,33 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock, * Resolve hostname (asynchronous!). */ GLOBAL bool -Resolve_Name( RES_STAT *s, const char *Host, void (*cbfunc)(int, short)) +Resolve_Name( PROC_STAT *s, const char *Host, void (*cbfunc)(int, short)) { int pipefd[2]; pid_t pid; assert(s != NULL); - pid = Resolver_fork(pipefd); + pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT); if (pid > 0) { /* Main process */ #ifdef DEBUG Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid ); #endif - s->pid = pid; - s->resolver_fd = pipefd[0]; - return register_callback(s, cbfunc); + return true; } else if( pid == 0 ) { /* Sub process */ + Log_Init_Subprocess("Resolver"); Do_ResolveName(Host, pipefd[1]); - Log_Exit_Resolver( ); + Log_Exit_Subprocess("Resolver"); exit(0); } return false; } /* Resolve_Name */ -GLOBAL void -Resolve_Init(RES_STAT *s) -{ - assert(s != NULL); - s->resolver_fd = -1; - s->pid = 0; -} - - -#ifndef WANT_IPV6 -#ifdef h_errno +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) +#if !defined(WANT_IPV6) && defined(h_errno) static char * Get_Error( int H_Error ) { @@ -162,8 +131,8 @@ Get_Error( int H_Error ) } return "unknown error"; } -#endif /* h_errno */ -#endif /* WANT_IPV6 */ +#endif +#endif /* Do "IDENT" (aka "AUTH") lookup and append result to resolved_addr array */ @@ -177,17 +146,20 @@ Do_IdentQuery(int identsock, array *resolved_addr) return; #ifdef DEBUG - Log_Resolver(LOG_DEBUG, "Doing IDENT lookup on socket %d ...", identsock); + Log_Subprocess(LOG_DEBUG, "Doing IDENT lookup on socket %d ...", + identsock); #endif res = ident_id( identsock, 10 ); #ifdef DEBUG - Log_Resolver(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"", - identsock, res ? res : "(NULL)" ); + Log_Subprocess(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"", + identsock, res ? res : "(NULL)"); #endif if (!res) /* no result */ return; if (!array_cats(resolved_addr, res)) - Log_Resolver(LOG_WARNING, "Resolver: Cannot copy IDENT result: %s!", strerror(errno)); + Log_Subprocess(LOG_WARNING, + "Resolver: Cannot copy IDENT result: %s!", + strerror(errno)); free(res); #else @@ -249,7 +221,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen) assert(reslen >= NG_INET_ADDRSTRLEN); ng_ipaddr_tostr_r(IpAddr, tmp_ip_str); - Log_Resolver(LOG_WARNING, "%s: Can't resolve address \"%s\": %s", + Log_Subprocess(LOG_WARNING, "%s: Can't resolve address \"%s\": %s", funcname, tmp_ip_str, errmsg); strlcpy(resbuf, tmp_ip_str, reslen); return false; @@ -297,10 +269,10 @@ ForwardLookup(const char *hostname, array *IpAddr) switch (res) { case 0: break; case EAI_SYSTEM: - Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno)); + Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno)); return false; default: - Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res)); + Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res)); return false; } @@ -323,9 +295,10 @@ ForwardLookup(const char *hostname, array *IpAddr) if (!h) { #ifdef h_errno - Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, Get_Error(h_errno)); + Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", + hostname, Get_Error(h_errno)); #else - Log_Resolver(LOG_WARNING, "Can't resolve \"%s\"", hostname); + Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\"", hostname); #endif return false; } @@ -361,7 +334,7 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr) tmpAddrs = array_start(resolved_addr); while (len > 0) { - Log_Resolver(LOG_WARNING, "Address mismatch: %s != %s", + Log_Subprocess(LOG_WARNING, "Address mismatch: %s != %s", tmp_ip_str, ng_ipaddr_tostr(tmpAddrs)); tmpAddrs++; len--; @@ -374,15 +347,15 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr) static void Log_Forgery_NoIP(const char *ip, const char *host) { - Log_Resolver(LOG_WARNING, "Possible forgery: %s resolved to %s " - "(which has no ip address)", ip, host); + Log_Subprocess(LOG_WARNING, + "Possible forgery: %s resolved to %s (which has no ip address)", ip, host); } static void Log_Forgery_WrongIP(const char *ip, const char *host) { - Log_Resolver(LOG_WARNING,"Possible forgery: %s resolved to %s " - "(which points to different address)", ip, host); + Log_Subprocess(LOG_WARNING, + "Possible forgery: %s resolved to %s (which points to different address)", ip, host); } @@ -395,7 +368,7 @@ ArrayWrite(int fd, const array *a) assert(data); if( (size_t)write(fd, data, len) != len ) - Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!", + Log_Subprocess( LOG_CRIT, "Resolver: Can't write to parent: %s!", strerror(errno)); } @@ -413,7 +386,7 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd) array_init(&resolved_addr); ng_ipaddr_tostr_r(Addr, tmp_ip_str); #ifdef DEBUG - Log_Resolver(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str); + Log_Subprocess(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str); #endif if (!ReverseLookup(Addr, hostname, sizeof(hostname))) goto dns_done; @@ -428,13 +401,15 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd) strlcpy(hostname, tmp_ip_str, sizeof(hostname)); } #ifdef DEBUG - Log_Resolver(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname); + Log_Subprocess(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname); #endif dns_done: len = strlen(hostname); hostname[len] = '\n'; if (!array_copyb(&resolved_addr, hostname, ++len)) { - Log_Resolver(LOG_CRIT, "Resolver: Can't copy resolved name: %s!", strerror(errno)); + Log_Subprocess(LOG_CRIT, + "Resolver: Can't copy resolved name: %s!", + strerror(errno)); array_free(&resolved_addr); return; } @@ -457,7 +432,7 @@ Do_ResolveName( const char *Host, int w_fd ) ng_ipaddr_t *addr; size_t len; #endif - Log_Resolver(LOG_DEBUG, "Now resolving \"%s\" ...", Host); + Log_Subprocess(LOG_DEBUG, "Now resolving \"%s\" ...", Host); array_init(&IpAddrs); /* Resolve hostname */ @@ -471,7 +446,7 @@ Do_ResolveName( const char *Host, int w_fd ) addr = array_start(&IpAddrs); assert(addr); for (; len > 0; --len,addr++) { - Log_Resolver(LOG_DEBUG, "translated \"%s\" to %s.", + Log_Subprocess(LOG_DEBUG, "translated \"%s\" to %s.", Host, ng_ipaddr_tostr(addr)); } #endif @@ -482,66 +457,4 @@ Do_ResolveName( const char *Host, int w_fd ) } /* Do_ResolveName */ -static bool -register_callback( RES_STAT *s, void (*cbfunc)(int, short)) -{ - assert(cbfunc != NULL); - assert(s != NULL); - assert(s->resolver_fd >= 0); - - if (io_setnonblock(s->resolver_fd) && - io_event_create(s->resolver_fd, IO_WANTREAD, cbfunc)) - return true; - - Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno)); - close(s->resolver_fd); - Resolve_Init(s); - return false; -} - - -GLOBAL bool -Resolve_Shutdown( RES_STAT *s) -{ - bool ret = false; - - assert(s != NULL); - assert(s->resolver_fd >= 0); - - if (s->resolver_fd >= 0) - ret = io_close(s->resolver_fd); - - Resolve_Init(s); - return ret; -} - - -/** - * Read result of resolver sub-process from pipe - */ -GLOBAL size_t -Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen) -{ - ssize_t bytes_read; - - assert(buflen > 0); - - /* Read result from pipe */ - bytes_read = read(s->resolver_fd, readbuf, buflen); - if (bytes_read < 0) { - if (errno == EAGAIN) - return 0; - - Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror(errno)); - bytes_read = 0; - } -#ifdef DEBUG - else if (bytes_read == 0) - Log( LOG_DEBUG, "Resolver: Can't read result: EOF"); -#endif - Resolve_Shutdown(s); - return (size_t)bytes_read; -} - - /* -eof- */