diff options
Diffstat (limited to 'src/forward.c')
-rw-r--r-- | src/forward.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/forward.c b/src/forward.c index 7916716..b396aa4 100644 --- a/src/forward.c +++ b/src/forward.c @@ -1081,6 +1081,37 @@ void receive_query(struct listener *listen, time_t now) source_addr.in6.sin6_flowinfo = 0; #endif + /* We can be configured to only accept queries from at-most-one-hop-away addresses. */ + if (option_bool(OPT_LOCAL_SERVICE)) + { + struct addrlist *addr; +#ifdef HAVE_IPV6 + if (listen->family == AF_INET6) + { + for (addr = daemon->interface_addrs; addr; addr = addr->next) + if ((addr->flags & ADDRLIST_IPV6) && + is_same_net6(&addr->addr.addr.addr6, &source_addr.in6.sin6_addr, addr->prefixlen)) + break; + } + else +#endif + { + struct in_addr netmask; + for (addr = daemon->interface_addrs; addr; addr = addr->next) + { + netmask.s_addr = 0xffffffff << (32 - addr->prefixlen); + if (!(addr->flags & ADDRLIST_IPV6) && + is_same_net(addr->addr.addr.addr4, source_addr.in.sin_addr, netmask)) + break; + } + } + if (!addr) + { + my_syslog(LOG_WARNING, _("Ignoring query from non-local network")); + return; + } + } + if (check_dst) { struct ifreq ifr; @@ -1544,6 +1575,37 @@ unsigned char *tcp_request(int confd, time_t now, if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1) return packet; + + /* We can be configured to only accept queries from at-most-one-hop-away addresses. */ + if (option_bool(OPT_LOCAL_SERVICE)) + { + struct addrlist *addr; +#ifdef HAVE_IPV6 + if (peer_addr.sa.sa_family == AF_INET6) + { + for (addr = daemon->interface_addrs; addr; addr = addr->next) + if ((addr->flags & ADDRLIST_IPV6) && + is_same_net6(&addr->addr.addr.addr6, &peer_addr.in6.sin6_addr, addr->prefixlen)) + break; + } + else +#endif + { + struct in_addr netmask; + for (addr = daemon->interface_addrs; addr; addr = addr->next) + { + netmask.s_addr = 0xffffffff << (32 - addr->prefixlen); + if (!(addr->flags & ADDRLIST_IPV6) && + is_same_net(addr->addr.addr.addr4, peer_addr.in.sin_addr, netmask)) + break; + } + } + if (!addr) + { + my_syslog(LOG_WARNING, _("Ignoring query from non-local network")); + return packet; + } + } while (1) { |