summaryrefslogtreecommitdiff
path: root/src/forward.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/forward.c')
-rw-r--r--src/forward.c62
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)
{