X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Fresolve.c;h=295a559f6f14a551c6f66cb89b3036e620511db3;hb=2d4ea288353c2240c8d13e41c8da1557fc32168b;hp=999ef9906df241f3c3d195524df8fb86c1082907;hpb=4c113d8850dfc423e3dae2d2f90e7e9a9d42f0b0;p=ngircd-alex.git diff --git a/src/ngircd/resolve.c b/src/ngircd/resolve.c index 999ef990..295a559f 100644 --- a/src/ngircd/resolve.c +++ b/src/ngircd/resolve.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2009 by Alexander Barton (alex@barton.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,8 +14,6 @@ #include "portab.h" -static char UNUSED id[] = "$Id: resolve.c,v 1.29 2008/02/26 22:04:17 fw Exp $"; - #include "imp.h" #include #include @@ -32,57 +30,33 @@ static char UNUSED id[] = "$Id: resolve.c,v 1.29 2008/02/26 22:04:17 fw Exp $"; #endif #endif +#include "array.h" #include "conn.h" #include "defines.h" #include "log.h" +#include "ng_ipaddr.h" +#include "proc.h" #include "exp.h" #include "resolve.h" #include "io.h" +static void Init_Subprocess PARAMS(( void )); 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]; @@ -90,15 +64,13 @@ 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); if (pid > 0) { - Log(LOG_DEBUG, "Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid); - - s->pid = pid; - s->resolver_fd = pipefd[0]; - return register_callback(s, cbfunc); + LogDebug("Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid); + return true; } else if( pid == 0 ) { /* Sub process */ + Init_Subprocess(); Do_ResolveAddr( Addr, identsock, pipefd[1]); Log_Exit_Resolver( ); exit(0); @@ -111,24 +83,23 @@ 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); 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 */ + Init_Subprocess(); Do_ResolveName(Host, pipefd[1]); Log_Exit_Resolver( ); exit(0); @@ -137,17 +108,35 @@ Resolve_Name( RES_STAT *s, const char *Host, void (*cbfunc)(int, short)) } /* Resolve_Name */ -GLOBAL void -Resolve_Init(RES_STAT *s) +/** + * Signal handler for the forked resolver subprocess. + */ +static void +Signal_Handler(int Signal) { - assert(s != NULL); - s->resolver_fd = -1; - s->pid = 0; + switch(Signal) { + case SIGTERM: +#ifdef DEBUG + Log_Resolver(LOG_DEBUG, "Resolver: Got TERM signal, exiting."); +#endif + exit(1); + } } -#ifndef WANT_IPV6 -#ifdef h_errno +/** + * Initialize forked resolver subprocess. + */ +static void +Init_Subprocess(void) +{ + signal(SIGTERM, Signal_Handler); + Log_Init_Resolver(); +} + + +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) +#if !defined(WANT_IPV6) && defined(h_errno) static char * Get_Error( int H_Error ) { @@ -164,8 +153,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 */ @@ -205,7 +194,7 @@ Do_IdentQuery(int identsock, array *resolved_addr) * the IP address in resbuf and returns false. * @param IpAddr ip address to resolve * @param resbuf result buffer to store DNS name/string representation of ip address - * @reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN) + * @param reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN) * @return true if reverse lookup successful, false otherwise */ static bool @@ -220,7 +209,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen) *resbuf = 0; res = getnameinfo((struct sockaddr *) IpAddr, ng_ipaddr_salen(IpAddr), - resbuf, reslen, NULL, 0, NI_NAMEREQD); + resbuf, (socklen_t)reslen, NULL, 0, NI_NAMEREQD); if (res == 0) return true; @@ -293,6 +282,8 @@ ForwardLookup(const char *hostname, array *IpAddr) if (!Conf_ConnectIPv4) hints.ai_family = AF_INET6; #endif + memset(&addr, 0, sizeof(addr)); + res = getaddrinfo(hostname, NULL, &hints, &ai_results); switch (res) { case 0: break; @@ -482,52 +473,18 @@ 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) +Resolve_Read( PROC_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); + bytes_read = read(Proc_GetPipeFd(s), readbuf, buflen); if (bytes_read < 0) { if (errno == EAGAIN) return 0; @@ -539,8 +496,9 @@ Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen) else if (bytes_read == 0) Log( LOG_DEBUG, "Resolver: Can't read result: EOF"); #endif - Resolve_Shutdown(s); + Proc_Kill(s); return (size_t)bytes_read; } -/* -eof- */ + +/* -eof- */