diff --git a/configure.ac b/configure.ac index 37e7d27..957699c 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,16 @@ if test x"$transparent_enabled" = x"yes"; then AC_DEFINE(TRANSPARENT_PROXY) fi +dnl Include support for reverse dns to match IP network/mask ? +AH_TEMPLATE([FDNS_ENABLE], + [Include support for forward dns to match IP network/mask. This is best used with nscd enabled to minimise DNS resolution delays]) +TP_ARG_ENABLE(fdns, + [Enable support for forward dns to match IP network/mask (default is NO)], + no) +if test x"$fdns__enabled" = x"yes"; then + AC_DEFINE(FDNS_ENABLE) +fi + dnl Let user decide whether he wants support for manpages dnl Which require either pod2man or a tarball release AH_TEMPLATE([MANPAGE_SUPPORT], diff --git a/docs/man5/tinyproxy.conf.txt.in b/docs/man5/tinyproxy.conf.txt.in index 4471cbd..78b8b69 100644 --- a/docs/man5/tinyproxy.conf.txt.in +++ b/docs/man5/tinyproxy.conf.txt.in @@ -204,6 +204,7 @@ Note that the upstream directive can also be used to null-route a specific target domain/host, e.g.: `upstream http 0.0.0.0:0 ".adserver.com"` +With FDNS enabled the site's IP address will also be matched against the <IP/bits> or <IP/mask> values in addition to the name or domain match =item B<MaxClients> Tinyproxy creates one thread for each connected client. diff --git a/src/hostspec.c b/src/hostspec.c index 1f956f2..fc48d43 100644 --- a/src/hostspec.c +++ b/src/hostspec.c @@ -2,6 +2,9 @@ #include "hostspec.h" #include "heap.h" #include "network.h" +#ifdef FDNS_ENABLE +#include "log.h" +#endif static int dotted_mask(char *bitmask_string, unsigned char array[]) { @@ -159,6 +162,42 @@ static int numeric_match(const uint8_t addr[], const struct hostspec *h) return 1; } +#ifdef FDNS_ENABLE +static int dns_numeric_match(const char *ip, const struct hostspec *h) +{ + int ret; + struct addrinfo *res, *ressave; + uint8_t numeric_addr[IPV6_LEN]; + char ipbuf[512]; + + errno = 0; + + ret =getaddrinfo (ip, NULL, NULL, &res); + + ressave = res; + + if (ret != 0) { + if (ret == EAI_SYSTEM) + log_message (LOG_ERR, "Could not retrieve address info for %s : %s",ip,strerror(errno)); + else + log_message (LOG_ERR, "Could not retrieve address info for %s : %s",ip,gai_strerror(errno)); + } else { + do { + /* return if IP matches */ + get_ip_string (res->ai_addr, ipbuf, sizeof (ipbuf)); + full_inet_pton (ipbuf, &numeric_addr); + if (numeric_match (numeric_addr, h)) { + break; + } + } while ((res = res->ai_next) != NULL); + } + + freeaddrinfo (ressave); + + return numeric_match (numeric_addr, h); +} +#endif + /* check whether ip matches hostspec. return 1 on match, 0 on non-match */ int hostspec_match(const char *ip, const struct hostspec *h) { @@ -171,6 +210,9 @@ int hostspec_match(const char *ip, const struct hostspec *h) { if(is_numeric_addr) return 0; return string_match (ip, h->address.string); case HST_NUMERIC: +#ifdef FDNS_ENABLE + if(!is_numeric_addr) return dns_numeric_match(ip, h); +#endif return numeric_match (numeric_addr, h); case HST_NONE: return 0;