mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-03 13:38:32 +00:00
Compare commits
48
Commits
v2.77test5
...
v2.78
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30df7efc96 | ||
|
|
3e8c42cba5 | ||
|
|
62cb936cb7 | ||
|
|
39921d03ba | ||
|
|
6a0b00f0d6 | ||
|
|
51eadb692a | ||
|
|
897c113fda | ||
|
|
33e3f1029c | ||
|
|
3d4ff1ba84 | ||
|
|
24036ea507 | ||
|
|
0549c73b7e | ||
|
|
b697fbb7f1 | ||
|
|
96e063c43d | ||
|
|
4e841da1a6 | ||
|
|
09ce307bdb | ||
|
|
a3303e196e | ||
|
|
63437ffbb5 | ||
|
|
69a815aa8f | ||
|
|
1d224949cc | ||
|
|
391f708a09 | ||
|
|
cbd29e5da8 | ||
|
|
50a2841d34 | ||
|
|
9396752c11 | ||
|
|
712dadb287 | ||
|
|
32be32eab8 | ||
|
|
1649f709e7 | ||
|
|
50ca85504c | ||
|
|
4bb68866a8 | ||
|
|
2446514e71 | ||
|
|
109d0e74f1 | ||
|
|
74ea91531a | ||
|
|
9828ab115e | ||
|
|
f77700aa27 | ||
|
|
0fbd980639 | ||
|
|
43cdf1c3d0 | ||
|
|
ff19b1a97d | ||
|
|
1835343acd | ||
|
|
2aaea18f43 | ||
|
|
7ab78b937f | ||
|
|
c7be0164ce | ||
|
|
d203af4a02 | ||
|
|
05f76dab89 | ||
|
|
bf05f8ff20 | ||
|
|
09f3b2cd9c | ||
|
|
22827870fa | ||
|
|
4583dd9e42 | ||
|
|
561441320f | ||
|
|
b2a9c571eb |
No files matched your search
@@ -0,0 +1 @@
|
||||
VERSION export-subst
|
||||
@@ -55,6 +55,8 @@ dbus_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG)
|
||||
dbus_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1`
|
||||
idn_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --cflags libidn`
|
||||
idn_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn`
|
||||
idn2_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --cflags libidn2`
|
||||
idn2_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --libs libidn2`
|
||||
ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack`
|
||||
ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack`
|
||||
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.2`
|
||||
@@ -82,8 +84,8 @@ hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
all : $(BUILDDIR)
|
||||
@cd $(BUILDDIR) && $(MAKE) \
|
||||
top="$(top)" \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
|
||||
-f $(top)/Makefile dnsmasq
|
||||
|
||||
mostly_clean :
|
||||
@@ -106,8 +108,8 @@ all-i18n : $(BUILDDIR)
|
||||
@cd $(BUILDDIR) && $(MAKE) \
|
||||
top="$(top)" \
|
||||
i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \
|
||||
build_cflags="$(version) $(dbus_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags) `$(PKG_CONFIG) --cflags libidn`" \
|
||||
build_libs="$(dbus_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) `$(PKG_CONFIG) --libs libidn`" \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
|
||||
-f $(top)/Makefile dnsmasq
|
||||
for f in `cd $(PO); echo *.po`; do \
|
||||
cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \
|
||||
|
||||
@@ -206,13 +206,13 @@ int main(int argc, char **argv)
|
||||
{
|
||||
unsigned int x;
|
||||
if ((x = t/86400))
|
||||
printf("%dd", x);
|
||||
printf("%ud", x);
|
||||
if ((x = (t/3600)%24))
|
||||
printf("%dh", x);
|
||||
printf("%uh", x);
|
||||
if ((x = (t/60)%60))
|
||||
printf("%dm", x);
|
||||
printf("%um", x);
|
||||
if ((x = t%60))
|
||||
printf("%ds", x);
|
||||
printf("%us", x);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
Hi,
|
||||
I updated the try-all-ns patch to work with the latest version of git. Ended up implementing it on top of master, 2.78test2-7-g63437ff. As that specific if-clause has been changed in the last few commits, it's not compatible for 2.77, sadly.
|
||||
|
||||
Find the patch attached.
|
||||
|
||||
Regards,
|
||||
|
||||
Rasmus Ahlberg
|
||||
Software Developer, R&D
|
||||
Electrolux Small Appliances
|
||||
@@ -0,0 +1,20 @@
|
||||
diff --git a/src/forward.c b/src/forward.c
|
||||
index e3fa94b..ecf3b98 100644
|
||||
--- a/src/forward.c
|
||||
+++ b/src/forward.c
|
||||
@@ -789,9 +789,12 @@ void reply_query(int fd, int family, time_t now)
|
||||
|
||||
/* Note: if we send extra options in the EDNS0 header, we can't recreate
|
||||
the query from the reply. */
|
||||
- if (RCODE(header) == REFUSED &&
|
||||
- forward->forwardall == 0 &&
|
||||
- !(forward->flags & FREC_HAS_EXTRADATA))
|
||||
+ if ((RCODE(header) == REFUSED &&
|
||||
+ forward->forwardall == 0 &&
|
||||
+ !(forward->flags & FREC_HAS_EXTRADATA)) ||
|
||||
+ /* If strict-order is set, try next server on NXDOMAIN reply */
|
||||
+ (RCODE(header) == NXDOMAIN && option_bool(OPT_ORDER) &&
|
||||
+ server->next != NULL))
|
||||
/* for broken servers, attempt to send to another one. */
|
||||
{
|
||||
unsigned char *pheader;
|
||||
Vendored
+14
@@ -1,3 +1,17 @@
|
||||
dnsmasq (2.78-1) unstable; urgency=high
|
||||
|
||||
* New upstream.
|
||||
Security fixes for CVE-2017-13704 (closes: #877102)
|
||||
Security fixes for CVE-2017-14491 - CVE-2017-14496 inclusive.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Sun, 29 Sep 2017 21:34:00 +0000
|
||||
|
||||
dnsmasq (2.77-2) unstable; urgency=low
|
||||
|
||||
* Improve sed regexp for parsing root.ds.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Mon, 5 Jun 2017 20:46:32 +0000
|
||||
|
||||
dnsmasq (2.77-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
|
||||
Vendored
+1
-1
@@ -111,7 +111,7 @@ DNSMASQ_OPTS="$DNSMASQ_OPTS --local-service"
|
||||
ROOT_DS="/usr/share/dns/root.ds"
|
||||
|
||||
if [ -f $ROOT_DS ]; then
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS `sed -e s/"^.*DS[\t ]"/--trust-anchor=.,/ -e s/" "/,/g $ROOT_DS | tr '\n' ' '`"
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS `sed -rne "s/^([.a-ZA-Z0-9]+)([[:space:]]+[0-9]+)*([[:space:]]+IN)*[[:space:]]+DS[[:space:]]+/--trust-anchor=\1,/;s/[[:space:]]+/,/gp" $ROOT_DS | tr '\n' ' '`"
|
||||
fi
|
||||
|
||||
start()
|
||||
|
||||
Vendored
+4
-3
@@ -48,6 +48,10 @@ ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_DBUS
|
||||
endif
|
||||
|
||||
ifeq (,$(filter noidn, $(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_IDN
|
||||
endif
|
||||
|
||||
ifeq (,$(filter noconntrack,$(DEB_BUILD_OPTIONS)))
|
||||
ifeq ($(DEB_HOST_ARCH_OS),linux)
|
||||
DEB_COPTS += -DHAVE_CONNTRACK
|
||||
@@ -84,9 +88,6 @@ endif
|
||||
|
||||
ifneq (,$(filter noi18n,$(DEB_BUILD_OPTIONS)))
|
||||
TARGET = install
|
||||
ifeq (,$(filter noidn, $(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_IDN
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter uselua,$(DEB_BUILD_OPTIONS)))
|
||||
|
||||
+3
-1
@@ -1021,6 +1021,8 @@ dhcp-host directive (or one implied by /etc/ethers) then the special
|
||||
tag "known" is set. This allows dnsmasq to be configured to
|
||||
ignore requests from unknown machines using
|
||||
.B --dhcp-ignore=tag:!known
|
||||
If the host matches only a dhcp-host directive which cannot
|
||||
be used because it specifies an address on different subnet, the tag "known-othernet" is set.
|
||||
Ethernet addresses (but not client-ids) may have
|
||||
wildcard bytes, so for example
|
||||
.B --dhcp-host=00:20:e0:3b:13:*,ignore
|
||||
@@ -2046,7 +2048,7 @@ include set:<tag>, including one from the
|
||||
.B dhcp-range
|
||||
used to allocate the address, one from any matching
|
||||
.B dhcp-host
|
||||
(and "known" if a dhcp-host matches)
|
||||
(and "known" or "known-othernet" if a dhcp-host matches)
|
||||
The tag "bootp" is set for BOOTP requests, and a tag whose name is the
|
||||
name of the interface on which the request arrived is also set.
|
||||
|
||||
|
||||
+492
-453
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+4
-9
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -119,11 +119,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
struct cname *a, *candidate;
|
||||
unsigned int wclen;
|
||||
|
||||
/* Clear buffer beyond request to avoid risk of
|
||||
information disclosure. */
|
||||
memset(((char *)header) + qlen, 0,
|
||||
(limit - ((char *)header)) - qlen);
|
||||
|
||||
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
|
||||
return 0;
|
||||
|
||||
@@ -597,12 +592,12 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
char *p = name;
|
||||
|
||||
if (subnet->prefixlen >= 24)
|
||||
p += sprintf(p, "%d.", a & 0xff);
|
||||
p += sprintf(p, "%u.", a & 0xff);
|
||||
a = a >> 8;
|
||||
if (subnet->prefixlen >= 16 )
|
||||
p += sprintf(p, "%d.", a & 0xff);
|
||||
p += sprintf(p, "%u.", a & 0xff);
|
||||
a = a >> 8;
|
||||
p += sprintf(p, "%d.in-addr.arpa", a & 0xff);
|
||||
p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
|
||||
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -1511,7 +1511,7 @@ void dump_cache(time_t now)
|
||||
/* ctime includes trailing \n - eat it */
|
||||
*(p-1) = 0;
|
||||
#endif
|
||||
my_syslog(LOG_INFO, daemon->namebuff);
|
||||
my_syslog(LOG_INFO, "%s", daemon->namebuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-8
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -94,10 +94,10 @@ HAVE_DBUS
|
||||
servers via DBus.
|
||||
|
||||
HAVE_IDN
|
||||
define this if you want international domain name support.
|
||||
NOTE: for backwards compatibility, IDN support is automatically
|
||||
included when internationalisation support is built, using the
|
||||
*-i18n makefile targets, even if HAVE_IDN is not explicitly set.
|
||||
define this if you want international domain name 2003 support.
|
||||
|
||||
HAVE_LIBIDN2
|
||||
define this if you want international domain name 2008 support.
|
||||
|
||||
HAVE_CONNTRACK
|
||||
define this to include code which propagates conntrack marks from
|
||||
@@ -177,6 +177,7 @@ RESOLVFILE
|
||||
/* #define HAVE_LUASCRIPT */
|
||||
/* #define HAVE_DBUS */
|
||||
/* #define HAVE_IDN */
|
||||
/* #define HAVE_LIBIDN2 */
|
||||
/* #define HAVE_CONNTRACK */
|
||||
/* #define HAVE_DNSSEC */
|
||||
|
||||
@@ -396,10 +397,14 @@ static char *compile_opts =
|
||||
"no-"
|
||||
#endif
|
||||
"i18n "
|
||||
#if !defined(LOCALEDIR) && !defined(HAVE_IDN)
|
||||
#if defined(HAVE_LIBIDN2)
|
||||
"IDN2 "
|
||||
#else
|
||||
#if !defined(HAVE_IDN)
|
||||
"no-"
|
||||
#endif
|
||||
"IDN "
|
||||
#endif
|
||||
"IDN "
|
||||
#endif
|
||||
#ifndef HAVE_DHCP
|
||||
"no-"
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+17
-13
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -145,7 +145,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
struct cmsghdr *cmptr;
|
||||
struct iovec iov;
|
||||
ssize_t sz;
|
||||
int iface_index = 0, unicast_dest = 0, is_inform = 0;
|
||||
int iface_index = 0, unicast_dest = 0, is_inform = 0, loopback = 0;
|
||||
int rcvd_iface_index;
|
||||
struct in_addr iface_addr;
|
||||
struct iface_param parm;
|
||||
@@ -223,9 +223,13 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
|
||||
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name) ||
|
||||
ioctl(daemon->dhcpfd, SIOCGIFFLAGS, &ifr) != 0)
|
||||
return;
|
||||
|
||||
|
||||
mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
|
||||
loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK);
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
/* ARP fiddling uses original interface even if we pretend to use a different one. */
|
||||
strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
|
||||
@@ -269,8 +273,8 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
if ((relay = relay_reply4((struct dhcp_packet *)daemon->dhcp_packet.iov_base, ifr.ifr_name)))
|
||||
{
|
||||
/* Reply from server, using us as relay. */
|
||||
iface_index = relay->iface_index;
|
||||
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
|
||||
rcvd_iface_index = relay->iface_index;
|
||||
if (!indextoname(daemon->dhcpfd, rcvd_iface_index, ifr.ifr_name))
|
||||
return;
|
||||
is_relay_reply = 1;
|
||||
iov.iov_len = sz;
|
||||
@@ -331,7 +335,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
|
||||
/* We're relaying this request */
|
||||
if (parm.relay_local.s_addr != 0 &&
|
||||
relay_upstream4(parm.relay, (struct dhcp_packet *)daemon->dhcp_packet.iov_base, (size_t)sz, iface_index))
|
||||
relay_upstream4(parm.relay, mess, (size_t)sz, iface_index))
|
||||
return;
|
||||
|
||||
/* May have configured relay, but not DHCP server */
|
||||
@@ -340,7 +344,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
|
||||
lease_prune(NULL, now); /* lose any expired leases */
|
||||
iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
|
||||
now, unicast_dest, &is_inform, pxe_fd, iface_addr, recvtime);
|
||||
now, unicast_dest, loopback, &is_inform, pxe_fd, iface_addr, recvtime);
|
||||
lease_update_file(now);
|
||||
lease_update_dns(0);
|
||||
|
||||
@@ -647,7 +651,7 @@ struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct i
|
||||
This wrapper handles a cache and load-limiting.
|
||||
Return is NULL is address in use, or a pointer to a cache entry
|
||||
recording that it isn't. */
|
||||
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int hash)
|
||||
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int hash, int loopback)
|
||||
{
|
||||
static struct ping_result dummy;
|
||||
struct ping_result *r, *victim = NULL;
|
||||
@@ -671,9 +675,9 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h
|
||||
}
|
||||
|
||||
/* didn't find cached entry */
|
||||
if ((count >= max) || option_bool(OPT_NO_PING))
|
||||
if ((count >= max) || option_bool(OPT_NO_PING) || loopback)
|
||||
{
|
||||
/* overloaded, or configured not to check, return "not in use" */
|
||||
/* overloaded, or configured not to check, loopback interface, return "not in use" */
|
||||
dummy.hash = 0;
|
||||
return &dummy;
|
||||
}
|
||||
@@ -705,7 +709,7 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h
|
||||
|
||||
int address_allocate(struct dhcp_context *context,
|
||||
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
|
||||
struct dhcp_netid *netids, time_t now)
|
||||
struct dhcp_netid *netids, time_t now, int loopback)
|
||||
{
|
||||
/* Find a free address: exclude anything in use and anything allocated to
|
||||
a particular hwaddr/clientid/hostname in our configuration.
|
||||
@@ -763,7 +767,7 @@ int address_allocate(struct dhcp_context *context,
|
||||
{
|
||||
struct ping_result *r;
|
||||
|
||||
if ((r = do_icmp_ping(now, addr, j)))
|
||||
if ((r = do_icmp_ping(now, addr, j, loopback)))
|
||||
{
|
||||
/* consec-ip mode: we offered this address for another client
|
||||
(different hash) recently, don't offer it to this one. */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -1375,7 +1375,7 @@ static void async_event(int pipe, time_t now)
|
||||
/* update timestamp file on TERM if time is considered valid */
|
||||
if (daemon->back_to_the_future)
|
||||
{
|
||||
if (utime(daemon->timestamp_file, NULL) == -1)
|
||||
if (utimes(daemon->timestamp_file, NULL) == -1)
|
||||
my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
+33
-25
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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,7 +14,13 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define COPYRIGHT "Copyright (c) 2000-2016 Simon Kelley"
|
||||
#define COPYRIGHT "Copyright (c) 2000-2017 Simon Kelley"
|
||||
|
||||
/* We do defines that influence behavior of stdio.h, so complain
|
||||
if included too early. */
|
||||
#ifdef _STDIO_H
|
||||
# error "Header file stdio.h included too early!"
|
||||
#endif
|
||||
|
||||
#ifndef NO_LARGEFILE
|
||||
/* Ensure we can use files >2GB (log files may grow this big) */
|
||||
@@ -117,7 +123,6 @@ typedef unsigned long long u64;
|
||||
#include <sys/uio.h>
|
||||
#include <syslog.h>
|
||||
#include <dirent.h>
|
||||
#include <utime.h>
|
||||
#ifndef HAVE_LINUX_NETWORK
|
||||
# include <net/if_dl.h>
|
||||
#endif
|
||||
@@ -1131,18 +1136,18 @@ unsigned int extract_request(struct dns_header *header, size_t qlen,
|
||||
char *name, unsigned short *typep);
|
||||
size_t setup_reply(struct dns_header *header, size_t qlen,
|
||||
struct all_addr *addrp, unsigned int flags,
|
||||
unsigned long local_ttl);
|
||||
int extract_addresses(struct dns_header *header, size_t qlen, char *namebuff,
|
||||
time_t now, char **ipsets, int is_sign, int checkrebind,
|
||||
int no_cache, int secure, int *doctored);
|
||||
unsigned long ttl);
|
||||
int extract_addresses(struct dns_header *header, size_t qlen, char *name,
|
||||
time_t now, char **ipsets, int is_sign, int check_rebind,
|
||||
int no_cache_dnssec, int secure, int *doctored);
|
||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
struct in_addr local_addr, struct in_addr local_netmask,
|
||||
time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
|
||||
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||
struct bogus_addr *addr, time_t now);
|
||||
struct bogus_addr *baddr, time_t now);
|
||||
int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
|
||||
int check_for_local_domain(char *name, time_t now);
|
||||
unsigned int questions_crc(struct dns_header *header, size_t plen, char *buff);
|
||||
unsigned int questions_crc(struct dns_header *header, size_t plen, char *name);
|
||||
size_t resize_packet(struct dns_header *header, size_t plen,
|
||||
unsigned char *pheader, size_t hlen);
|
||||
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
|
||||
@@ -1164,11 +1169,11 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
|
||||
|
||||
/* dnssec.c */
|
||||
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, union mysockaddr *addr, int edns_pktsz);
|
||||
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t n, char *name, char *keyname, int class);
|
||||
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
|
||||
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
|
||||
int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class,
|
||||
int check_unsigned, int *neganswer, int *nons);
|
||||
int dnskey_keytag(int alg, int flags, unsigned char *rdata, int rdlen);
|
||||
int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen);
|
||||
size_t filter_rrsigs(struct dns_header *header, size_t plen);
|
||||
unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
|
||||
int setup_timestamp(void);
|
||||
@@ -1178,9 +1183,9 @@ void rand_init(void);
|
||||
unsigned short rand16(void);
|
||||
u32 rand32(void);
|
||||
u64 rand64(void);
|
||||
int legal_hostname(char *c);
|
||||
char *canonicalise(char *s, int *nomem);
|
||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
||||
int legal_hostname(char *name);
|
||||
char *canonicalise(char *in, int *nomem);
|
||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
|
||||
void *safe_malloc(size_t size);
|
||||
void safe_pipe(int *fd, int read_noblock);
|
||||
void *whine_malloc(size_t size);
|
||||
@@ -1213,7 +1218,9 @@ int wildcard_matchn(const char* wildcard, const char* match, int num);
|
||||
void die(char *message, char *arg1, int exit_code);
|
||||
int log_start(struct passwd *ent_pw, int errfd);
|
||||
int log_reopen(char *log_file);
|
||||
|
||||
void my_syslog(int priority, const char *format, ...);
|
||||
|
||||
void set_log_writer(void);
|
||||
void check_log_writer(int force);
|
||||
void flush_log(void);
|
||||
@@ -1241,7 +1248,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force);
|
||||
int send_from(int fd, int nowild, char *packet, size_t len,
|
||||
union mysockaddr *to, struct all_addr *source,
|
||||
unsigned int iface);
|
||||
void resend_query();
|
||||
void resend_query(void);
|
||||
struct randfd *allocate_rfd(int family);
|
||||
void free_rfd(struct randfd *rfd);
|
||||
|
||||
@@ -1261,12 +1268,12 @@ void add_update_server(int flags,
|
||||
void check_servers(void);
|
||||
int enumerate_interfaces(int reset);
|
||||
void create_wildcard_listeners(void);
|
||||
void create_bound_listeners(int die);
|
||||
void create_bound_listeners(int dienow);
|
||||
void warn_bound_listeners(void);
|
||||
void warn_wild_labels(void);
|
||||
void warn_int_names(void);
|
||||
int is_dad_listeners(void);
|
||||
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
|
||||
int iface_check(int family, struct all_addr *addr, char *name, int *auth);
|
||||
int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
|
||||
int label_exception(int index, int family, struct all_addr *addr);
|
||||
int fix_fd(int fd);
|
||||
@@ -1287,16 +1294,16 @@ void newaddress(time_t now);
|
||||
void dhcp_init(void);
|
||||
void dhcp_packet(time_t now, int pxe_fd);
|
||||
struct dhcp_context *address_available(struct dhcp_context *context,
|
||||
struct in_addr addr,
|
||||
struct in_addr taddr,
|
||||
struct dhcp_netid *netids);
|
||||
struct dhcp_context *narrow_context(struct dhcp_context *context,
|
||||
struct in_addr taddr,
|
||||
struct dhcp_netid *netids);
|
||||
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr,
|
||||
unsigned int hash);
|
||||
unsigned int hash, int loopback);
|
||||
int address_allocate(struct dhcp_context *context,
|
||||
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
|
||||
struct dhcp_netid *netids, time_t now);
|
||||
struct dhcp_netid *netids, time_t now, int loopback);
|
||||
void dhcp_read_ethers(void);
|
||||
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
|
||||
char *host_from_dns(struct in_addr addr);
|
||||
@@ -1345,7 +1352,8 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
|
||||
/* rfc2131.c */
|
||||
#ifdef HAVE_DHCP
|
||||
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe_fd, struct in_addr fallback, time_t recvtime);
|
||||
size_t sz, time_t now, int unicast_dest, int loopback,
|
||||
int *is_inform, int pxe, struct in_addr fallback, time_t recvtime);
|
||||
unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
|
||||
int clid_len, unsigned char *clid, int *len_out);
|
||||
#endif
|
||||
@@ -1460,10 +1468,10 @@ unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arriva
|
||||
#ifdef HAVE_DHCP
|
||||
void dhcp_common_init(void);
|
||||
ssize_t recv_dhcp_packet(int fd, struct msghdr *msg);
|
||||
struct dhcp_netid *run_tag_if(struct dhcp_netid *input);
|
||||
struct dhcp_netid *run_tag_if(struct dhcp_netid *tags);
|
||||
struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *context_tags,
|
||||
struct dhcp_opt *opts);
|
||||
int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int negonly);
|
||||
int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int tagnotneeded);
|
||||
char *strip_hostname(char *hostname);
|
||||
void log_tags(struct dhcp_netid *netid, u32 xid);
|
||||
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
||||
@@ -1521,13 +1529,13 @@ void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *inte
|
||||
|
||||
/* loop.c */
|
||||
#ifdef HAVE_LOOP
|
||||
void loop_send_probes();
|
||||
void loop_send_probes(void);
|
||||
int detect_loop(char *query, int type);
|
||||
#endif
|
||||
|
||||
/* inotify.c */
|
||||
#ifdef HAVE_INOTIFY
|
||||
void inotify_dnsmasq_init();
|
||||
void inotify_dnsmasq_init(void);
|
||||
int inotify_check(time_t now);
|
||||
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
|
||||
#endif
|
||||
|
||||
+9
-7
@@ -1,5 +1,5 @@
|
||||
/* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
|
||||
and Copyright (c) 2012-2016 Simon Kelley
|
||||
and Copyright (c) 2012-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -475,7 +475,7 @@ int setup_timestamp(void)
|
||||
if (difftime(timestamp_time, time(0)) <= 0)
|
||||
{
|
||||
/* time already OK, update timestamp, and do key checking from the start. */
|
||||
if (utime(daemon->timestamp_file, NULL) == -1)
|
||||
if (utimes(daemon->timestamp_file, NULL) == -1)
|
||||
my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
|
||||
daemon->back_to_the_future = 1;
|
||||
return 0;
|
||||
@@ -489,12 +489,14 @@ int setup_timestamp(void)
|
||||
int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK | O_EXCL, 0666);
|
||||
if (fd != -1)
|
||||
{
|
||||
struct utimbuf timbuf;
|
||||
struct timeval tv[2];
|
||||
|
||||
close(fd);
|
||||
|
||||
timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
|
||||
if (utime(daemon->timestamp_file, &timbuf) == 0)
|
||||
timestamp_time = 1420070400; /* 1-1-2015 */
|
||||
tv[0].tv_sec = tv[1].tv_sec = timestamp_time;
|
||||
tv[0].tv_usec = tv[1].tv_usec = 0;
|
||||
if (utimes(daemon->timestamp_file, tv) == 0)
|
||||
goto check_and_exit;
|
||||
}
|
||||
}
|
||||
@@ -519,7 +521,7 @@ static int check_date_range(u32 date_start, u32 date_end)
|
||||
{
|
||||
if (daemon->back_to_the_future == 0 && difftime(timestamp_time, curtime) <= 0)
|
||||
{
|
||||
if (utime(daemon->timestamp_file, NULL) != 0)
|
||||
if (utimes(daemon->timestamp_file, NULL) != 0)
|
||||
my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
|
||||
|
||||
my_syslog(LOG_INFO, _("system time considered valid, now checking DNSSEC signature timestamps."));
|
||||
@@ -2228,7 +2230,7 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char
|
||||
|
||||
p = (unsigned char *)(header+1);
|
||||
|
||||
p = do_rfc1035_name(p, name);
|
||||
p = do_rfc1035_name(p, name, NULL);
|
||||
*p++ = 0;
|
||||
PUTSHORT(type, p);
|
||||
PUTSHORT(class, p);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+26
-6
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -144,7 +144,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
GETSHORT(len, p);
|
||||
|
||||
/* malformed option, delete the whole OPT RR and start again. */
|
||||
if (i + len > rdlen)
|
||||
if (i + 4 + len > rdlen)
|
||||
{
|
||||
rdlen = 0;
|
||||
is_last = 0;
|
||||
@@ -159,7 +159,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
/* delete option if we're to replace it. */
|
||||
p -= 4;
|
||||
rdlen -= len + 4;
|
||||
memcpy(p, p+len+4, rdlen - i);
|
||||
memmove(p, p+len+4, rdlen - i);
|
||||
PUTSHORT(rdlen, lenp);
|
||||
lenp -= 2;
|
||||
}
|
||||
@@ -192,7 +192,15 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
!(p = skip_section(p,
|
||||
ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
|
||||
header, plen)))
|
||||
{
|
||||
free(buff);
|
||||
return plen;
|
||||
}
|
||||
if (p + 11 > limit)
|
||||
{
|
||||
free(buff);
|
||||
return plen; /* Too big */
|
||||
}
|
||||
*p++ = 0; /* empty name */
|
||||
PUTSHORT(T_OPT, p);
|
||||
PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */
|
||||
@@ -204,11 +212,19 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
/* Copy back any options */
|
||||
if (buff)
|
||||
{
|
||||
if (p + rdlen > limit)
|
||||
{
|
||||
free(buff);
|
||||
return plen; /* Too big */
|
||||
}
|
||||
memcpy(p, buff, rdlen);
|
||||
free(buff);
|
||||
p += rdlen;
|
||||
}
|
||||
header->arcount = htons(ntohs(header->arcount) + 1);
|
||||
|
||||
/* Only bump arcount if RR is going to fit */
|
||||
if (((ssize_t)optlen) <= (limit - (p + 4)))
|
||||
header->arcount = htons(ntohs(header->arcount) + 1);
|
||||
}
|
||||
|
||||
if (((ssize_t)optlen) > (limit - (p + 4)))
|
||||
@@ -217,8 +233,12 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
/* Add new option */
|
||||
if (optno != 0 && replace != 2)
|
||||
{
|
||||
if (p + 4 > limit)
|
||||
return plen; /* Too big */
|
||||
PUTSHORT(optno, p);
|
||||
PUTSHORT(optlen, p);
|
||||
if (p + optlen > limit)
|
||||
return plen; /* Too big */
|
||||
memcpy(p, opt, optlen);
|
||||
p += optlen;
|
||||
PUTSHORT(p - datap, lenp);
|
||||
@@ -304,7 +324,7 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
|
||||
|
||||
int len;
|
||||
void *addrp;
|
||||
void *addrp = NULL;
|
||||
int sa_family = source->sa.sa_family;
|
||||
|
||||
opt->source_netmask = 0;
|
||||
@@ -344,7 +364,7 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
|
||||
len = 0;
|
||||
|
||||
if (opt->source_netmask != 0)
|
||||
if (addrp && opt->source_netmask != 0)
|
||||
{
|
||||
len = ((opt->source_netmask - 1) >> 3) + 1;
|
||||
memcpy(opt->addr, addrp, len);
|
||||
|
||||
+75
-66
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -120,8 +120,10 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
|
||||
unsigned int flags = 0;
|
||||
|
||||
for (serv = daemon->servers; serv; serv=serv->next)
|
||||
if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC))
|
||||
continue;
|
||||
/* domain matches take priority over NODOTS matches */
|
||||
if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
|
||||
else if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
|
||||
{
|
||||
unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
|
||||
*type = SERV_FOR_NODOTS;
|
||||
@@ -202,7 +204,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
|
||||
}
|
||||
}
|
||||
|
||||
if (flags == 0 && !(qtype & F_QUERY) &&
|
||||
if (flags == 0 && !(qtype & (F_QUERY | F_DNSSECOK)) &&
|
||||
option_bool(OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
|
||||
/* don't forward A or AAAA queries for simple names, except the empty name */
|
||||
flags = F_NOERR;
|
||||
@@ -788,7 +790,6 @@ void reply_query(int fd, int family, time_t now)
|
||||
/* Note: if we send extra options in the EDNS0 header, we can't recreate
|
||||
the query from the reply. */
|
||||
if (RCODE(header) == REFUSED &&
|
||||
!option_bool(OPT_ORDER) &&
|
||||
forward->forwardall == 0 &&
|
||||
!(forward->flags & FREC_HAS_EXTRADATA))
|
||||
/* for broken servers, attempt to send to another one. */
|
||||
@@ -877,10 +878,10 @@ void reply_query(int fd, int family, time_t now)
|
||||
return;
|
||||
|
||||
/* Truncated answer can't be validated.
|
||||
If this is an answer to a DNSSEC-generated query, we still
|
||||
need to get the client to retry over TCP, so return
|
||||
an answer with the TC bit set, even if the actual answer fits.
|
||||
*/
|
||||
If this is an answer to a DNSSEC-generated query, we still
|
||||
need to get the client to retry over TCP, so return
|
||||
an answer with the TC bit set, even if the actual answer fits.
|
||||
*/
|
||||
if (header->hb3 & HB3_TC)
|
||||
status = STAT_TRUNCATED;
|
||||
|
||||
@@ -897,7 +898,7 @@ void reply_query(int fd, int family, time_t now)
|
||||
status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
|
||||
else
|
||||
status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class,
|
||||
option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags && SERV_DO_DNSSEC), NULL, NULL);
|
||||
option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags & SERV_DO_DNSSEC), NULL, NULL);
|
||||
}
|
||||
|
||||
/* Can't validate, as we're missing key data. Put this
|
||||
@@ -933,37 +934,35 @@ void reply_query(int fd, int family, time_t now)
|
||||
/* Find server to forward to. This will normally be the
|
||||
same as for the original query, but may be another if
|
||||
servers for domains are involved. */
|
||||
if (search_servers(now, NULL, F_QUERY, daemon->keyname, &type, &domain, NULL) == 0)
|
||||
if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL) == 0)
|
||||
{
|
||||
struct server *start = server, *new_server = NULL;
|
||||
type &= ~SERV_DO_DNSSEC;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (type == (start->flags & SERV_TYPE) &&
|
||||
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
||||
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
||||
{
|
||||
new_server = start;
|
||||
if (server == start)
|
||||
{
|
||||
new_server = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(start = start->next))
|
||||
start = daemon->servers;
|
||||
if (start == server)
|
||||
break;
|
||||
}
|
||||
|
||||
if (new_server)
|
||||
server = new_server;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) &&
|
||||
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
||||
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
||||
{
|
||||
new_server = start;
|
||||
if (server == start)
|
||||
{
|
||||
new_server = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(start = start->next))
|
||||
start = daemon->servers;
|
||||
if (start == server)
|
||||
break;
|
||||
}
|
||||
|
||||
if (new_server)
|
||||
server = new_server;
|
||||
}
|
||||
|
||||
|
||||
new->sentto = server;
|
||||
|
||||
new->rfd4 = NULL;
|
||||
#ifdef HAVE_IPV6
|
||||
new->rfd6 = NULL;
|
||||
@@ -1189,6 +1188,10 @@ void receive_query(struct listener *listen, time_t now)
|
||||
(msg.msg_flags & MSG_TRUNC) ||
|
||||
(header->hb3 & HB3_QR))
|
||||
return;
|
||||
|
||||
/* Clear buffer beyond request to avoid risk of
|
||||
information disclosure. */
|
||||
memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
|
||||
|
||||
source_addr.sa.sa_family = listen->family;
|
||||
|
||||
@@ -1409,6 +1412,8 @@ void receive_query(struct listener *listen, time_t now)
|
||||
defaults to 512 */
|
||||
if (udp_size > daemon->edns_pktsz)
|
||||
udp_size = daemon->edns_pktsz;
|
||||
else if (udp_size < PACKETSZ)
|
||||
udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
|
||||
}
|
||||
|
||||
#ifdef HAVE_AUTH
|
||||
@@ -1477,7 +1482,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
||||
new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
|
||||
else
|
||||
new_status = dnssec_validate_reply(now, header, n, name, keyname, &class,
|
||||
option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags && SERV_DO_DNSSEC), NULL, NULL);
|
||||
option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags & SERV_DO_DNSSEC), NULL, NULL);
|
||||
|
||||
if (new_status != STAT_NEED_DS && new_status != STAT_NEED_KEY)
|
||||
break;
|
||||
@@ -1506,14 +1511,12 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
||||
/* Find server to forward to. This will normally be the
|
||||
same as for the original query, but may be another if
|
||||
servers for domains are involved. */
|
||||
if (search_servers(now, NULL, F_QUERY, keyname, &type, &domain, NULL) != 0)
|
||||
if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL) != 0)
|
||||
{
|
||||
new_status = STAT_ABANDONED;
|
||||
break;
|
||||
}
|
||||
|
||||
type &= ~SERV_DO_DNSSEC;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!firstsendto)
|
||||
@@ -1530,34 +1533,34 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
||||
}
|
||||
}
|
||||
|
||||
if (type != (server->flags & SERV_TYPE) ||
|
||||
if (type != (server->flags & (SERV_TYPE | SERV_DO_DNSSEC)) ||
|
||||
(type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
|
||||
(server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
||||
continue;
|
||||
|
||||
retry:
|
||||
/* may need to make new connection. */
|
||||
if (server->tcpfd == -1)
|
||||
{
|
||||
if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
|
||||
continue; /* No good, next server */
|
||||
|
||||
#ifdef HAVE_CONNTRACK
|
||||
/* Copy connection mark of incoming query to outgoing connection. */
|
||||
if (have_mark)
|
||||
setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
||||
#endif
|
||||
|
||||
if (!local_bind(server->tcpfd, &server->source_addr, server->interface, 1) ||
|
||||
connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
|
||||
{
|
||||
close(server->tcpfd);
|
||||
server->tcpfd = -1;
|
||||
|
||||
retry:
|
||||
/* may need to make new connection. */
|
||||
if (server->tcpfd == -1)
|
||||
{
|
||||
if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
|
||||
continue; /* No good, next server */
|
||||
}
|
||||
|
||||
server->flags &= ~SERV_GOT_TCP;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CONNTRACK
|
||||
/* Copy connection mark of incoming query to outgoing connection. */
|
||||
if (have_mark)
|
||||
setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
||||
#endif
|
||||
|
||||
if (!local_bind(server->tcpfd, &server->source_addr, server->interface, 1) ||
|
||||
connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
|
||||
{
|
||||
close(server->tcpfd);
|
||||
server->tcpfd = -1;
|
||||
continue; /* No good, next server */
|
||||
}
|
||||
|
||||
server->flags &= ~SERV_GOT_TCP;
|
||||
}
|
||||
|
||||
if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
|
||||
!read_write(server->tcpfd, &c1, 1, 1) ||
|
||||
@@ -1691,6 +1694,10 @@ unsigned char *tcp_request(int confd, time_t now,
|
||||
|
||||
if (size < (int)sizeof(struct dns_header))
|
||||
continue;
|
||||
|
||||
/* Clear buffer beyond request to avoid risk of
|
||||
information disclosure. */
|
||||
memset(payload + size, 0, 65536 - size);
|
||||
|
||||
query_count++;
|
||||
|
||||
@@ -2080,6 +2087,8 @@ static void free_frec(struct frec *f)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* if wait==NULL return a free or older than TIMEOUT record.
|
||||
else return *wait zero if one available, or *wait is delay to
|
||||
when the oldest in-use record will expire. Impose an absolute
|
||||
@@ -2126,7 +2135,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force)
|
||||
|
||||
/* can't find empty one, use oldest if there is one
|
||||
and it's older than timeout */
|
||||
if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
|
||||
if (!force && oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
|
||||
{
|
||||
/* keep stuff for twice timeout if we can by allocating a new
|
||||
record instead */
|
||||
@@ -2166,7 +2175,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force)
|
||||
|
||||
return f; /* OK if malloc fails and this is NULL */
|
||||
}
|
||||
|
||||
|
||||
/* crc is all-ones if not known. */
|
||||
static struct frec *lookup_frec(unsigned short id, void *hash)
|
||||
{
|
||||
|
||||
+1
-2
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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,7 +14,6 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifdef HAVE_SCRIPT
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+3
-10
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -133,7 +133,6 @@ static int read_leases(time_t now, FILE *leasestream)
|
||||
void lease_init(time_t now)
|
||||
{
|
||||
FILE *leasestream;
|
||||
int readok = 0;
|
||||
|
||||
leases_left = daemon->dhcp_max;
|
||||
|
||||
@@ -172,7 +171,7 @@ void lease_init(time_t now)
|
||||
|
||||
if (leasestream)
|
||||
{
|
||||
if (!(readok = read_leases(now, leasestream)))
|
||||
if (!read_leases(now, leasestream))
|
||||
my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database, invalid line: %s %s %s %s ..."),
|
||||
daemon->dhcp_buff3, daemon->dhcp_buff2,
|
||||
daemon->namebuff, daemon->dhcp_buff);
|
||||
@@ -202,12 +201,6 @@ void lease_init(time_t now)
|
||||
sprintf(daemon->dhcp_buff, "%d", WEXITSTATUS(rc));
|
||||
die(_("lease-init script returned exit code %s"), daemon->dhcp_buff, WEXITSTATUS(rc) + EC_INIT_OFFSET);
|
||||
}
|
||||
|
||||
/* Only die if we stopped reading due to a non-parsed line when running script,
|
||||
this is expected behaviour when reading from a file, if the file was written with IPv6 data
|
||||
and we are not compiled to understand that. */
|
||||
if (!readok)
|
||||
die(_("failed to read lease-init script output"), NULL, EC_FILE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -236,7 +229,7 @@ void lease_update_from_configs(void)
|
||||
else if ((name = host_from_dns(lease->addr)))
|
||||
lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */
|
||||
}
|
||||
|
||||
|
||||
static void ourprintf(int *errp, char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+7
-4
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -882,7 +882,7 @@ static struct server *add_rev4(struct in_addr addr, int msize)
|
||||
switch (msize)
|
||||
{
|
||||
case 32:
|
||||
p += sprintf(p, "%d.", a & 0xff);
|
||||
p += sprintf(p, "%u.", a & 0xff);
|
||||
/* fall through */
|
||||
case 24:
|
||||
p += sprintf(p, "%d.", (a >> 8) & 0xff);
|
||||
@@ -1415,7 +1415,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
|
||||
}
|
||||
|
||||
p = newp;
|
||||
end = do_rfc1035_name(p + len, dom);
|
||||
end = do_rfc1035_name(p + len, dom, NULL);
|
||||
*end++ = 0;
|
||||
len = end - p;
|
||||
free(dom);
|
||||
@@ -3848,9 +3848,12 @@ err:
|
||||
while (arg != last)
|
||||
{
|
||||
alias = canonicalise_opt(arg);
|
||||
|
||||
if (!alias || !target)
|
||||
ret_err(_("bad CNAME"));
|
||||
|
||||
for (new = daemon->cnames; new; new = new->next)
|
||||
if (hostname_isequal(new->alias, arg))
|
||||
if (hostname_isequal(new->alias, alias))
|
||||
ret_err(_("duplicate CNAME"));
|
||||
new = opt_malloc(sizeof(struct cname));
|
||||
new->next = daemon->cnames;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -198,6 +198,9 @@ void icmp6_packet(time_t now)
|
||||
/* look for link-layer address option for logging */
|
||||
if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz)
|
||||
{
|
||||
if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) {
|
||||
return;
|
||||
}
|
||||
print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2);
|
||||
mac = daemon->namebuff;
|
||||
}
|
||||
|
||||
+50
-18
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -37,7 +37,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
||||
/* end marker */
|
||||
{
|
||||
/* check that there are the correct no of bytes after the name */
|
||||
if (!CHECK_LEN(header, p, plen, extrabytes))
|
||||
if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
|
||||
return 0;
|
||||
|
||||
if (isExtract)
|
||||
@@ -498,6 +498,8 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *
|
||||
{
|
||||
unsigned int i, len = *p1;
|
||||
unsigned char *p2 = p1;
|
||||
if ((p1 + len - p) >= rdlen)
|
||||
return 0; /* bad packet */
|
||||
/* make counted string zero-term and sanitise */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
@@ -1062,6 +1064,7 @@ int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bog
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
|
||||
unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
|
||||
{
|
||||
@@ -1071,29 +1074,47 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
|
||||
unsigned short usval;
|
||||
long lval;
|
||||
char *sval;
|
||||
#define CHECK_LIMIT(size) \
|
||||
if (limit && p + (size) > (unsigned char*)limit) \
|
||||
{ \
|
||||
va_end(ap); \
|
||||
goto truncated; \
|
||||
}
|
||||
|
||||
if (truncp && *truncp)
|
||||
return 0;
|
||||
|
||||
|
||||
va_start(ap, format); /* make ap point to 1st unamed argument */
|
||||
|
||||
|
||||
if (nameoffset > 0)
|
||||
{
|
||||
CHECK_LIMIT(2);
|
||||
PUTSHORT(nameoffset | 0xc000, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *name = va_arg(ap, char *);
|
||||
if (name)
|
||||
p = do_rfc1035_name(p, name);
|
||||
if (name && !(p = do_rfc1035_name(p, name, limit)))
|
||||
{
|
||||
va_end(ap);
|
||||
goto truncated;
|
||||
}
|
||||
|
||||
if (nameoffset < 0)
|
||||
{
|
||||
CHECK_LIMIT(2);
|
||||
PUTSHORT(-nameoffset | 0xc000, p);
|
||||
}
|
||||
else
|
||||
*p++ = 0;
|
||||
{
|
||||
CHECK_LIMIT(1);
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* type (2) + class (2) + ttl (4) + rdlen (2) */
|
||||
CHECK_LIMIT(10);
|
||||
|
||||
PUTSHORT(type, p);
|
||||
PUTSHORT(class, p);
|
||||
PUTLONG(ttl, p); /* TTL */
|
||||
@@ -1106,6 +1127,7 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
case '6':
|
||||
CHECK_LIMIT(IN6ADDRSZ);
|
||||
sval = va_arg(ap, char *);
|
||||
memcpy(p, sval, IN6ADDRSZ);
|
||||
p += IN6ADDRSZ;
|
||||
@@ -1113,36 +1135,47 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
|
||||
#endif
|
||||
|
||||
case '4':
|
||||
CHECK_LIMIT(INADDRSZ);
|
||||
sval = va_arg(ap, char *);
|
||||
memcpy(p, sval, INADDRSZ);
|
||||
p += INADDRSZ;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
CHECK_LIMIT(1);
|
||||
usval = va_arg(ap, int);
|
||||
*p++ = usval;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
CHECK_LIMIT(2);
|
||||
usval = va_arg(ap, int);
|
||||
PUTSHORT(usval, p);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
CHECK_LIMIT(4);
|
||||
lval = va_arg(ap, long);
|
||||
PUTLONG(lval, p);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
/* get domain-name answer arg and store it in RDATA field */
|
||||
if (offset)
|
||||
*offset = p - (unsigned char *)header;
|
||||
p = do_rfc1035_name(p, va_arg(ap, char *));
|
||||
*p++ = 0;
|
||||
/* get domain-name answer arg and store it in RDATA field */
|
||||
if (offset)
|
||||
*offset = p - (unsigned char *)header;
|
||||
p = do_rfc1035_name(p, va_arg(ap, char *), limit);
|
||||
if (!p)
|
||||
{
|
||||
va_end(ap);
|
||||
goto truncated;
|
||||
}
|
||||
CHECK_LIMIT(1);
|
||||
*p++ = 0;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
usval = va_arg(ap, int);
|
||||
CHECK_LIMIT(usval);
|
||||
sval = va_arg(ap, char *);
|
||||
if (usval != 0)
|
||||
memcpy(p, sval, usval);
|
||||
@@ -1154,20 +1187,24 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
|
||||
usval = sval ? strlen(sval) : 0;
|
||||
if (usval > 255)
|
||||
usval = 255;
|
||||
CHECK_LIMIT(usval + 1);
|
||||
*p++ = (unsigned char)usval;
|
||||
memcpy(p, sval, usval);
|
||||
p += usval;
|
||||
break;
|
||||
}
|
||||
|
||||
#undef CHECK_LIMIT
|
||||
va_end(ap); /* clean up variable argument pointer */
|
||||
|
||||
j = p - sav - 2;
|
||||
PUTSHORT(j, sav); /* Now, store real RDLength */
|
||||
/* this has already been checked against limit before */
|
||||
PUTSHORT(j, sav); /* Now, store real RDLength */
|
||||
|
||||
/* check for overflow of buffer */
|
||||
if (limit && ((unsigned char *)limit - p) < 0)
|
||||
{
|
||||
truncated:
|
||||
if (truncp)
|
||||
*truncp = 1;
|
||||
return 0;
|
||||
@@ -1223,11 +1260,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
struct mx_srv_record *rec;
|
||||
size_t len;
|
||||
|
||||
/* Clear buffer beyond request to avoid risk of
|
||||
information disclosure. */
|
||||
memset(((char *)header) + qlen, 0,
|
||||
(limit - ((char *)header)) - qlen);
|
||||
|
||||
if (ntohs(header->ancount) != 0 ||
|
||||
ntohs(header->nscount) != 0 ||
|
||||
ntohs(header->qdcount) == 0 ||
|
||||
|
||||
+28
-19
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -32,7 +32,7 @@ static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, in
|
||||
static void option_put_string(struct dhcp_packet *mess, unsigned char *end,
|
||||
int opt, char *string, int null_term);
|
||||
static struct in_addr option_addr(unsigned char *opt);
|
||||
static unsigned int option_uint(unsigned char *opt, int i, int size);
|
||||
static unsigned int option_uint(unsigned char *opt, int offset, int size);
|
||||
static void log_packet(char *type, void *addr, unsigned char *ext_mac,
|
||||
int mac_len, char *interface, char *string, char *err, u32 xid);
|
||||
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
|
||||
@@ -42,14 +42,14 @@ static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
|
||||
static int in_list(unsigned char *list, int opt);
|
||||
static void do_options(struct dhcp_context *context,
|
||||
struct dhcp_packet *mess,
|
||||
unsigned char *real_end,
|
||||
unsigned char *end,
|
||||
unsigned char *req_options,
|
||||
char *hostname,
|
||||
char *config_domain,
|
||||
char *domain,
|
||||
struct dhcp_netid *netid,
|
||||
struct in_addr subnet_addr,
|
||||
unsigned char fqdn_flags,
|
||||
int null_term, int pxearch,
|
||||
int null_term, int pxe_arch,
|
||||
unsigned char *uuid,
|
||||
int vendor_class_len,
|
||||
time_t now,
|
||||
@@ -58,7 +58,7 @@ static void do_options(struct dhcp_context *context,
|
||||
|
||||
|
||||
static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
|
||||
static int do_encap_opts(struct dhcp_opt *opts, int encap, int flag, struct dhcp_packet *mess, unsigned char *end, int null_term);
|
||||
static int do_encap_opts(struct dhcp_opt *opt, int encap, int flag, struct dhcp_packet *mess, unsigned char *end, int null_term);
|
||||
static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid);
|
||||
static int prune_vendor_opts(struct dhcp_netid *netid);
|
||||
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
|
||||
@@ -67,7 +67,8 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh
|
||||
static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid);
|
||||
|
||||
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe, struct in_addr fallback, time_t recvtime)
|
||||
size_t sz, time_t now, int unicast_dest, int loopback,
|
||||
int *is_inform, int pxe, struct in_addr fallback, time_t recvtime)
|
||||
{
|
||||
unsigned char *opt, *clid = NULL;
|
||||
struct dhcp_lease *ltmp, *lease = NULL;
|
||||
@@ -156,7 +157,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
for (offset = 0; offset < (len - 5); offset += elen + 5)
|
||||
{
|
||||
elen = option_uint(opt, offset + 4 , 1);
|
||||
if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA)
|
||||
if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA && offset + elen + 5 <= len)
|
||||
{
|
||||
unsigned char *x = option_ptr(opt, offset + 5);
|
||||
unsigned char *y = option_ptr(opt, offset + elen + 5);
|
||||
@@ -382,7 +383,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
{
|
||||
len = option_uint(opt, offset + 4 , 1);
|
||||
/* Need to take care that bad data can't run us off the end of the packet */
|
||||
if ((offset + len + 5 <= (option_len(opt))) &&
|
||||
if ((offset + len + 5 <= (unsigned)(option_len(opt))) &&
|
||||
(option_uint(opt, offset, 4) == (unsigned int)o->u.encap))
|
||||
for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1)
|
||||
{
|
||||
@@ -487,6 +488,13 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
known_id.next = netid;
|
||||
netid = &known_id;
|
||||
}
|
||||
else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len,
|
||||
mess->chaddr, mess->hlen, mess->htype, NULL))
|
||||
{
|
||||
known_id.net = "known-othernet";
|
||||
known_id.next = netid;
|
||||
netid = &known_id;
|
||||
}
|
||||
|
||||
if (mess_type == 0 && !pxe)
|
||||
{
|
||||
@@ -568,7 +576,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
lease_prune(lease, now);
|
||||
lease = NULL;
|
||||
}
|
||||
if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, tagif_netid, now))
|
||||
if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, tagif_netid, now, loopback))
|
||||
message = _("no address available");
|
||||
}
|
||||
else
|
||||
@@ -826,9 +834,12 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
else
|
||||
mess->siaddr = context->local;
|
||||
|
||||
snprintf((char *)mess->file, sizeof(mess->file),
|
||||
strchr(service->basename, '.') ? "%s" :"%s.%d",
|
||||
service->basename, layer);
|
||||
if (strchr(service->basename, '.'))
|
||||
snprintf((char *)mess->file, sizeof(mess->file),
|
||||
"%s", service->basename);
|
||||
else
|
||||
snprintf((char *)mess->file, sizeof(mess->file),
|
||||
"%s.%d", service->basename, layer);
|
||||
|
||||
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
|
||||
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
|
||||
@@ -1029,8 +1040,6 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
else if (have_config(config, CONFIG_DECLINED) &&
|
||||
difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
|
||||
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
|
||||
else if (!do_icmp_ping(now, config->addr, 0))
|
||||
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by another host"), addrs);
|
||||
else
|
||||
conf = config->addr;
|
||||
}
|
||||
@@ -1043,11 +1052,11 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
!config_find_by_address(daemon->dhcp_conf, lease->addr))
|
||||
mess->yiaddr = lease->addr;
|
||||
else if (opt && address_available(context, addr, tagif_netid) && !lease_find_by_addr(addr) &&
|
||||
!config_find_by_address(daemon->dhcp_conf, addr) && do_icmp_ping(now, addr, 0))
|
||||
!config_find_by_address(daemon->dhcp_conf, addr) && do_icmp_ping(now, addr, 0, loopback))
|
||||
mess->yiaddr = addr;
|
||||
else if (emac_len == 0)
|
||||
message = _("no unique-id");
|
||||
else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now))
|
||||
else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now, loopback))
|
||||
message = _("no address available");
|
||||
}
|
||||
|
||||
@@ -2443,10 +2452,10 @@ static void do_options(struct dhcp_context *context,
|
||||
|
||||
if (fqdn_flags & 0x04)
|
||||
{
|
||||
p = do_rfc1035_name(p, hostname);
|
||||
p = do_rfc1035_name(p, hostname, NULL);
|
||||
if (domain)
|
||||
{
|
||||
p = do_rfc1035_name(p, domain);
|
||||
p = do_rfc1035_name(p, domain, NULL);
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-4
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -206,6 +206,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
|
||||
/* RFC-6939 */
|
||||
if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3)))
|
||||
{
|
||||
if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) {
|
||||
return 0;
|
||||
}
|
||||
state->mac_type = opt6_uint(opt, 0, 2);
|
||||
state->mac_len = opt6_len(opt) - 2;
|
||||
memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len);
|
||||
@@ -213,6 +216,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
|
||||
|
||||
for (opt = opts; opt; opt = opt6_next(opt, end))
|
||||
{
|
||||
if (opt6_ptr(opt, 0) + opt6_len(opt) >= end) {
|
||||
return 0;
|
||||
}
|
||||
int o = new_opt6(opt6_type(opt));
|
||||
if (opt6_type(opt) == OPTION6_RELAY_MSG)
|
||||
{
|
||||
@@ -526,7 +532,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||
if (have_config(config, CONFIG_DISABLE))
|
||||
ignore = 1;
|
||||
}
|
||||
|
||||
else if (state->clid &&
|
||||
find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL))
|
||||
{
|
||||
known_id.net = "known-othernet";
|
||||
known_id.next = state->tags;
|
||||
state->tags = &known_id;
|
||||
}
|
||||
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
/* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
|
||||
if (daemon->prefix_classes && (msg_type == DHCP6SOLICIT || msg_type == DHCP6REQUEST))
|
||||
@@ -1472,10 +1485,10 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
|
||||
if ((p = expand(len + 2)))
|
||||
{
|
||||
*(p++) = state->fqdn_flags;
|
||||
p = do_rfc1035_name(p, state->hostname);
|
||||
p = do_rfc1035_name(p, state->hostname, NULL);
|
||||
if (state->send_domain)
|
||||
{
|
||||
p = do_rfc1035_name(p, state->send_domain);
|
||||
p = do_rfc1035_name(p, state->send_domain, NULL);
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix);
|
||||
static void free_transfer(struct tftp_transfer *transfer);
|
||||
static ssize_t tftp_err(int err, char *packet, char *mess, char *file);
|
||||
static ssize_t tftp_err(int err, char *packet, char *message, char *file);
|
||||
static ssize_t tftp_err_oops(char *packet, char *file);
|
||||
static ssize_t get_block(char *packet, struct tftp_transfer *transfer);
|
||||
static char *next(char **p, char *end);
|
||||
@@ -734,7 +734,7 @@ static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
|
||||
if (transfer->opt_blocksize)
|
||||
{
|
||||
p += (sprintf(p, "blksize") + 1);
|
||||
p += (sprintf(p, "%d", transfer->blocksize) + 1);
|
||||
p += (sprintf(p, "%u", transfer->blocksize) + 1);
|
||||
}
|
||||
if (transfer->opt_transize)
|
||||
{
|
||||
|
||||
+55
-27
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -24,7 +24,9 @@
|
||||
#include <sys/times.h>
|
||||
#endif
|
||||
|
||||
#if defined(LOCALEDIR) || defined(HAVE_IDN)
|
||||
#if defined(HAVE_LIBIDN2)
|
||||
#include <idn2.h>
|
||||
#elif defined(HAVE_IDN)
|
||||
#include <idna.h>
|
||||
#endif
|
||||
|
||||
@@ -109,6 +111,7 @@ u64 rand64(void)
|
||||
return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
|
||||
}
|
||||
|
||||
/* returns 2 if names is OK but contains one or more underscores */
|
||||
static int check_name(char *in)
|
||||
{
|
||||
/* remove trailing .
|
||||
@@ -116,6 +119,7 @@ static int check_name(char *in)
|
||||
size_t dotgap = 0, l = strlen(in);
|
||||
char c;
|
||||
int nowhite = 0;
|
||||
int hasuscore = 0;
|
||||
|
||||
if (l == 0 || l > MAXDNAME) return 0;
|
||||
|
||||
@@ -134,18 +138,22 @@ static int check_name(char *in)
|
||||
else if (isascii((unsigned char)c) && iscntrl((unsigned char)c))
|
||||
/* iscntrl only gives expected results for ascii */
|
||||
return 0;
|
||||
#if !defined(LOCALEDIR) && !defined(HAVE_IDN)
|
||||
#if !defined(HAVE_IDN) && !defined(HAVE_LIBIDN2)
|
||||
else if (!isascii((unsigned char)c))
|
||||
return 0;
|
||||
#endif
|
||||
else if (c != ' ')
|
||||
nowhite = 1;
|
||||
{
|
||||
nowhite = 1;
|
||||
if (c == '_')
|
||||
hasuscore = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nowhite)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return hasuscore ? 2 : 1;
|
||||
}
|
||||
|
||||
/* Hostnames have a more limited valid charset than domain names
|
||||
@@ -184,49 +192,68 @@ int legal_hostname(char *name)
|
||||
char *canonicalise(char *in, int *nomem)
|
||||
{
|
||||
char *ret = NULL;
|
||||
#if defined(LOCALEDIR) || defined(HAVE_IDN)
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
|
||||
if (nomem)
|
||||
*nomem = 0;
|
||||
|
||||
if (!check_name(in))
|
||||
if (!(rc = check_name(in)))
|
||||
return NULL;
|
||||
|
||||
#if defined(LOCALEDIR) || defined(HAVE_IDN)
|
||||
if ((rc = idna_to_ascii_lz(in, &ret, 0)) != IDNA_SUCCESS)
|
||||
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
|
||||
/* older libidn2 strips underscores, so don't do IDN processing
|
||||
if the name has an underscore (check_name() returned 2) */
|
||||
if (rc != 2)
|
||||
#endif
|
||||
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
|
||||
{
|
||||
if (ret)
|
||||
free(ret);
|
||||
|
||||
if (nomem && (rc == IDNA_MALLOC_ERROR || rc == IDNA_DLOPEN_ERROR))
|
||||
# ifdef HAVE_LIBIDN2
|
||||
rc = idn2_to_ascii_lz(in, &ret, IDN2_NONTRANSITIONAL);
|
||||
if (rc == IDN2_DISALLOWED)
|
||||
rc = idn2_to_ascii_lz(in, &ret, IDN2_TRANSITIONAL);
|
||||
# else
|
||||
rc = idna_to_ascii_lz(in, &ret, 0);
|
||||
# endif
|
||||
if (rc != IDNA_SUCCESS)
|
||||
{
|
||||
my_syslog(LOG_ERR, _("failed to allocate memory"));
|
||||
*nomem = 1;
|
||||
if (ret)
|
||||
free(ret);
|
||||
|
||||
if (nomem && (rc == IDNA_MALLOC_ERROR || rc == IDNA_DLOPEN_ERROR))
|
||||
{
|
||||
my_syslog(LOG_ERR, _("failed to allocate memory"));
|
||||
*nomem = 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
|
||||
if ((ret = whine_malloc(strlen(in)+1)))
|
||||
strcpy(ret, in);
|
||||
else if (nomem)
|
||||
*nomem = 1;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
|
||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
|
||||
{
|
||||
int j;
|
||||
|
||||
while (sval && *sval)
|
||||
{
|
||||
if (limit && p + 1 > (unsigned char*)limit)
|
||||
return p;
|
||||
|
||||
unsigned char *cp = p++;
|
||||
for (j = 0; *sval && (*sval != '.'); sval++, j++)
|
||||
{
|
||||
if (limit && p + 1 > (unsigned char*)limit)
|
||||
return p;
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE)
|
||||
*p++ = (*(++sval))-1;
|
||||
@@ -439,13 +466,13 @@ void prettyprint_time(char *buf, unsigned int t)
|
||||
{
|
||||
unsigned int x, p = 0;
|
||||
if ((x = t/86400))
|
||||
p += sprintf(&buf[p], "%dd", x);
|
||||
p += sprintf(&buf[p], "%ud", x);
|
||||
if ((x = (t/3600)%24))
|
||||
p += sprintf(&buf[p], "%dh", x);
|
||||
p += sprintf(&buf[p], "%uh", x);
|
||||
if ((x = (t/60)%60))
|
||||
p += sprintf(&buf[p], "%dm", x);
|
||||
p += sprintf(&buf[p], "%um", x);
|
||||
if ((x = t%60))
|
||||
p += sprintf(&buf[p], "%ds", x);
|
||||
p += sprintf(&buf[p], "%us", x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,7 +530,8 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
|
||||
return -1;
|
||||
out[i] = strtol(&in[j*2], NULL, 16);
|
||||
mask = mask << 1;
|
||||
i++;
|
||||
if (++i == maxlen)
|
||||
break;
|
||||
if (j < bytes - 1)
|
||||
in[(j+1)*2] = sav;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user