From 6a8de931ec95518c909990181c24d650e0c81933 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Sat, 24 Jun 2017 11:28:33 -0400 Subject: [PATCH] [core] continue collecting use of netdb.h continue collecting use of netdb.h into inet_ntop_cache.[ch] --- src/inet_ntop_cache.c | 62 +++++++++++++++++++++++++++++++++++++++++++ src/inet_ntop_cache.h | 1 + src/mod_extforward.c | 56 +------------------------------------- 3 files changed, 64 insertions(+), 55 deletions(-) diff --git a/src/inet_ntop_cache.c b/src/inet_ntop_cache.c index c8b9f633..330d288e 100644 --- a/src/inet_ntop_cache.c +++ b/src/inet_ntop_cache.c @@ -248,6 +248,68 @@ int sock_addr_from_str_hints(server *srv, sock_addr *addr, socklen_t *len, const } +int sock_addr_from_str_numeric(server *srv, sock_addr *addr, const char *str) +{ + /*(note: does not handle port if getaddrinfo() is not available)*/ + /*(note: getaddrinfo() is stricter than inet_aton() in what is accepted)*/ + /*(this routine originates from mod_extforward.c:ipstr_to_sockaddr()*/ + #ifdef HAVE_IPV6 + struct addrinfo hints, *addrlist = NULL; + int result; + + /** + * quoting $ man getaddrinfo + * + * NOTES + * AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3. + * AI_NUMERICSERV is available since glibc 2.3.4. + */ + #ifndef AI_NUMERICSERV + #define AI_NUMERICSERV 0 + #endif + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; + + errno = 0; + result = getaddrinfo(str, NULL, &hints, &addrlist); + + if (result != 0) { + log_error_write(srv, __FILE__, __LINE__, "SSSs(S)", + "could not parse ip address ", str, " because ", + gai_strerror(result), strerror(errno)); + } else if (addrlist == NULL) { + log_error_write(srv, __FILE__, __LINE__, "SSS", + "Problem in parsing ip address ", str, + ": succeeded, but no information returned"); + result = -1; + } else switch (addrlist->ai_family) { + case AF_INET: + memcpy(&addr->ipv4, addrlist->ai_addr, sizeof(addr->ipv4)); + force_assert(AF_INET == addr->plain.sa_family); + break; + case AF_INET6: + memcpy(&addr->ipv6, addrlist->ai_addr, sizeof(addr->ipv6)); + force_assert(AF_INET6 == addr->plain.sa_family); + break; + default: + log_error_write(srv, __FILE__, __LINE__, "SSS", + "Problem in parsing ip address ", str, + ": succeeded, but unknown family"); + result = -1; + break; + } + + freeaddrinfo(addrlist); + return (0 == result); + #else + UNUSED(srv); + addr->ipv4.sin_addr.s_addr = inet_addr(str); + addr->plain.sa_family = AF_INET; + return (addr->ipv4.sin_addr.s_addr != 0xFFFFFFFF); + #endif +} + + const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) { #ifdef HAVE_IPV6 typedef struct { diff --git a/src/inet_ntop_cache.h b/src/inet_ntop_cache.h index 37db3b94..6c395ae8 100644 --- a/src/inet_ntop_cache.h +++ b/src/inet_ntop_cache.h @@ -20,6 +20,7 @@ int sock_addr_inet_ntop_copy_buffer(buffer *b, const sock_addr *addr); int sock_addr_inet_ntop_append_buffer(buffer *b, const sock_addr *addr); int sock_addr_from_str_hints(server *srv, sock_addr *addr, socklen_t *len, const char *str, int family, unsigned short port); +int sock_addr_from_str_numeric(server *srv, sock_addr *addr, const char *str); const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr); diff --git a/src/mod_extforward.c b/src/mod_extforward.c index b7539288..be29ec7c 100644 --- a/src/mod_extforward.c +++ b/src/mod_extforward.c @@ -15,9 +15,6 @@ #include #include "sys-socket.h" -#ifndef _WIN32 -#include -#endif /** * mod_extforward.c for lighttpd, by comman.kang gmail com @@ -432,57 +429,6 @@ static const char *last_not_in_array(array *a, plugin_data *p) return NULL; } -static void ipstr_to_sockaddr(server *srv, const char *host, sock_addr *sock) { -#ifdef HAVE_IPV6 - struct addrinfo hints, *addrlist = NULL; - int result; - - memset(&hints, 0, sizeof(hints)); - sock->plain.sa_family = AF_UNSPEC; - -#ifndef AI_NUMERICSERV - /** - * quoting $ man getaddrinfo - * - * NOTES - * AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3. - * AI_NUMERICSERV is available since glibc 2.3.4. - */ -#define AI_NUMERICSERV 0 -#endif - hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; - - errno = 0; - result = getaddrinfo(host, NULL, &hints, &addrlist); - - if (result != 0) { - log_error_write(srv, __FILE__, __LINE__, "SSSs(S)", - "could not parse ip address ", host, " because ", gai_strerror(result), strerror(errno)); - } else if (addrlist == NULL) { - log_error_write(srv, __FILE__, __LINE__, "SSS", - "Problem in parsing ip address ", host, ": succeeded, but no information returned"); - } else switch (addrlist->ai_family) { - case AF_INET: - memcpy(&sock->ipv4, addrlist->ai_addr, sizeof(sock->ipv4)); - force_assert(AF_INET == sock->plain.sa_family); - break; - case AF_INET6: - memcpy(&sock->ipv6, addrlist->ai_addr, sizeof(sock->ipv6)); - force_assert(AF_INET6 == sock->plain.sa_family); - break; - default: - log_error_write(srv, __FILE__, __LINE__, "SSS", - "Problem in parsing ip address ", host, ": succeeded, but unknown family"); - } - - freeaddrinfo(addrlist); -#else - UNUSED(srv); - sock->ipv4.sin_addr.s_addr = inet_addr(host); - sock->plain.sa_family = (sock->ipv4.sin_addr.s_addr == 0xFFFFFFFF) ? AF_UNSPEC : AF_INET; -#endif -} - static int mod_extforward_set_addr(server *srv, connection *con, plugin_data *p, const char *addr) { sock_addr sock; handler_ctx *hctx = con->plugin_ctx[p->id]; @@ -492,7 +438,7 @@ static int mod_extforward_set_addr(server *srv, connection *con, plugin_data *p, } sock.plain.sa_family = AF_UNSPEC; - ipstr_to_sockaddr(srv, addr, &sock); + if (1 != sock_addr_from_str_numeric(srv, &sock, addr)) return 0; if (sock.plain.sa_family == AF_UNSPEC) return 0; /* we found the remote address, modify current connection and save the old address */