import dnsmasq-2.79-13.el8

This commit is contained in:
CentOS Sources 2020-06-09 19:23:34 +00:00 committed by Andrew Lukoshko
commit 817be80490
25 changed files with 4986 additions and 0 deletions

1
.dnsmasq.metadata Normal file
View File

@ -0,0 +1 @@
d4a1af08b02b27736954ce8b2db2da7799d75812 SOURCES/dnsmasq-2.79.tar.xz

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/dnsmasq-2.79.tar.xz

View File

@ -0,0 +1,52 @@
From cae343c1f3bea9d1ca2e71d3709d3f02b799f94d Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Thu, 4 Jul 2019 20:28:08 +0200
Subject: [PATCH 1/5] Log listening on new interfaces
Log in debug mode listening on interfaces. They can be dynamically
found, include interface number, since it is checked on TCP connections.
Print also addresses found on them.
---
src/network.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/network.c b/src/network.c
index d75f560..fd90288 100644
--- a/src/network.c
+++ b/src/network.c
@@ -662,6 +662,13 @@ int enumerate_interfaces(int reset)
else
{
*up = l->next;
+ if (l->iface->done)
+ {
+ iface = l->iface;
+ (void)prettyprint_addr(&iface->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s"),
+ iface->name, iface->index, daemon->addrbuff);
+ }
/* In case it ever returns */
l->iface->done = 0;
@@ -978,6 +985,9 @@ void create_bound_listeners(int dienow)
new->next = daemon->listeners;
daemon->listeners = new;
iface->done = 1;
+ (void)prettyprint_addr(&iface->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s"),
+ iface->name, iface->index, daemon->addrbuff);
}
/* Check for --listen-address options that haven't been used because there's
@@ -997,6 +1007,8 @@ void create_bound_listeners(int dienow)
{
new->next = daemon->listeners;
daemon->listeners = new;
+ (void)prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("listening on %s"), daemon->addrbuff);
}
}
--
2.20.1

View File

@ -0,0 +1,74 @@
From 527029312cbe37c0285240943ad02352d64d403d Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 9 Jul 2019 14:05:59 +0200
Subject: [PATCH 3/5] Cleanup interfaces no longer available
Clean addresses and interfaces not found after enumerate. Free unused
records to speed up checking active interfaces and reduce used memory.
---
src/network.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/network.c b/src/network.c
index f247811..d6d4b01 100644
--- a/src/network.c
+++ b/src/network.c
@@ -553,7 +553,30 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
}
-
+
+/*
+ * Clean old interfaces no longer found.
+ */
+static void clean_interfaces()
+{
+ struct irec *iface;
+ struct irec **up = &daemon->interfaces;
+
+ for (iface = *up; iface; iface = *up)
+ {
+ if (!iface->found && !iface->done)
+ {
+ *up = iface->next;
+ free(iface->name);
+ free(iface);
+ }
+ else
+ {
+ up = &iface->next;
+ }
+ }
+}
+
int enumerate_interfaces(int reset)
{
static struct addrlist *spare = NULL;
@@ -653,6 +676,7 @@ int enumerate_interfaces(int reset)
in OPT_CLEVERBIND mode, that at listener will just disappear after
a call to enumerate_interfaces, this is checked OK on all calls. */
struct listener *l, *tmp, **up;
+ int freed = 0;
for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
{
@@ -682,10 +706,14 @@ int enumerate_interfaces(int reset)
close(l->tftpfd);
free(l);
+ freed = 1;
}
}
+
+ if (freed)
+ clean_interfaces();
}
-
+
errno = errsave;
spare = param.spare;
--
2.20.1

View File

@ -0,0 +1,75 @@
From 3d27384fc5f2a437b7bce128c8ba62e8d6e12df7 Mon Sep 17 00:00:00 2001
From: Brian Haley <haleyb.dev@gmail.com>
Date: Wed, 28 Aug 2019 16:13:23 -0400
Subject: [PATCH] Change dhcp_release to use default address when no IP subnet
matches
Currently, dhcp_release will only send a 'fake' release
when the address given is in the same subnet as an IP
on the interface that was given.
This doesn't work in an environment where dnsmasq is
managing leases for remote subnets via a DHCP relay, as
running dhcp_release locally will just cause it to
silently exit without doing anything, leaving the lease
in the database.
Change it to use the default IP on the interface, as the
dnsmasq source code at src/dhcp.c does, if no matching subnet
IP is found, as a fall-back. This fixes an issue we are
seeing in certain Openstack deployments where we are using
dnsmasq to provision baremetal systems in a datacenter.
While using Dbus might have seemed like an obvious solution,
because of our extensive use of network namespaces (which
Dbus doesn't support), this seemed like a better solution
than creating system.d policy files for each dnsmasq we
might spawn and using --enable-dbus=$id in order to isolate
messages to specific dnsmasq instances.
Signed-off-by: Brian Haley <haleyb.dev@gmail.com>
(cherry picked from commit d9f882bea2806799bf3d1f73937f5e72d0bfc650)
---
contrib/lease-tools/dhcp_release.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
index a51f04b..1dd8d32 100644
--- a/contrib/lease-tools/dhcp_release.c
+++ b/contrib/lease-tools/dhcp_release.c
@@ -178,7 +178,7 @@ static int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
}
-static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index)
+static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index, int ifrfd, struct ifreq *ifr)
{
struct sockaddr_nl addr;
struct nlmsghdr *h;
@@ -218,7 +218,13 @@ static struct in_addr find_interface(struct in_addr client, int fd, unsigned int
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
if (h->nlmsg_type == NLMSG_DONE)
- exit(0);
+ {
+ /* No match found, return first address as src/dhcp.c code does */
+ ifr->ifr_addr.sa_family = AF_INET;
+ if (ioctl(ifrfd, SIOCGIFADDR, ifr) != -1)
+ return ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
+ exit(0);
+ }
else if (h->nlmsg_type == RTM_NEWADDR)
{
struct ifaddrmsg *ifa = NLMSG_DATA(h);
@@ -284,7 +290,7 @@ int main(int argc, char **argv)
}
lease.s_addr = inet_addr(argv[2]);
- server = find_interface(lease, nl, if_nametoindex(argv[1]));
+ server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr);
memset(&packet, 0, sizeof(packet));
--
2.20.1

View File

@ -0,0 +1,63 @@
From c82a594d95431e8615126621397ea595eb037a6b Mon Sep 17 00:00:00 2001
From: Doran Moppert <dmoppert@redhat.com>
Date: Tue, 26 Sep 2017 14:48:20 +0930
Subject: [PATCH] google patch hand-applied
---
src/edns0.c | 10 +++++-----
src/forward.c | 4 ++++
src/rfc1035.c | 2 ++
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/edns0.c b/src/edns0.c
index af33877..ba6ff0c 100644
--- a/src/edns0.c
+++ b/src/edns0.c
@@ -212,11 +212,11 @@ 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 */
- }
+ if (p + rdlen > limit)
+ {
+ free(buff);
+ return plen; /* Too big */
+ }
memcpy(p, buff, rdlen);
free(buff);
p += rdlen;
diff --git a/src/forward.c b/src/forward.c
index cdd11d3..3078f64 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -1438,6 +1438,10 @@ void receive_query(struct listener *listen, time_t now)
udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
}
+ // Make sure the udp size is not smaller than the incoming message so that we
+ // do not underflow
+ if (udp_size < n) udp_size = n;
+
#ifdef HAVE_AUTH
if (auth_dns)
{
diff --git a/src/rfc1035.c b/src/rfc1035.c
index b078b59..777911b 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1281,6 +1281,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
struct mx_srv_record *rec;
size_t len;
+ // Make sure we do not underflow here too.
+ if (qlen > (limit - ((char *)header))) return 0;
if (ntohs(header->ancount) != 0 ||
ntohs(header->nscount) != 0 ||
--
2.14.3

View File

@ -0,0 +1,37 @@
From 89f57e39b69f92beacb6bad9c68d61f9c4fb0e77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Fri, 2 Mar 2018 13:17:04 +0100
Subject: [PATCH] Print warning on FIPS machine with dnssec enabled. Dnsmasq
has no proper FIPS 140-2 compliant implementation.
---
src/dnsmasq.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index ce44809..9f6c020 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -187,6 +187,7 @@ int main (int argc, char **argv)
if (daemon->cachesize < CACHESIZ)
die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
+
#else
die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
#endif
@@ -769,7 +770,10 @@ int main (int argc, char **argv)
}
my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
-
+
+ if (access("/etc/system-fips", F_OK) == 0)
+ my_syslog(LOG_WARNING, _("DNSSEC support is not FIPS 140-2 compliant"));
+
daemon->dnssec_no_time_check = option_bool(OPT_DNSSEC_TIME);
if (option_bool(OPT_DNSSEC_TIME) && !daemon->back_to_the_future)
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until receipt of SIGINT"));
--
2.14.4

View File

@ -0,0 +1,49 @@
From dcb4fa04548ab2364f662b735be86e275bd50745 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Fri, 19 Jul 2019 14:00:08 +0200
Subject: [PATCH] Remove warnings in coverity
Change in dnsmasq should never occur, because ent_pw would not change.
But keep Coverity happy and prevent logic error. Second change avoids
warning from compiler.
---
src/dnsmasq.c | 9 ++++++++-
src/option.c | 2 +-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index ce44809..2984f55 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -608,7 +608,14 @@ int main (int argc, char **argv)
if (ent_pw && ent_pw->pw_uid != 0)
{
-#if defined(HAVE_LINUX_NETWORK)
+#if defined(HAVE_LINUX_NETWORK)
+ if (!hdr || !data)
+ {
+ /* Just failsafe for logic errors */
+ send_event(err_pipe[1], EVENT_CAP_ERR, ENOMEM, NULL);
+ _exit(0);
+ }
+
/* On linux, we keep CAP_NETADMIN (for ARP-injection) and
CAP_NET_RAW (for icmp) if we're doing dhcp. If we have yet to bind
ports because of DAD, or we're doing it dynamically,
diff --git a/src/option.c b/src/option.c
index 9768efb..b12183b 100644
--- a/src/option.c
+++ b/src/option.c
@@ -4255,7 +4255,7 @@ err:
struct name_list *nl;
if (!canon)
{
- struct name_list *tmp = new->names, *next;
+ struct name_list *tmp, *next;
for (tmp = new->names; tmp; tmp = next)
{
next = tmp->next;
--
2.20.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
From 10642f9fb350e118d88e995b8dfa2badc7be1c30 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Wed, 11 Dec 2019 13:41:57 +0100
Subject: [PATCH] Restore ability to answer non-recursive requests
Instead, check only local configured entries are answered without
rdbit set. All cached replies are still denied, but locally configured
names are available with both recursion and without it.
---
src/rfc1035.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 6b3bb27..6a7c154 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1262,7 +1262,11 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
else
return daemon->max_ttl;
}
-
+
+static int cache_validated(const struct crec *crecp)
+{
+ return (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK));
+}
/* return zero if we can't answer from cache, or packet size if we can */
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
@@ -1281,6 +1285,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
struct mx_srv_record *rec;
size_t len;
+ int rd_bit;
// Make sure we do not underflow here too.
if (qlen > (limit - ((char *)header))) return 0;
@@ -1290,10 +1295,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
OPCODE(header) != QUERY )
return 0;
- /* always servfail queries with RD unset, to avoid cache snooping. */
- if (!(header->hb3 & HB3_RD))
- return setup_reply(header, qlen, NULL, F_SERVFAIL, 0);
-
+ rd_bit = (header->hb3 & HB3_RD);
+
/* Don't return AD set if checking disabled. */
if (header->hb4 & HB4_CD)
sec_data = 0;
@@ -1458,9 +1461,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
/* Don't use cache when DNSSEC data required, unless we know that
the zone is unsigned, which implies that we're doing
validation. */
- if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
- !do_bit ||
- (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
+ if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
+ (rd_bit && (!do_bit || cache_validated(crecp)) ))
{
do
{
@@ -1657,8 +1659,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
/* If the client asked for DNSSEC don't use cached data. */
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
- !do_bit ||
- (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
+ (rd_bit && (!do_bit || cache_validated(crecp)) ))
do
{
/* don't answer wildcard queries with data not from /etc/hosts
@@ -1741,8 +1742,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (qtype == T_CNAME || qtype == T_ANY)
{
if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | (dryrun ? F_NO_RR : 0))) &&
- (qtype == T_CNAME || (crecp->flags & F_CONFIG)) &&
- ((crecp->flags & F_CONFIG) || !do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
+ ((qtype == T_CNAME && rd_bit) || (crecp->flags & F_CONFIG)) &&
+ ((crecp->flags & F_CONFIG) || (!do_bit || cache_validated(crecp))))
{
if (!(crecp->flags & F_DNSSECOK))
sec_data = 0;
@@ -1780,7 +1781,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
}
- if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
+ if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
{
ans = 1;
--
2.21.0

View File

@ -0,0 +1,48 @@
From 7e3250d52921b5f75bdbe0b794514bb78a209969 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Wed, 3 Jul 2019 17:02:16 +0200
Subject: [PATCH 2/5] Compare address and interface index for allowed interface
If interface is recreated with the same address but different index, it
would not change any other parameter.
Test also address family on incoming TCP queries.
---
src/dnsmasq.c | 3 ++-
src/network.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index f3d2671..7812be8 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -1667,7 +1667,8 @@ static void check_dns_listeners(time_t now)
#endif
for (iface = daemon->interfaces; iface; iface = iface->next)
- if (iface->index == if_index)
+ if (iface->index == if_index &&
+ iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
break;
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
diff --git a/src/network.c b/src/network.c
index fd90288..f247811 100644
--- a/src/network.c
+++ b/src/network.c
@@ -404,10 +404,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
/* check whether the interface IP has been added already
we call this routine multiple times. */
for (iface = daemon->interfaces; iface; iface = iface->next)
- if (sockaddr_isequal(&iface->addr, addr))
+ if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
{
iface->dad = !!(iface_flags & IFACE_TENTATIVE);
iface->found = 1; /* for garbage collection */
+ iface->netmask = netmask;
return 1;
}
--
2.20.1

View File

@ -0,0 +1,188 @@
From 11ab42e63f9089c4c14a391f30175d4c2d071e99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Mon, 15 Jul 2019 17:13:12 +0200
Subject: [PATCH 4/5] Handle listening on duplicate addresses
Save listening address into listener. Use it to find existing listeners
before creating new one. If it exist, increase just used counter.
Release only listeners not already used.
Duplicates family in listener.
---
src/dnsmasq.h | 3 +-
src/network.c | 115 ++++++++++++++++++++++++++++++++++++--------------
2 files changed, 85 insertions(+), 33 deletions(-)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 89d138a..3b3f6ef 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -552,7 +552,8 @@ struct irec {
};
struct listener {
- int fd, tcpfd, tftpfd, family;
+ int fd, tcpfd, tftpfd, family, used;
+ union mysockaddr addr;
struct irec *iface; /* only sometimes valid for non-wildcard */
struct listener *next;
};
diff --git a/src/network.c b/src/network.c
index d6d4b01..4bbd810 100644
--- a/src/network.c
+++ b/src/network.c
@@ -577,6 +577,56 @@ static void clean_interfaces()
}
}
+/** Release listener if no other interface needs it.
+ *
+ * @return 1 if released, 0 if still required
+ */
+static int release_listener(struct listener *l)
+{
+ if (l->used > 1)
+ {
+ struct irec *iface;
+ for (iface = daemon->interfaces; iface; iface = iface->next)
+ if (iface->done && sockaddr_isequal(&l->addr, &iface->addr))
+ {
+ if (iface->found)
+ {
+ /* update listener to point to active interface instead */
+ if (!l->iface->found)
+ l->iface = iface;
+ }
+ else
+ {
+ l->used--;
+ iface->done = 0;
+ }
+ }
+
+ /* Someone is still using this listener, skip its deletion */
+ if (l->used > 0)
+ return 0;
+ }
+
+ if (l->iface->done)
+ {
+ (void)prettyprint_addr(&l->iface->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s"),
+ l->iface->name, l->iface->index, daemon->addrbuff);
+ /* In case it ever returns */
+ l->iface->done = 0;
+ }
+
+ if (l->fd != -1)
+ close(l->fd);
+ if (l->tcpfd != -1)
+ close(l->tcpfd);
+ if (l->tftpfd != -1)
+ close(l->tftpfd);
+
+ free(l);
+ return 1;
+}
+
int enumerate_interfaces(int reset)
{
static struct addrlist *spare = NULL;
@@ -684,29 +734,10 @@ int enumerate_interfaces(int reset)
if (!l->iface || l->iface->found)
up = &l->next;
- else
+ else if (release_listener(l))
{
- *up = l->next;
- if (l->iface->done)
- {
- iface = l->iface;
- (void)prettyprint_addr(&iface->addr, daemon->addrbuff);
- my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s"),
- iface->name, iface->index, daemon->addrbuff);
- }
-
- /* In case it ever returns */
- l->iface->done = 0;
-
- if (l->fd != -1)
- close(l->fd);
- if (l->tcpfd != -1)
- close(l->tcpfd);
- if (l->tftpfd != -1)
- close(l->tftpfd);
-
- free(l);
- freed = 1;
+ *up = tmp;
+ freed = 1;
}
}
@@ -959,7 +990,9 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
l->family = addr->sa.sa_family;
l->fd = fd;
l->tcpfd = tcpfd;
- l->tftpfd = tftpfd;
+ l->tftpfd = tftpfd;
+ l->addr = *addr;
+ l->used = 1;
l->iface = NULL;
}
@@ -1000,23 +1033,41 @@ void create_wildcard_listeners(void)
daemon->listeners = l;
}
+static struct listener *find_listener(union mysockaddr *addr)
+{
+ struct listener *l;
+ for (l = daemon->listeners; l; l = l->next)
+ if (sockaddr_isequal(&l->addr, addr))
+ return l;
+ return NULL;
+}
+
void create_bound_listeners(int dienow)
{
struct listener *new;
struct irec *iface;
struct iname *if_tmp;
+ struct listener *existing;
for (iface = daemon->interfaces; iface; iface = iface->next)
- if (!iface->done && !iface->dad && iface->found &&
- (new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
+ if (!iface->done && !iface->dad && iface->found)
{
- new->iface = iface;
- new->next = daemon->listeners;
- daemon->listeners = new;
- iface->done = 1;
- (void)prettyprint_addr(&iface->addr, daemon->addrbuff);
- my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s"),
- iface->name, iface->index, daemon->addrbuff);
+ existing = find_listener(&iface->addr);
+ if (existing)
+ {
+ iface->done = 1;
+ existing->used++; /* increase usage counter */
+ }
+ else if ((new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
+ {
+ new->iface = iface;
+ new->next = daemon->listeners;
+ daemon->listeners = new;
+ iface->done = 1;
+ (void)prettyprint_addr(&iface->addr, daemon->addrbuff);
+ my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s"),
+ iface->name, iface->index, daemon->addrbuff);
+ }
}
/* Check for --listen-address options that haven't been used because there's
--
2.20.1

View File

@ -0,0 +1,22 @@
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 14 Aug 2019 20:52:50 +0000 (+0100)
Subject: Fix breakage of dhcp_lease_time utility.
X-Git-Url: http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commitdiff_plain;h=225accd235a09413ca253e710d7d691a3475c523
Fix breakage of dhcp_lease_time utility.
---
diff --git a/contrib/lease-tools/dhcp_lease_time.c b/contrib/lease-tools/dhcp_lease_time.c
index 697d627..91edbfa 100644
--- a/contrib/lease-tools/dhcp_lease_time.c
+++ b/contrib/lease-tools/dhcp_lease_time.c
@@ -83,7 +83,7 @@ static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt
if (p >= end - 2)
return NULL; /* malformed packet */
opt_len = option_len(p);
- if (end - p >= (2 + opt_len))
+ if (end - p < (2 + opt_len))
return NULL; /* malformed packet */
if (*p == opt && opt_len >= minsize)
return p;

View File

@ -0,0 +1,34 @@
From 8fda4b4620ca2b23152ca805d14c7cde1083fe31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 1 Oct 2019 16:08:28 +0200
Subject: [PATCH] Report error on dhcp_release
If no IPv4 address is present on given interface, the tool would not
send any request. It would not report any error at the same time. Report
error if request send failed.
Signed-off-by: Petr Mensik <pemensik@redhat.com>
---
contrib/lease-tools/dhcp_release.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
index c866cd9..30e77c6 100644
--- a/contrib/lease-tools/dhcp_release.c
+++ b/contrib/lease-tools/dhcp_release.c
@@ -223,7 +223,11 @@ static struct in_addr find_interface(struct in_addr client, int fd, unsigned int
ifr->ifr_addr.sa_family = AF_INET;
if (ioctl(ifrfd, SIOCGIFADDR, ifr) != -1)
return ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
- exit(0);
+ else
+ {
+ fprintf(stderr, "error: local IPv4 address not found\n");
+ exit(1);
+ }
}
else if (h->nlmsg_type == RTM_NEWADDR)
{
--
2.20.1

View File

@ -0,0 +1,73 @@
From a997ca0da044719a0ce8a232d14da8b30022592b Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 29 Jun 2018 14:39:41 +0100
Subject: [PATCH] Fix sometimes missing DNSSEC RRs when DNSSEC validation not
enabled.
Dnsmasq does pass on the do-bit, and return DNSSEC RRs, irrespective
of of having DNSSEC validation compiled in or enabled.
The thing to understand here is that the cache does not store all the
DNSSEC RRs, and dnsmasq doesn't have the (very complex) logic required
to determine the set of DNSSEC RRs required in an answer. Therefore if
the client wants the DNSSEC RRs, the query can not be answered from
the cache. When DNSSEC validation is enabled, any query with the
do-bit set is never answered from the cache, unless the domain is
known not to be signed: the query is always forwarded. This ensures
that the DNSEC RRs are included.
The same thing should be true when DNSSEC validation is not enabled,
but there's a bug in the logic.
line 1666 of src/rfc1035.c looks like this
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
{ ...answer from cache ... }
So local stuff (hosts, DHCP, ) get answered. If the do_bit is not set
then the query is answered, and if the domain is known not to be
signed, the query is answered.
Unfortunately, if DNSSEC validation is not turned on then the
F_DNSSECOK bit is not valid, and it's always zero, so the question
always gets answered from the cache, even when the do-bit is set.
This code should look like that at line 1468, dealing with PTR queries
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
!do_bit ||
(option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
where the F_DNSSECOK bit is only used when validation is enabled.
---
src/rfc1035.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/rfc1035.c b/src/rfc1035.c
index ebb1f36..580f5ef 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1663,7 +1663,9 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
/* If the client asked for DNSSEC don't use cached data. */
- if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
+ if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
+ !do_bit ||
+ (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
do
{
/* don't answer wildcard queries with data not from /etc/hosts
@@ -1747,7 +1749,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
{
if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | (dryrun ? F_NO_RR : 0))) &&
(qtype == T_CNAME || (crecp->flags & F_CONFIG)) &&
- ((crecp->flags & F_CONFIG) || !do_bit || !(crecp->flags & F_DNSSECOK)))
+ ((crecp->flags & F_CONFIG) || !do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
{
if (!(crecp->flags & F_DNSSECOK))
sec_data = 0;
--
2.14.4

View File

@ -0,0 +1,47 @@
From 69bc94779c2f035a9fffdb5327a54c3aeca73ed5 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 14 Aug 2019 20:44:50 +0100
Subject: [PATCH] Fix memory leak in helper.c
Thanks to Xu Mingjie <xumingjie1995@outlook.com> for spotting this.
---
src/helper.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/helper.c b/src/helper.c
index 33ba120..c392eec 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -80,7 +80,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
pid_t pid;
int i, pipefd[2];
struct sigaction sigact;
-
+ unsigned char *alloc_buff = NULL;
+
/* create the pipe through which the main program sends us commands,
then fork our process. */
if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1)
@@ -186,11 +187,16 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
struct script_data data;
char *p, *action_str, *hostname = NULL, *domain = NULL;
unsigned char *buf = (unsigned char *)daemon->namebuff;
- unsigned char *end, *extradata, *alloc_buff = NULL;
+ unsigned char *end, *extradata;
int is6, err = 0;
int pipeout[2];
- free(alloc_buff);
+ /* Free rarely-allocated memory from previous iteration. */
+ if (alloc_buff)
+ {
+ free(alloc_buff);
+ alloc_buff = NULL;
+ }
/* we read zero bytes when pipe closed: this is our signal to exit */
if (!read_write(pipefd[0], (unsigned char *)&data, sizeof(data), 1))
--
1.7.10.4

View File

@ -0,0 +1,317 @@
From 653481c6ebf46dcadb5a017085325d956dd04a28 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Tue, 21 Aug 2018 22:06:36 +0100
Subject: [PATCH] Properly deal with unaligned addresses in DHCPv6 packets.
Thanks to Vladislav Grishenko for spotting this.
(cherry picked from commit 97f876b64c22b2b18412e2e3d8506ee33e42db7c)
Conflicts:
src/rfc3315.c
---
src/rfc1035.c | 2 +-
src/rfc3315.c | 101 ++++++++++++++++++++++++++++++++++------------------------
2 files changed, 61 insertions(+), 42 deletions(-)
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 6b3bb27..ee5f7a0 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1376,7 +1376,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL,
t->class, C_IN, "t", t->len, t->txt))
- anscount ++;
+ anscount++;
}
}
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 21fcd9b..ee1cf17 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -639,9 +639,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
int plain_range = 1;
u32 lease_time;
struct dhcp_lease *ltmp;
- struct in6_addr *req_addr;
- struct in6_addr addr;
-
+ struct in6_addr req_addr, addr;
+
if (!check_ia(state, opt, &ia_end, &ia_option))
continue;
@@ -709,9 +708,10 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
{
- req_addr = opt6_ptr(ia_option, 0);
+ /* worry about alignment here. */
+ memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
- if ((c = address6_valid(state->context, req_addr, solicit_tags, plain_range)))
+ if ((c = address6_valid(state->context, &req_addr, solicit_tags, plain_range)))
{
lease_time = c->lease_time;
/* If the client asks for an address on the same network as a configured address,
@@ -719,14 +719,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
addresses automatic. */
if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr) && check_address(state, &addr))
{
- req_addr = &addr;
+ req_addr = addr;
mark_config_used(c, &addr);
if (have_config(config, CONFIG_TIME))
lease_time = config->lease_time;
}
- else if (!(c = address6_available(state->context, req_addr, solicit_tags, plain_range)))
+ else if (!(c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
continue; /* not an address we're allowed */
- else if (!check_address(state, req_addr))
+ else if (!check_address(state, &req_addr))
continue; /* address leased elsewhere */
/* add address to output packet */
@@ -734,8 +734,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
state->send_prefix_class = prefix_class_from_context(c);
#endif
- add_address(state, c, lease_time, ia_option, &min_time, req_addr, now);
- mark_context_used(state, req_addr);
+ add_address(state, c, lease_time, ia_option, &min_time, &req_addr, now);
+ mark_context_used(state, &req_addr);
get_context_tag(state, c);
address_assigned = 1;
}
@@ -768,15 +768,15 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
ltmp = NULL;
while ((ltmp = lease6_find_by_client(ltmp, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, state->clid, state->clid_len, state->iaid)))
{
- req_addr = &ltmp->addr6;
- if ((c = address6_available(state->context, req_addr, solicit_tags, plain_range)))
+ req_addr = ltmp->addr6;
+ if ((c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
{
#ifdef OPTION6_PREFIX_CLASS
if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
state->send_prefix_class = prefix_class_from_context(c);
#endif
- add_address(state, c, c->lease_time, NULL, &min_time, req_addr, now);
- mark_context_used(state, req_addr);
+ add_address(state, c, c->lease_time, NULL, &min_time, &req_addr, now);
+ mark_context_used(state, &req_addr);
get_context_tag(state, c);
address_assigned = 1;
}
@@ -892,16 +892,19 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
{
- struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
+ struct in6_addr req_addr;
struct dhcp_context *dynamic, *c;
unsigned int lease_time;
struct in6_addr addr;
int config_ok = 0;
+
+ /* align. */
+ memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
- if ((c = address6_valid(state->context, req_addr, tagif, 1)))
- config_ok = config_valid(config, c, &addr) && IN6_ARE_ADDR_EQUAL(&addr, req_addr);
+ if ((c = address6_valid(state->context, &req_addr, tagif, 1)))
+ config_ok = config_valid(config, c, &addr) && IN6_ARE_ADDR_EQUAL(&addr, &req_addr);
- if ((dynamic = address6_available(state->context, req_addr, tagif, 1)) || c)
+ if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c)
{
if (!dynamic && !config_ok)
{
@@ -911,7 +914,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
put_opt6_string(_("address unavailable"));
end_opt6(o1);
}
- else if (!check_address(state, req_addr))
+ else if (!check_address(state, &req_addr))
{
/* Address leased to another DUID/IAID */
o1 = new_opt6(OPTION6_STATUS_CODE);
@@ -933,7 +936,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
state->send_prefix_class = prefix_class_from_context(c);
#endif
- add_address(state, dynamic, lease_time, ia_option, &min_time, req_addr, now);
+ add_address(state, dynamic, lease_time, ia_option, &min_time, &req_addr, now);
get_context_tag(state, dynamic);
address_assigned = 1;
}
@@ -996,15 +999,17 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
{
struct dhcp_lease *lease = NULL;
- struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
+ struct in6_addr req_addr;
unsigned int preferred_time = opt6_uint(ia_option, 16, 4);
unsigned int valid_time = opt6_uint(ia_option, 20, 4);
char *message = NULL;
struct dhcp_context *this_context;
+
+ memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
if (!(lease = lease6_find(state->clid, state->clid_len,
state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
- state->iaid, req_addr)))
+ state->iaid, &req_addr)))
{
/* If the server cannot find a client entry for the IA the server
returns the IA containing no addresses with a Status Code option set
@@ -1012,7 +1017,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
save_counter(iacntr);
t1cntr = 0;
- log6_packet(state, "DHCPREPLY", req_addr, _("lease not found"));
+ log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
o1 = new_opt6(OPTION6_STATUS_CODE);
put_opt6_short(DHCP6NOBINDING);
@@ -1024,15 +1029,15 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
}
- if ((this_context = address6_available(state->context, req_addr, tagif, 1)) ||
- (this_context = address6_valid(state->context, req_addr, tagif, 1)))
+ if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
+ (this_context = address6_valid(state->context, &req_addr, tagif, 1)))
{
struct in6_addr addr;
unsigned int lease_time;
get_context_tag(state, this_context);
- if (config_valid(config, this_context, &addr) && IN6_ARE_ADDR_EQUAL(&addr, req_addr) && have_config(config, CONFIG_TIME))
+ if (config_valid(config, this_context, &addr) && IN6_ARE_ADDR_EQUAL(&addr, &req_addr) && have_config(config, CONFIG_TIME))
lease_time = config->lease_time;
else
lease_time = this_context->lease_time;
@@ -1045,7 +1050,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
lease_set_hwaddr(lease, state->mac, state->clid, state->mac_len, state->mac_type, state->clid_len, now, 0);
if (state->ia_type == OPTION6_IA_NA && state->hostname)
{
- char *addr_domain = get_domain6(req_addr);
+ char *addr_domain = get_domain6(&req_addr);
if (!state->send_domain)
state->send_domain = addr_domain;
lease_set_hostname(lease, state->hostname, state->hostname_auth, addr_domain, state->domain);
@@ -1063,12 +1068,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
}
if (message && (message != state->hostname))
- log6_packet(state, "DHCPREPLY", req_addr, message);
+ log6_packet(state, "DHCPREPLY", &req_addr, message);
else
- log6_quiet(state, "DHCPREPLY", req_addr, message);
+ log6_quiet(state, "DHCPREPLY", &req_addr, message);
o1 = new_opt6(OPTION6_IAADDR);
- put_opt6(req_addr, sizeof(*req_addr));
+ put_opt6(&req_addr, sizeof(req_addr));
put_opt6_long(preferred_time);
put_opt6_long(valid_time);
end_opt6(o1);
@@ -1100,19 +1105,23 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
ia_option;
ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
{
- struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
+ struct in6_addr req_addr;
+
+ /* alignment */
+ memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
- if (!address6_valid(state->context, req_addr, tagif, 1))
+ if (!address6_valid(state->context, &req_addr, tagif, 1))
{
o1 = new_opt6(OPTION6_STATUS_CODE);
put_opt6_short(DHCP6NOTONLINK);
put_opt6_string(_("confirm failed"));
end_opt6(o1);
+ log6_quiet(state, "DHCPREPLY", &req_addr, _("confirm failed"));
return 1;
}
good_addr = 1;
- log6_quiet(state, "DHCPREPLY", req_addr, state->hostname);
+ log6_quiet(state, "DHCPREPLY", &req_addr, state->hostname);
}
}
@@ -1171,9 +1180,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
{
struct dhcp_lease *lease;
-
+ struct in6_addr addr;
+
+ /* align */
+ memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
- state->iaid, opt6_ptr(ia_option, 0))))
+ state->iaid, &addr)))
lease_prune(lease, now);
else
{
@@ -1233,12 +1245,15 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
{
struct dhcp_lease *lease;
- struct in6_addr *addrp = opt6_ptr(ia_option, 0);
+ struct in6_addr addr;
- if (have_config(config, CONFIG_ADDR6) && IN6_ARE_ADDR_EQUAL(&config->addr6, addrp))
+ /* align */
+ memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
+
+ if (have_config(config, CONFIG_ADDR6) && IN6_ARE_ADDR_EQUAL(&config->addr6, &addr))
{
prettyprint_time(daemon->dhcp_buff3, DECLINE_BACKOFF);
- inet_ntop(AF_INET6, addrp, daemon->addrbuff, ADDRSTRLEN);
+ inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
daemon->addrbuff, daemon->dhcp_buff3);
config->flags |= CONFIG_DECLINED;
@@ -1250,7 +1265,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
context_tmp->addr_epoch++;
if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
- state->iaid, opt6_ptr(ia_option, 0))))
+ state->iaid, &addr)))
lease_prune(lease, now);
else
{
@@ -1267,7 +1282,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
}
o1 = new_opt6(OPTION6_IAADDR);
- put_opt6(opt6_ptr(ia_option, 0), IN6ADDRSZ);
+ put_opt6(&addr, IN6ADDRSZ);
put_opt6_long(0);
put_opt6_long(0);
end_opt6(o1);
@@ -1935,7 +1950,11 @@ static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_op
}
else if (type == OPTION6_IAADDR)
{
- inet_ntop(AF_INET6, opt6_ptr(opt, 0), daemon->addrbuff, ADDRSTRLEN);
+ struct in6_addr addr;
+
+ /* align */
+ memcpy(&addr, opt6_ptr(opt, 0), IN6ADDRSZ);
+ inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
sprintf(daemon->namebuff, "%s PL=%u VL=%u",
daemon->addrbuff, opt6_uint(opt, 16, 4), opt6_uint(opt, 20, 4));
optname = "iaaddr";
--
1.8.3.1

View File

@ -0,0 +1,44 @@
From 6307208c806f9b968eca178931b3d77c4ed83c54 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Fri, 6 Mar 2020 15:37:23 +0100
Subject: [PATCH] Correct range check of dhcp-host prefix
It incorrectly works with 32 bit integer only when counting number of
addresses in range. It works correctly only between prefixlen 96 and
128. Use 64bit shift to work with well with numbers higher than 64.
Fixes commit 79aba0f10ad0157fb4f48afbbcb03f094caff97a error.
---
src/option.c | 2 +-
src/rfc3315.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/option.c b/src/option.c
index 88cd2ab..79122df 100644
--- a/src/option.c
+++ b/src/option.c
@@ -3247,7 +3247,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (!atoi_check(pref, &new_addr->prefixlen) ||
new_addr->prefixlen > 128 ||
- (((1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
+ ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
{
dhcp_config_free(new);
ret_err(_("bad IPv6 prefix"));
diff --git a/src/rfc3315.c b/src/rfc3315.c
index a0067e9..f59aedc 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -1798,7 +1798,7 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context
addresses = 1;
if (addr_list->flags & ADDRLIST_PREFIX)
- addresses = 1<<(128-addr_list->prefixlen);
+ addresses = (u64)1<<(128-addr_list->prefixlen);
if ((addr_list->flags & ADDRLIST_WILDCARD))
{
--
2.21.1

View File

@ -0,0 +1,132 @@
commit 98c6998116e33f9f34b798682e0695f4166bd86d
Author: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon Mar 2 17:10:25 2020 +0000
Optimise closing file descriptors.
Dnsmasq needs to close all the file descriptors it inherits, for security
reasons. This is traditionally done by calling close() on every possible
file descriptor (most of which won't be open.) On big servers where
"every possible file descriptor" is a rather large set, this gets
rather slow, so we use the /proc/<pid>/fd directory to get a list
of the fds which are acually open.
This only works on Linux. On other platforms, and on Linux systems
without a /proc filesystem, we fall back to the old way.
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 573aac0..10f19ea 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -138,20 +138,18 @@ int main (int argc, char **argv)
}
#endif
- /* Close any file descriptors we inherited apart from std{in|out|err}
-
- Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
+ /* Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
otherwise file descriptors we create can end up being 0, 1, or 2
and then get accidentally closed later when we make 0, 1, and 2
open to /dev/null. Normally we'll be started with 0, 1 and 2 open,
but it's not guaranteed. By opening /dev/null three times, we
ensure that we're not using those fds for real stuff. */
- for (i = 0; i < max_fd; i++)
- if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
- close(i);
- else
- open("/dev/null", O_RDWR);
-
+ for (i = 0; i < 3; i++)
+ open("/dev/null", O_RDWR);
+
+ /* Close any file descriptors we inherited apart from std{in|out|err} */
+ close_fds(max_fd, -1, -1, -1);
+
#ifndef HAVE_LINUX_NETWORK
# if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
if (!option_bool(OPT_NOWILD))
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 6103eb5..c46bfeb 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1283,7 +1283,7 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len,
int expand_buf(struct iovec *iov, size_t size);
char *print_mac(char *buff, unsigned char *mac, int len);
int read_write(int fd, unsigned char *packet, int size, int rw);
-
+void close_fds(long max_fd, int spare1, int spare2, int spare3);
int wildcard_match(const char* wildcard, const char* match);
int wildcard_matchn(const char* wildcard, const char* match, int num);
diff --git a/src/helper.c b/src/helper.c
index 1b260a1..7072cf4 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -131,12 +131,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
Don't close err_fd, in case the lua-init fails.
Note that we have to do this before lua init
so we don't close any lua fds. */
- for (max_fd--; max_fd >= 0; max_fd--)
- if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO &&
- max_fd != STDIN_FILENO && max_fd != pipefd[0] &&
- max_fd != event_fd && max_fd != err_fd)
- close(max_fd);
-
+ close_fds(max_fd, pipefd[0], event_fd, err_fd);
+
#ifdef HAVE_LUASCRIPT
if (daemon->luascript)
{
diff --git a/src/util.c b/src/util.c
index 73bf62a..f058c92 100644
--- a/src/util.c
+++ b/src/util.c
@@ -705,6 +705,47 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
return 1;
}
+/* close all fds except STDIN, STDOUT and STDERR, spare1, spare2 and spare3 */
+void close_fds(long max_fd, int spare1, int spare2, int spare3)
+{
+ /* On Linux, use the /proc/ filesystem to find which files
+ are actually open, rather than iterate over the whole space,
+ for efficiency reasons. If this fails we drop back to the dumb code. */
+#ifdef HAVE_LINUX_NETWORK
+ DIR *d;
+
+ if ((d = opendir("/proc/self/fd")))
+ {
+ struct dirent *de;
+
+ while ((de = readdir(d)))
+ {
+ long fd;
+ char *e = NULL;
+
+ errno = 0;
+ fd = strtol(de->d_name, &e, 10);
+
+ if (errno != 0 || !e || *e || fd == dirfd(d) ||
+ fd == STDOUT_FILENO || fd == STDERR_FILENO || fd == STDIN_FILENO ||
+ fd == spare1 || fd == spare2 || fd == spare3)
+ continue;
+
+ close(fd);
+ }
+
+ closedir(d);
+ return;
+ }
+#endif
+
+ /* fallback, dumb code. */
+ for (max_fd--; max_fd >= 0; max_fd--)
+ if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO && max_fd != STDIN_FILENO &&
+ max_fd != spare1 && max_fd != spare2 && max_fd != spare3)
+ close(max_fd);
+}
+
/* Basically match a string value against a wildcard pattern. */
int wildcard_match(const char* wildcard, const char* match)
{

View File

@ -0,0 +1,895 @@
From 9b200103342c0909def9f8d9b97cfd889be6bfd8 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 3 Feb 2020 23:58:45 +0000
Subject: [PATCH] Support prefixed ranges of ipv6 addresses in dhcp-host.
When a request matching the clid or mac address is
recieved the server will iterate over all candidate
addresses until it find's one that is not already
leased to a different clid/iaid and advertise
this address.
Using multiple reservations for a single host makes it
possible to maintain a static leases only configuration
which support network booting systems with UEFI firmware
that request a new address (a new SOLICIT with a new IA_NA
option using a new IAID) for different boot modes, for
instance 'PXE over IPv6', and 'HTTP-Boot over IPv6'. Open
Virtual Machine Firmware (OVMF) and most UEFI firmware
build on the EDK2 code base exhibit this behaviour.
(cherry picked from commit 79aba0f10ad0157fb4f48afbbcb03f094caff97a)
Conflicts:
CHANGELOG
src/dhcp-common.c
src/dnsmasq.h
src/dhcp6.c
Extend 79aba0f10ad0157fb4f48afbbcb03f094caff97a for multiple IPv6 addresses.
(cherry picked from commit 137286e9baecf6a3ba97722ef1b49c851b531810)
Conflicts:
man/dnsmasq.8
src/dhcp-common.c
src/dhcp6.c
src/rfc3315.c
src/option.c
Fix bug with prefixed wildcard addresses in 137286e9baecf6a3ba97722ef1b49c851b531810
(cherry picked from commit f064188032a829efdcf3988b24ac795ff52785ec)
Conflicts:
src/rfc3315.c
---
man/dnsmasq.8 | 13 +-
src/dhcp-common.c | 56 +++++---
src/dhcp6.c | 51 +++----
src/dnsmasq.h | 17 +--
src/option.c | 402 ++++++++++++++++++++++++++++++------------------------
src/rfc3315.c | 83 ++++++++++-
6 files changed, 370 insertions(+), 252 deletions(-)
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index f52762f..2c9d9f6 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -985,13 +985,20 @@ allowed to specify the client ID as text, like this:
.B --dhcp-host=id:clientidastext,.....
A single
-.B dhcp-host
-may contain an IPv4 address or an IPv6 address, or both. IPv6 addresses must be bracketed by square brackets thus:
+.B --dhcp-host
+may contain an IPv4 address or one or more IPv6 addresses, or both. IPv6 addresses must be bracketed by square brackets thus:
.B --dhcp-host=laptop,[1234::56]
IPv6 addresses may contain only the host-identifier part:
.B --dhcp-host=laptop,[::56]
in which case they act as wildcards in constructed dhcp ranges, with
-the appropriate network part inserted.
+the appropriate network part inserted. For IPv6, an address may include a prefix length:
+.B --dhcp-host=laptop,[1234:50/126]
+which (in this case) specifies four addresses, 1234::50 to 1234::53. This (an the ability
+to specify multiple addresses) is useful
+when a host presents either a consistent name or hardware-ID, but varying DUIDs, since it allows
+dnsmasq to honour the static address allocation but assign a different adddress for each DUID. This
+typically occurs when chain netbooting, as each stage of the chain gets in turn allocates an address.
+
Note that in IPv6 DHCP, the hardware address may not be
available, though it normally is for direct-connected clients, or
clients using DHCP relays which support RFC 6939.
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
index d9719d1..5d437dd 100644
--- a/src/dhcp-common.c
+++ b/src/dhcp-common.c
@@ -271,26 +271,35 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
{
if (!context) /* called via find_config() from lease_update_from_configs() */
return 1;
-
- if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
- return 1;
#ifdef HAVE_DHCP6
- if ((context->flags & CONTEXT_V6) && (config->flags & CONFIG_WILDCARD))
- return 1;
-#endif
+ if (context->flags & CONTEXT_V6)
+ {
+ struct addrlist *addr_list;
- for (; context; context = context->current)
-#ifdef HAVE_DHCP6
- if (context->flags & CONTEXT_V6)
- {
- if ((config->flags & CONFIG_ADDR6) && is_same_net6(&config->addr6, &context->start6, context->prefix))
- return 1;
- }
- else
+ if (!(config->flags & CONFIG_ADDR6))
+ return 1;
+
+ for (; context; context = context->current)
+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+ {
+ if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
+ return 1;
+
+ if (is_same_net6(&addr_list->addr.addr.addr6, &context->start6, context->prefix))
+ return 1;
+ }
+ }
+ else
#endif
- if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
+ {
+ if (!(config->flags & CONFIG_ADDR))
return 1;
+
+ for (; context; context = context->current)
+ if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
+ return 1;
+ }
return 0;
}
@@ -418,10 +427,21 @@ void dhcp_update_configs(struct dhcp_config *configs)
#ifdef HAVE_DHCP6
if (prot == AF_INET6 &&
- (!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 128, 0)) || conf_tmp == config))
+ (!(conf_tmp = config_find_by_address6(configs, NULL, 0, &crec->addr.addr.addr.addr6)) || conf_tmp == config))
{
- memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ);
- config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS;
+ /* host must have exactly one address if comming from /etc/hosts. */
+ if (!config->addr6 && (config->addr6 = whine_malloc(sizeof(struct addrlist))))
+ {
+ config->addr6->next = NULL;
+ config->addr6->flags = 0;
+ }
+
+ if (config->addr6 && !config->addr6->next && !(config->addr6->flags & (ADDRLIST_WILDCARD|ADDRLIST_PREFIX)))
+ {
+ memcpy(&config->addr6->addr.addr.addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ);
+ config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS;
+ }
+
continue;
}
#endif
diff --git a/src/dhcp6.c b/src/dhcp6.c
index 0853664..6f1f54e 100644
--- a/src/dhcp6.c
+++ b/src/dhcp6.c
@@ -384,21 +384,26 @@ static int complete_context6(struct in6_addr *local, int prefix,
return 1;
}
-struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, u64 addr)
+struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, struct in6_addr *addr)
{
struct dhcp_config *config;
for (config = configs; config; config = config->next)
- if ((config->flags & CONFIG_ADDR6) &&
- is_same_net6(&config->addr6, net, prefix) &&
- (prefix == 128 || addr6part(&config->addr6) == addr))
- return config;
+ if (config->flags & CONFIG_ADDR6)
+ {
+ struct addrlist *addr_list;
+
+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+ if ((!net || is_same_net6(&addr_list->addr.addr.addr6, net, prefix) || ((addr_list->flags & ADDRLIST_WILDCARD) && prefix == 64)) &&
+ is_same_net6(&addr_list->addr.addr.addr6, addr, (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128))
+ return config;
+ }
return NULL;
}
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
- int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
+ unsigned int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
{
/* Find a free address: exclude anything in use and anything allocated to
a particular hwaddr/clientid/hostname in our configuration.
@@ -453,16 +458,15 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
for (d = context; d; d = d->current)
if (addr == addr6part(&d->local6))
break;
+
+ *ans = c->start6;
+ setaddr6part (ans, addr);
if (!d &&
!lease6_find_by_addr(&c->start6, c->prefix, addr) &&
- !config_find_by_address6(daemon->dhcp_conf, &c->start6, c->prefix, addr))
- {
- *ans = c->start6;
- setaddr6part (ans, addr);
- return c;
- }
-
+ !config_find_by_address6(daemon->dhcp_conf, &c->start6, c->prefix, ans))
+ return c;
+
addr++;
if (addr == addr6part(&c->end6) + 1)
@@ -516,27 +520,6 @@ struct dhcp_context *address6_valid(struct dhcp_context *context,
return NULL;
}
-int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
-{
- if (!config || !(config->flags & CONFIG_ADDR6))
- return 0;
-
- if ((config->flags & CONFIG_WILDCARD) && context->prefix == 64)
- {
- *addr = context->start6;
- setaddr6part(addr, addr6part(&config->addr6));
- return 1;
- }
-
- if (is_same_net6(&context->start6, &config->addr6, context->prefix))
- {
- *addr = config->addr6;
- return 1;
- }
-
- return 0;
-}
-
void make_duid(time_t now)
{
(void)now;
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 6b18bb7..9437226 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -343,9 +343,11 @@ struct ds_config {
struct ds_config *next;
};
-#define ADDRLIST_LITERAL 1
-#define ADDRLIST_IPV6 2
-#define ADDRLIST_REVONLY 4
+#define ADDRLIST_LITERAL 1
+#define ADDRLIST_IPV6 2
+#define ADDRLIST_REVONLY 4
+#define ADDRLIST_PREFIX 8
+#define ADDRLIST_WILDCARD 16
struct addrlist {
struct all_addr addr;
@@ -748,7 +750,7 @@ struct dhcp_config {
char *hostname, *domain;
struct dhcp_netid_list *netid;
#ifdef HAVE_DHCP6
- struct in6_addr addr6;
+ struct addrlist *addr6;
#endif
struct in_addr addr;
time_t decline_time;
@@ -770,7 +772,7 @@ struct dhcp_config {
#define CONFIG_DECLINED 1024 /* address declined by client */
#define CONFIG_BANK 2048 /* from dhcp hosts file */
#define CONFIG_ADDR6 4096
-#define CONFIG_WILDCARD 8192
+#define CONFIG_ADDR6_HOSTS 16384 /* address added by from /etc/hosts */
struct dhcp_opt {
int opt, len, flags;
@@ -1463,8 +1465,7 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
void dhcp6_init(void);
void dhcp6_packet(time_t now);
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
- int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
-int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
+ unsigned int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
struct dhcp_context *address6_available(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids,
@@ -1474,7 +1475,7 @@ struct dhcp_context *address6_valid(struct dhcp_context *context,
struct dhcp_netid *netids,
int plain_range);
struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net,
- int prefix, u64 addr);
+ int prefix, struct in6_addr *addr);
void make_duid(time_t now);
void dhcp_construct_contexts(time_t now);
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
diff --git a/src/option.c b/src/option.c
index b12183b..ea70ee3 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1010,15 +1010,30 @@ static void dhcp_config_free(struct dhcp_config *config)
if (config)
{
struct hwaddr_config *hwaddr = config->hwaddr;
+
while (hwaddr)
{
struct hwaddr_config *tmp = hwaddr;
hwaddr = hwaddr->next;
free(tmp);
}
+
dhcp_netid_list_free(config->netid);
+
if (config->flags & CONFIG_CLID)
free(config->clid);
+
+ if (config->flags & CONFIG_ADDR6)
+ {
+ struct addrlist *addr, *tmp;
+
+ for (addr = config->addr6; addr; addr = tmp)
+ {
+ tmp = addr->next;
+ free(addr);
+ }
+ }
+
free(config);
}
}
@@ -3143,8 +3158,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
case LOPT_BANK:
case 'G': /* --dhcp-host */
{
- int j, k = 0;
- char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
struct dhcp_config *new;
struct in_addr in;
@@ -3155,197 +3168,222 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->hwaddr = NULL;
new->netid = NULL;
new->clid = NULL;
+ new->addr6 = NULL;
- if ((a[0] = arg))
- for (k = 1; k < 7; k++)
- if (!(a[k] = split(a[k-1])))
- break;
-
- for (j = 0; j < k; j++)
- if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */
- {
- char *arg = a[j];
-
- if ((arg[0] == 'i' || arg[0] == 'I') &&
- (arg[1] == 'd' || arg[1] == 'D') &&
- arg[2] == ':')
- {
- if (arg[3] == '*')
- new->flags |= CONFIG_NOCLID;
- else
- {
- int len;
- arg += 3; /* dump id: */
- if (strchr(arg, ':'))
- len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
- else
- {
- unhide_metas(arg);
- len = (int) strlen(arg);
- }
-
- if (len == -1)
- {
- dhcp_config_free(new);
- ret_err(_("bad hex constant"));
- }
- else if ((new->clid = opt_malloc(len)))
- {
- new->flags |= CONFIG_CLID;
- new->clid_len = len;
- memcpy(new->clid, arg, len);
- }
- }
- }
- /* dhcp-host has strange backwards-compat needs. */
- else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
- {
- struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
- newlist->next = new->netid;
- new->netid = newlist;
- newlist->list = dhcp_netid_create(arg+4, NULL);
- }
- else if (strstr(arg, "tag:") == arg)
- {
-
- dhcp_config_free(new);
- ret_err(_("cannot match tags in --dhcp-host"));
- }
+ while (arg)
+ {
+ comma = split(arg);
+ if (strchr(arg, ':')) /* ethernet address, netid or binary CLID */
+ {
+ if ((arg[0] == 'i' || arg[0] == 'I') &&
+ (arg[1] == 'd' || arg[1] == 'D') &&
+ arg[2] == ':')
+ {
+ if (arg[3] == '*')
+ new->flags |= CONFIG_NOCLID;
+ else
+ {
+ int len;
+ arg += 3; /* dump id: */
+ if (strchr(arg, ':'))
+ len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
+ else
+ {
+ unhide_metas(arg);
+ len = (int) strlen(arg);
+ }
+
+ if (len == -1)
+ {
+ dhcp_config_free(new);
+ ret_err(_("bad hex constant"));
+ }
+ else if ((new->clid = opt_malloc(len)))
+ {
+ new->flags |= CONFIG_CLID;
+ new->clid_len = len;
+ memcpy(new->clid, arg, len);
+ }
+ }
+ }
+ /* dhcp-host has strange backwards-compat needs. */
+ else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
+ {
+ struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
+ newlist->next = new->netid;
+ new->netid = newlist;
+ newlist->list = dhcp_netid_create(arg+4, NULL);
+ }
+ else if (strstr(arg, "tag:") == arg)
+ {
+
+ dhcp_config_free(new);
+ ret_err(_("cannot match tags in --dhcp-host"));
+ }
#ifdef HAVE_DHCP6
- else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
- {
- arg[strlen(arg)-1] = 0;
- arg++;
-
- if (!inet_pton(AF_INET6, arg, &new->addr6))
- {
- dhcp_config_free(new);
- ret_err(_("bad IPv6 address"));
- }
-
- for (i= 0; i < 8; i++)
- if (new->addr6.s6_addr[i] != 0)
- break;
+ else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
+ {
+ char *pref;
+ struct in6_addr in6;
+ struct addrlist *new_addr;
+
+ arg[strlen(arg)-1] = 0;
+ arg++;
+ pref = split_chr(arg, '/');
+
+ if (!inet_pton(AF_INET6, arg, &in6))
+ {
+ dhcp_config_free(new);
+ ret_err(_("bad IPv6 address"));
+ }
- /* set WILDCARD if network part all zeros */
- if (i == 8)
- new->flags |= CONFIG_WILDCARD;
+ new_addr = opt_malloc(sizeof(struct addrlist));
+ new_addr->next = new->addr6;
+ new_addr->flags = 0;
+ new_addr->addr.addr.addr6 = in6;
+ new->addr6 = new_addr;
+
+ if (pref)
+ {
+ u64 addrpart = addr6part(&in6);
+
+ if (!atoi_check(pref, &new_addr->prefixlen) ||
+ new_addr->prefixlen > 128 ||
+ (((1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
+ {
+ dhcp_config_free(new);
+ ret_err(_("bad IPv6 prefix"));
+ }
+
+ new_addr->flags |= ADDRLIST_PREFIX;
+ }
- new->flags |= CONFIG_ADDR6;
- }
+ for (i= 0; i < 8; i++)
+ if (in6.s6_addr[i] != 0)
+ break;
+
+ /* set WILDCARD if network part all zeros */
+ if (i == 8)
+ new_addr->flags |= ADDRLIST_WILDCARD;
+
+ new->flags |= CONFIG_ADDR6;
+ }
#endif
- else
- {
- struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
- if ((newhw->hwaddr_len = parse_hex(a[j], newhw->hwaddr, DHCP_CHADDR_MAX,
- &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
- {
- free(newhw);
- dhcp_config_free(new);
- ret_err(_("bad hex constant"));
- }
- else
- {
- newhw->next = new->hwaddr;
- new->hwaddr = newhw;
- }
- }
- }
- else if (strchr(a[j], '.') && (inet_pton(AF_INET, a[j], &in) > 0))
- {
- struct dhcp_config *configs;
-
- new->addr = in;
- new->flags |= CONFIG_ADDR;
-
- /* If the same IP appears in more than one host config, then DISCOVER
- for one of the hosts will get the address, but REQUEST will be NAKed,
- since the address is reserved by the other one -> protocol loop. */
- for (configs = daemon->dhcp_conf; configs; configs = configs->next)
- if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
+ else
{
- sprintf(errstr, _("duplicate dhcp-host IP address %s"), inet_ntoa(in));
- return 0;
- }
- }
- else
- {
- char *cp, *lastp = NULL, last = 0;
- int fac = 1, isdig = 0;
-
- if (strlen(a[j]) > 1)
- {
- lastp = a[j] + strlen(a[j]) - 1;
- last = *lastp;
- switch (last)
+ struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
+ if ((newhw->hwaddr_len = parse_hex(arg, newhw->hwaddr, DHCP_CHADDR_MAX,
+ &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
+ {
+ free(newhw);
+ dhcp_config_free(new);
+ ret_err(_("bad hex constant"));
+ }
+ else
+ {
+ newhw->next = new->hwaddr;
+ new->hwaddr = newhw;
+ }
+ }
+ }
+ else if (strchr(arg, '.') && (inet_pton(AF_INET, arg, &in) > 0))
+ {
+ struct dhcp_config *configs;
+
+ new->addr = in;
+ new->flags |= CONFIG_ADDR;
+
+ /* If the same IP appears in more than one host config, then DISCOVER
+ for one of the hosts will get the address, but REQUEST will be NAKed,
+ since the address is reserved by the other one -> protocol loop. */
+ for (configs = daemon->dhcp_conf; configs; configs = configs->next)
+ if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
{
- case 'w':
- case 'W':
- fac *= 7;
- /* fall through */
- case 'd':
- case 'D':
- fac *= 24;
- /* fall through */
- case 'h':
- case 'H':
- fac *= 60;
- /* fall through */
- case 'm':
- case 'M':
- fac *= 60;
- /* fall through */
- case 's':
- case 'S':
- *lastp = 0;
- }
- }
-
- for (cp = a[j]; *cp; cp++)
- if (isdigit((unsigned char)*cp))
- isdig = 1;
- else if (*cp != ' ')
- break;
+ sprintf(errstr, _("duplicate dhcp-host IP address %s"), inet_ntoa(in));
+ return 0;
+ }
+ }
+ else
+ {
+ char *cp, *lastp = NULL, last = 0;
+ int fac = 1, isdig = 0;
+
+ if (strlen(arg) > 1)
+ {
+ lastp = arg + strlen(arg) - 1;
+ last = *lastp;
+ switch (last)
+ {
+ case 'w':
+ case 'W':
+ fac *= 7;
+ /* fall through */
+ case 'd':
+ case 'D':
+ fac *= 24;
+ /* fall through */
+ case 'h':
+ case 'H':
+ fac *= 60;
+ /* fall through */
+ case 'm':
+ case 'M':
+ fac *= 60;
+ /* fall through */
+ case 's':
+ case 'S':
+ *lastp = 0;
+ }
+ }
+
+ for (cp = arg; *cp; cp++)
+ if (isdigit((unsigned char)*cp))
+ isdig = 1;
+ else if (*cp != ' ')
+ break;
+
+ if (*cp)
+ {
+ if (lastp)
+ *lastp = last;
+ if (strcmp(arg, "infinite") == 0)
+ {
+ new->lease_time = 0xffffffff;
+ new->flags |= CONFIG_TIME;
+ }
+ else if (strcmp(arg, "ignore") == 0)
+ new->flags |= CONFIG_DISABLE;
+ else
+ {
+ if (!(new->hostname = canonicalise_opt(arg)) ||
+ !legal_hostname(new->hostname))
+ {
+ dhcp_config_free(new);
+ ret_err(_("bad DHCP host name"));
+ }
+
+ new->flags |= CONFIG_NAME;
+ new->domain = strip_hostname(new->hostname);
+ }
+ }
+ else if (isdig)
+ {
+ new->lease_time = atoi(arg) * fac;
+ /* Leases of a minute or less confuse
+ some clients, notably Apple's */
+ if (new->lease_time < 120)
+ new->lease_time = 120;
+ new->flags |= CONFIG_TIME;
+ }
+ }
+
+ arg = comma;
+ }
- if (*cp)
- {
- if (lastp)
- *lastp = last;
- if (strcmp(a[j], "infinite") == 0)
- {
- new->lease_time = 0xffffffff;
- new->flags |= CONFIG_TIME;
- }
- else if (strcmp(a[j], "ignore") == 0)
- new->flags |= CONFIG_DISABLE;
- else
- {
- if (!(new->hostname = canonicalise_opt(a[j])) ||
- !legal_hostname(new->hostname))
- {
- dhcp_config_free(new);
- ret_err(_("bad DHCP host name"));
- }
-
- new->flags |= CONFIG_NAME;
- new->domain = strip_hostname(new->hostname);
- }
- }
- else if (isdig)
- {
- new->lease_time = atoi(a[j]) * fac;
- /* Leases of a minute or less confuse
- some clients, notably Apple's */
- if (new->lease_time < 120)
- new->lease_time = 120;
- new->flags |= CONFIG_TIME;
- }
- }
-
daemon->dhcp_conf = new;
break;
}
-
+
case LOPT_TAG_IF: /* --tag-if */
{
struct tag_if *new = opt_malloc(sizeof(struct tag_if));
diff --git a/src/rfc3315.c b/src/rfc3315.c
index ee1cf17..ee58b57 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -55,6 +55,8 @@ static struct prefix_class *prefix_class_from_context(struct dhcp_context *conte
static void mark_context_used(struct state *state, struct in6_addr *addr);
static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
static int check_address(struct state *state, struct in6_addr *addr);
+static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state);
+static int config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option,
unsigned int *min_time, struct in6_addr *addr, time_t now);
static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now);
@@ -717,7 +719,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
/* If the client asks for an address on the same network as a configured address,
offer the configured address instead, to make moving to newly-configured
addresses automatic. */
- if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr) && check_address(state, &addr))
+ if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state))
{
req_addr = addr;
mark_config_used(c, &addr);
@@ -745,8 +747,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
for (c = state->context; c; c = c->current)
if (!(c->flags & CONTEXT_CONF_USED) &&
match_netid(c->filter, solicit_tags, plain_range) &&
- config_valid(config, c, &addr) &&
- check_address(state, &addr))
+ config_valid(config, c, &addr, state))
{
mark_config_used(state->context, &addr);
if (have_config(config, CONFIG_TIME))
@@ -895,14 +896,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
struct in6_addr req_addr;
struct dhcp_context *dynamic, *c;
unsigned int lease_time;
- struct in6_addr addr;
int config_ok = 0;
/* align. */
memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
if ((c = address6_valid(state->context, &req_addr, tagif, 1)))
- config_ok = config_valid(config, c, &addr) && IN6_ARE_ADDR_EQUAL(&addr, &req_addr);
+ config_ok = config_implies(config, c, &req_addr);
if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c)
{
@@ -1032,12 +1032,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
(this_context = address6_valid(state->context, &req_addr, tagif, 1)))
{
- struct in6_addr addr;
unsigned int lease_time;
get_context_tag(state, this_context);
- if (config_valid(config, this_context, &addr) && IN6_ARE_ADDR_EQUAL(&addr, &req_addr) && have_config(config, CONFIG_TIME))
+ if (config_implies(config, this_context, &req_addr) && have_config(config, CONFIG_TIME))
lease_time = config->lease_time;
else
lease_time = this_context->lease_time;
@@ -1760,6 +1759,76 @@ static int check_address(struct state *state, struct in6_addr *addr)
}
+/* return true of *addr could have been generated from config. */
+static int config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
+{
+ int prefix;
+ struct in6_addr wild_addr;
+ struct addrlist *addr_list;
+
+ if (!config || !(config->flags & CONFIG_ADDR6))
+ return 0;
+
+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+ {
+ prefix = (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128;
+ wild_addr = addr_list->addr.addr.addr6;
+
+ if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
+ {
+ wild_addr = context->start6;
+ setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr.addr6));
+ }
+ else if (!is_same_net6(&context->start6, addr, context->prefix))
+ continue;
+
+ if (is_same_net6(&wild_addr, addr, prefix))
+ return 1;
+ }
+
+ return 0;
+}
+
+static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state)
+{
+ u64 addrpart, i, addresses;
+ struct addrlist *addr_list;
+
+ if (!config || !(config->flags & CONFIG_ADDR6))
+ return 0;
+
+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+ {
+ addrpart = addr6part(&addr_list->addr.addr.addr6);
+ addresses = 1;
+
+ if (addr_list->flags & ADDRLIST_PREFIX)
+ addresses = 1<<(128-addr_list->prefixlen);
+
+ if ((addr_list->flags & ADDRLIST_WILDCARD))
+ {
+ if (context->prefix != 64)
+ continue;
+
+ *addr = context->start6;
+ }
+ else if (is_same_net6(&context->start6, &addr_list->addr.addr.addr6, context->prefix))
+ *addr = addr_list->addr.addr.addr6;
+ else
+ continue;
+
+ for (i = 0 ; i < addresses; i++)
+ {
+ setaddr6part(addr, addrpart+i);
+
+ if (check_address(state, addr))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* Calculate valid and preferred times to send in leases/renewals.
Inputs are:
--
1.8.3.1

View File

@ -0,0 +1,62 @@
From 3d113137fd64cd0723cbecab6a36a75d3ecfb0a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Harald=20Jens=C3=A5s?= <hjensas@redhat.com>
Date: Thu, 7 May 2020 00:33:54 +0200
Subject: [PATCH 1/1] Fix regression in s_config_in_context() method
Prior to commit 137286e9baecf6a3ba97722ef1b49c851b531810
a config would not be considered in context if:
a) it has no address family flags set
b) it has the address family flag of current context set
Since above commit config is considered in context if the
address family is the opposite of current context.
The result is that a config with two dhcp-host records,
one for IPv6 and another for IPv4 no longer works, for
example with the below config the config with the IPv6
address would be considered in context for a DHCP(v4)
request.
dhcp-host=52:54:00:bc:c3:fd,172.20.0.11,host2
dhcp-host=52:54:00:bc:c3:fd,[fd12:3456:789a:1::aadd],host2
This commit restores the previous behavior.
---
src/dhcp-common.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
index eae9886..ffc78ca 100644
--- a/src/dhcp-common.c
+++ b/src/dhcp-common.c
@@ -280,14 +280,18 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
{
if (!context) /* called via find_config() from lease_update_from_configs() */
return 1;
-
+
+ /* No address present in config == in context */
+ if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
+ return 1;
+
#ifdef HAVE_DHCP6
if (context->flags & CONTEXT_V6)
{
struct addrlist *addr_list;
if (!(config->flags & CONFIG_ADDR6))
- return 1;
+ return 0;
for (; context; context = context->current)
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
@@ -303,7 +307,7 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
#endif
{
if (!(config->flags & CONFIG_ADDR))
- return 1;
+ return 0;
for (; context; context = context->current)
if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
--
2.25.4

View File

@ -0,0 +1,322 @@
From dd04a0d90d2fca66b5f91952ae7286c5de1714f1 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 7 Feb 2020 21:05:54 +0000
Subject: [PATCH] Add tag filtering of dhcp-host directives.
(cherry picked from commit 52ec7836139e7a11374971905e5ac0d2d02e32c0)
Conflicts:
CHANGELOG
src/rfc3315.c
---
man/dnsmasq.8 | 5 ++++-
src/dhcp-common.c | 42 ++++++++++++++++++++++++++++++++----------
src/dnsmasq.h | 4 +++-
src/lease.c | 2 +-
src/option.c | 14 ++++++--------
src/rfc2131.c | 6 +++---
src/rfc3315.c | 49 ++++++++++++++++++++++---------------------------
7 files changed, 71 insertions(+), 51 deletions(-)
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 2c9d9f6..a59b06f 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -953,7 +953,7 @@ is also included, as described in RFC-3775 section 7.3.
tells dnsmasq to advertise the prefix without the on-link (aka L) bit set.
.TP
-.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
+.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][tag:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
Specify per host parameters for the DHCP server. This allows a machine
with a particular hardware address to be always allocated the same
hostname, IP address and lease time. A hostname specified like this
@@ -1038,6 +1038,9 @@ 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.
+
+The tag:<tag> construct filters which dhcp-host directives are used. Tagged directives are used in preference to untagged ones.
+
Ethernet addresses (but not client-ids) may have
wildcard bytes, so for example
.B --dhcp-host=00:20:e0:3b:13:*,ignore
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
index 5d437dd..71e9e5b 100644
--- a/src/dhcp-common.c
+++ b/src/dhcp-common.c
@@ -304,11 +304,12 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
return 0;
}
-struct dhcp_config *find_config(struct dhcp_config *configs,
- struct dhcp_context *context,
- unsigned char *clid, int clid_len,
- unsigned char *hwaddr, int hw_len,
- int hw_type, char *hostname)
+static struct dhcp_config *find_config_match(struct dhcp_config *configs,
+ struct dhcp_context *context,
+ unsigned char *clid, int clid_len,
+ unsigned char *hwaddr, int hw_len,
+ int hw_type, char *hostname,
+ struct dhcp_netid *tags, int tag_not_needed)
{
int count, new;
struct dhcp_config *config, *candidate;
@@ -320,7 +321,9 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
{
if (config->clid_len == clid_len &&
memcmp(config->clid, clid, clid_len) == 0 &&
- is_config_in_context(context, config))
+ is_config_in_context(context, config) &&
+ match_netid(config->filter, tags, tag_not_needed))
+
return config;
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
@@ -328,7 +331,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
see lease_update_from_configs() */
if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && config->clid_len == clid_len-1 &&
memcmp(config->clid, clid+1, clid_len-1) == 0 &&
- is_config_in_context(context, config))
+ is_config_in_context(context, config) &&
+ match_netid(config->filter, tags, tag_not_needed))
return config;
}
@@ -336,14 +340,16 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
if (hwaddr)
for (config = configs; config; config = config->next)
if (config_has_mac(config, hwaddr, hw_len, hw_type) &&
- is_config_in_context(context, config))
+ is_config_in_context(context, config) &&
+ match_netid(config->filter, tags, tag_not_needed))
return config;
if (hostname && context)
for (config = configs; config; config = config->next)
if ((config->flags & CONFIG_NAME) &&
hostname_isequal(config->hostname, hostname) &&
- is_config_in_context(context, config))
+ is_config_in_context(context, config) &&
+ match_netid(config->filter, tags, tag_not_needed))
return config;
@@ -352,7 +358,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
/* use match with fewest wildcard octets */
for (candidate = NULL, count = 0, config = configs; config; config = config->next)
- if (is_config_in_context(context, config))
+ if (is_config_in_context(context, config) &&
+ match_netid(config->filter, tags, tag_not_needed))
for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
if (conf_addr->wildcard_mask != 0 &&
conf_addr->hwaddr_len == hw_len &&
@@ -366,6 +373,21 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
return candidate;
}
+/* Find tagged configs first. */
+struct dhcp_config *find_config(struct dhcp_config *configs,
+ struct dhcp_context *context,
+ unsigned char *clid, int clid_len,
+ unsigned char *hwaddr, int hw_len,
+ int hw_type, char *hostname, struct dhcp_netid *tags)
+{
+ struct dhcp_config *ret = find_config_match(configs, context, clid, clid_len, hwaddr, hw_len, hw_type, hostname, tags, 0);
+
+ if (!ret)
+ ret = find_config_match(configs, context, clid, clid_len, hwaddr, hw_len, hw_type, hostname, tags, 1);
+
+ return ret;
+}
+
void dhcp_update_configs(struct dhcp_config *configs)
{
/* Some people like to keep all static IP addresses in /etc/hosts.
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 9437226..055a0d1 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -749,6 +749,7 @@ struct dhcp_config {
unsigned char *clid; /* clientid */
char *hostname, *domain;
struct dhcp_netid_list *netid;
+ struct dhcp_netid *filter;
#ifdef HAVE_DHCP6
struct addrlist *addr6;
#endif
@@ -1514,7 +1515,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
struct dhcp_context *context,
unsigned char *clid, int clid_len,
unsigned char *hwaddr, int hw_len,
- int hw_type, char *hostname);
+ int hw_type, char *hostname,
+ struct dhcp_netid *filter);
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
#ifdef HAVE_LINUX_NETWORK
char *whichdevice(void);
diff --git a/src/lease.c b/src/lease.c
index 5c33df7..00c82f6 100644
--- a/src/lease.c
+++ b/src/lease.c
@@ -222,7 +222,7 @@ void lease_update_from_configs(void)
if (lease->flags & (LEASE_TA | LEASE_NA))
continue;
else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
- lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
+ lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL, NULL)) &&
(config->flags & CONFIG_NAME) &&
(!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
diff --git a/src/option.c b/src/option.c
index ea70ee3..88cd2ab 100644
--- a/src/option.c
+++ b/src/option.c
@@ -953,8 +953,7 @@ static char *set_prefix(char *arg)
return arg;
}
-static struct dhcp_netid *
-dhcp_netid_create(const char *net, struct dhcp_netid *next)
+static struct dhcp_netid *dhcp_netid_create(const char *net, struct dhcp_netid *next)
{
struct dhcp_netid *tt;
tt = opt_malloc(sizeof (struct dhcp_netid));
@@ -1019,7 +1018,8 @@ static void dhcp_config_free(struct dhcp_config *config)
}
dhcp_netid_list_free(config->netid);
-
+ dhcp_netid_free(config->filter);
+
if (config->flags & CONFIG_CLID)
free(config->clid);
@@ -3167,6 +3167,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
new->hwaddr = NULL;
new->netid = NULL;
+ new->filter = NULL;
new->clid = NULL;
new->addr6 = NULL;
@@ -3215,11 +3216,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
newlist->list = dhcp_netid_create(arg+4, NULL);
}
else if (strstr(arg, "tag:") == arg)
- {
-
- dhcp_config_free(new);
- ret_err(_("cannot match tags in --dhcp-host"));
- }
+ new->filter = dhcp_netid_create(arg+4, new->filter);
+
#ifdef HAVE_DHCP6
else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
{
diff --git a/src/rfc2131.c b/src/rfc2131.c
index 997575a..a741f9f 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -479,7 +479,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
mess->op = BOOTREPLY;
config = find_config(daemon->dhcp_conf, context, clid, clid_len,
- mess->chaddr, mess->hlen, mess->htype, NULL);
+ mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid));
/* set "known" tag for known hosts */
if (config)
@@ -489,7 +489,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
netid = &known_id;
}
else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len,
- mess->chaddr, mess->hlen, mess->htype, NULL))
+ mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid)))
{
known_id.net = "known-othernet";
known_id.next = netid;
@@ -725,7 +725,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
to avoid impersonation by name. */
struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0,
mess->chaddr, mess->hlen,
- mess->htype, hostname);
+ mess->htype, hostname, run_tag_if(netid));
if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
{
config = new;
diff --git a/src/rfc3315.c b/src/rfc3315.c
index ee58b57..a0067e9 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -486,35 +486,29 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
}
}
- if (state->clid)
+ if (state->clid &&
+ (config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len,
+ state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags))) &&
+ have_config(config, CONFIG_NAME))
{
- config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL);
-
- if (have_config(config, CONFIG_NAME))
- {
- state->hostname = config->hostname;
- state->domain = config->domain;
- state->hostname_auth = 1;
- }
- else if (state->client_hostname)
- {
- state->domain = strip_hostname(state->client_hostname);
+ state->hostname = config->hostname;
+ state->domain = config->domain;
+ state->hostname_auth = 1;
+ }
+ else if (state->client_hostname)
+ {
+ state->domain = strip_hostname(state->client_hostname);
- if (strlen(state->client_hostname) != 0)
- {
- state->hostname = state->client_hostname;
- if (!config)
- {
- /* Search again now we have a hostname.
- Only accept configs without CLID here, (it won't match)
- to avoid impersonation by name. */
- struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname);
- if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
- config = new;
- }
- }
+ if (strlen(state->client_hostname) != 0)
+ {
+ /* Search again now we have a hostname.
+ Only accept configs without CLID here, (it won't match)
+ to avoid impersonation by name. */
+ struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname, run_tag_if(state->tags));
+ if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
+ config = new;
}
- }
+ }
if (config)
{
@@ -535,7 +529,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
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))
+ find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len,
+ state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags)))
{
known_id.net = "known-othernet";
known_id.next = state->tags;
--
1.8.3.1

View File

@ -0,0 +1 @@
u dnsmasq - "Dnsmasq DHCP and DNS server" /var/lib/dnsmasq

9
SOURCES/dnsmasq.service Normal file
View File

@ -0,0 +1,9 @@
[Unit]
Description=DNS caching server.
After=network.target
[Service]
ExecStart=/usr/sbin/dnsmasq -k
[Install]
WantedBy=multi-user.target

659
SPECS/dnsmasq.spec Normal file
View File

@ -0,0 +1,659 @@
%define testrelease 0
%define releasecandidate 0
%if 0%{testrelease}
%define extrapath test-releases/
%define extraversion test%{testrelease}
%endif
%if 0%{releasecandidate}
%define extrapath release-candidates/
%define extraversion rc%{releasecandidate}
%endif
%define _hardened_build 1
Name: dnsmasq
Version: 2.79
Release: 13%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
License: GPLv2 or GPLv3
URL: http://www.thekelleys.org.uk/dnsmasq/
Source0: http://www.thekelleys.org.uk/dnsmasq/%{?extrapath}%{name}-%{version}%{?extraversion}.tar.xz
Source1: %{name}.service
Source2: dnsmasq-systemd-sysusers.conf
# https://bugzilla.redhat.com/show_bug.cgi?id=1495409
Patch1: dnsmasq-2.77-underflow.patch
Patch3: dnsmasq-2.78-fips.patch
Patch4: dnsmasq-2.80-dnssec.patch
Patch5: dnsmasq-2.79-rh1602477.patch
# Few changes not yet in upstream
Patch6: dnsmasq-2.79-rh1602477-2.patch
# commit 60ac10d8d86e6f95ab0f06abe6c42596adcedcb8
Patch7: dnsmasq-2.76-rh1752569.patch
# Report failure when no release would be sent
Patch8: dnsmasq-2.79-rh1749092-fail.patch
Patch9: dnsmasq-2.76-rh1728698-1.patch
Patch10: dnsmasq-2.79-rh1728698-2.patch
Patch11: dnsmasq-2.76-rh1728698-3.patch
Patch12: dnsmasq-2.79-rh1728698-4.patch
Patch13: dnsmasq-2.79-rh1746411.patch
Patch14: dnsmasq-2.79-rh1700916.patch
Patch15: dnsmasq-2.80-rh1795370.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1779187
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=97f876b64c22b2b18412e2e3d8506ee33e42db7c
Patch16: dnsmasq-2.80-unaligned-addresses-in-DHCPv6-packet.patch
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=f064188032a829efdcf3988b24ac795ff52785ec
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=137286e9baecf6a3ba97722ef1b49c851b531810
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=79aba0f10ad0157fb4f48afbbcb03f094caff97a
Patch17: dnsmasq-2.81-prefix-ranges-or-list-of-ipv6-addresses.patch
# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=52ec7836139e7a11374971905e5ac0d2d02e32c0
Patch18: dnsmasq-2.81-tag-filtering-of-dhcp-host-directives.patch
Patch19: dnsmasq-2.81-correct-range-check-of-dhcp-host-prefix.patch
Patch20: dnsmasq-2.81-optimize-fds-close.patch
Patch21: dnsmasq-2.81-rh1829448.patch
# This is workaround to nettle bug #1549190
# https://bugzilla.redhat.com/show_bug.cgi?id=1549190
Requires: nettle >= 3.4
BuildRequires: dbus-devel
BuildRequires: pkgconfig
BuildRequires: libidn2-devel
BuildRequires: nettle-devel
Buildrequires: gcc
BuildRequires: systemd
%{?systemd_requires}
%description
Dnsmasq is lightweight, easy to configure DNS forwarder and DHCP server.
It is designed to provide DNS and, optionally, DHCP, to a small network.
It can serve the names of local machines which are not in the global
DNS. The DHCP server integrates with the DNS server and allows machines
with DHCP-allocated addresses to appear in the DNS with names configured
either in each host or in a central configuration file. Dnsmasq supports
static and dynamic DHCP leases and BOOTP for network booting of diskless
machines.
%package utils
Summary: Utilities for manipulating DHCP server leases
%description utils
Utilities that use the standard DHCP protocol to query/remove a DHCP
server's leases.
%prep
%setup -q -n %{name}-%{version}%{?extraversion}
%patch1 -p1 -b .underflow
%patch3 -p1 -b .fips
%patch4 -p1 -b .dnssec
%patch5 -p1 -b .rh1602477
%patch6 -p1 -b .rh1602477-2
%patch7 -p1 -b .rh1752569
%patch8 -p1 -b .rh1752569
%patch9 -p1 -b .rh1728698-1
%patch10 -p1 -b .rh1728698-2
%patch11 -p1 -b .rh1728698-3
%patch12 -p1 -b .rh1728698-4
%patch13 -p1 -b .rh1746411
%patch14 -p1 -b .rh1700916
%patch15 -p1 -b .rh1795370
%patch16 -p1 -b .rh1779187-1
%patch17 -p1 -b .rh1779187-2
%patch18 -p1 -b .rh1779187-3
%patch19 -p1 -b .rh1779187-4
%patch20 -p1 -b .rh1816613
%patch21 -p1 -b .rh1829448
# use /var/lib/dnsmasq instead of /var/lib/misc
for file in dnsmasq.conf.example man/dnsmasq.8 man/es/dnsmasq.8 src/config.h; do
sed -i 's|/var/lib/misc/dnsmasq.leases|/var/lib/dnsmasq/dnsmasq.leases|g' "$file"
done
# fix the path to the trust anchor
sed -i 's|%%%%PREFIX%%%%|%{_prefix}|' dnsmasq.conf.example
#set dnsmasq user / group
sed -i 's|#user=|user=dnsmasq|' dnsmasq.conf.example
sed -i 's|#group=|group=dnsmasq|' dnsmasq.conf.example
#set default user /group in src/config.h
sed -i 's|#define CHUSER "nobody"|#define CHUSER "dnsmasq"|' src/config.h
sed -i 's|#define CHGRP "dip"|#define CHGRP "dnsmasq"|' src/config.h
# optional parts
sed -i 's|^COPTS[[:space:]]*=|\0 -DHAVE_DBUS -DHAVE_LIBIDN2 -DHAVE_DNSSEC|' Makefile
#enable /etc/dnsmasq.d fix bz 526703, ignore RPM backup files
cat << EOF >> dnsmasq.conf.example
# Include all files in /etc/dnsmasq.d except RPM backup files
conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig
EOF
%build
%make_build CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS"
%make_build -C contrib/lease-tools CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS"
%install
# normally i'd do 'make install'...it's a bit messy, though
mkdir -p $RPM_BUILD_ROOT%{_sbindir} \
$RPM_BUILD_ROOT%{_mandir}/man8 \
$RPM_BUILD_ROOT%{_var}/lib/dnsmasq \
$RPM_BUILD_ROOT%{_sysconfdir}/dnsmasq.d \
$RPM_BUILD_ROOT%{_sysconfdir}/dbus-1/system.d
install src/dnsmasq $RPM_BUILD_ROOT%{_sbindir}/dnsmasq
install dnsmasq.conf.example $RPM_BUILD_ROOT%{_sysconfdir}/dnsmasq.conf
install dbus/dnsmasq.conf $RPM_BUILD_ROOT%{_sysconfdir}/dbus-1/system.d/
install -m 644 man/dnsmasq.8 $RPM_BUILD_ROOT%{_mandir}/man8/
install -D trust-anchors.conf $RPM_BUILD_ROOT%{_datadir}/%{name}/trust-anchors.conf
# utils sub package
mkdir -p $RPM_BUILD_ROOT%{_bindir} \
$RPM_BUILD_ROOT%{_mandir}/man1
install -m 755 contrib/lease-tools/dhcp_release $RPM_BUILD_ROOT%{_bindir}/dhcp_release
install -m 644 contrib/lease-tools/dhcp_release.1 $RPM_BUILD_ROOT%{_mandir}/man1/dhcp_release.1
install -m 755 contrib/lease-tools/dhcp_release6 $RPM_BUILD_ROOT%{_bindir}/dhcp_release6
install -m 644 contrib/lease-tools/dhcp_release6.1 $RPM_BUILD_ROOT%{_mandir}/man1/dhcp_release6.1
install -m 755 contrib/lease-tools/dhcp_lease_time $RPM_BUILD_ROOT%{_bindir}/dhcp_lease_time
install -m 644 contrib/lease-tools/dhcp_lease_time.1 $RPM_BUILD_ROOT%{_mandir}/man1/dhcp_lease_time.1
# Systemd
mkdir -p %{buildroot}%{_unitdir}
install -m644 %{SOURCE1} %{buildroot}%{_unitdir}
rm -rf %{buildroot}%{_initrddir}
#install systemd sysuser file
install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/dnsmasq.conf
%pre
#precreate users so that rpm can install files owned by that user
%sysusers_create_inline %(cat %{SOURCE2})
%post
#https://fedoraproject.org/wiki/Changes/SystemdSysusers
%sysusers_create
%systemd_post dnsmasq.service
%preun
%systemd_preun dnsmasq.service
%postun
%systemd_postun_with_restart dnsmasq.service
%files
%doc CHANGELOG FAQ doc.html setup.html dbus/DBus-interface
%license COPYING COPYING-v3
%defattr(0644,root,dnsmasq,0755)
%config(noreplace) %{_sysconfdir}/dnsmasq.conf
%dir %{_sysconfdir}/dnsmasq.d
%dir %{_var}/lib/dnsmasq
%defattr(-,root,root,-)
%config(noreplace) %{_sysconfdir}/dbus-1/system.d/dnsmasq.conf
%{_unitdir}/%{name}.service
%{_sbindir}/dnsmasq
%{_mandir}/man8/dnsmasq*
%dir %{_datadir}/%{name}
%{_datadir}/%{name}/trust-anchors.conf
%{_sysusersdir}/dnsmasq.conf
%files utils
%license COPYING COPYING-v3
%{_bindir}/dhcp_*
%{_mandir}/man1/dhcp_*
%changelog
* Tue May 05 2020 Petr Menšík <pemensik@redhat.com> - 2.79-13
- Fix mixed address family reservations on DHCP (#1829448)
* Mon Mar 30 2020 Tomas Korbar <tkorbar@redhat.com> - 2.79-12
- Minimize count of close syscalls on startup (#1816613)
* Mon Mar 02 2020 Petr Menšík <pemensik@redhat.com> - 2.79-11
- Support multiple static leases for single mac on IPv6 (#1779187)
* Mon Feb 17 2020 Tomas Korbar <tkorbar@redhat.com> - 2.79-10
- Fix memory leak in helper.c (#1795370)
* Tue Dec 10 2019 Tomas Korbar <tkorbar@redhat.com> - 2.79-9
- Fix replies to non-recursive queries (#1700916)
* Mon Dec 09 2019 Tomas Korbar <tkorbar@redhat.com> - 2.79-8
- Fix dhcp_lease_time (#1746411)
* Mon Dec 09 2019 Tomas Korbar <tkorbar@redhat.com> - 2.79-7
- Fix TCP queries after interface recreation (#1728698)
* Mon Sep 30 2019 Petr Menšík <pemensik@redhat.com> - 2.79-6
- Send dhcp_release even for addresses not on local network (#1749092)
* Thu Jul 18 2019 Petr Menšík <pemensik@redhat.com> - 2.79-5
- Fix Coverity detected issues (#1602477)
* Thu Jul 26 2018 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.79-4
- Fix %%pre scriptlet (#1548050)
* Mon Jul 02 2018 Petr Menšík <pemensik@redhat.com> - 2.79-3
- Make dnsmasq leases writeable by root again (#1554390)
* Mon Jul 02 2018 Petr Menšík <pemensik@redhat.com> - 2.79-2
- Fix passing of dnssec enabled queries (#1597309)
* Thu Mar 15 2018 Petr Menšík <pemensik@redhat.com> - 2.79-1
- Rebase to 2.79
- Stop using nettle_hashes directly, use access function (#1548060)
- Do not break on cname with spaces (#1498667)
- Require nettle 3.4+
- Do not own sysusers.d directory, already depends on systemd providing it
* Fri Mar 02 2018 Petr Menšík <pemensik@redhat.com> - 2.78-7
- Emit warning with dnssec enabled on FIPS system (#1549507)
* Sun Feb 25 2018 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.78-6
- Create user before installing files (#1548050)
* Fri Feb 23 2018 Petr Menšík <pemensik@redhat.com> - 2.78-5
- Create user first and then restart service
* Thu Feb 22 2018 Itamar Reis Peixoto <itamar@ispbrasil.com.br> - 2.78-4
- add gcc into buildrequires
- deliver an extra sysusers.d file to create dnsmasq user/group
- set CHUSER and CHGRP to dnsmasq in src/config.h
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.78-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Mon Jan 22 2018 Petr Menšík <pemensik@redhat.com> - 2.78-2
- DNSSEC fix for wildcard NSEC records (CVE-2017-15107)
* Tue Oct 03 2017 Petr Menšík <pemensik@redhat.com> - 2.78-1
- Rebase to 2.78
* Tue Oct 03 2017 Petr Menšík <pemensik@redhat.com> - 2.77-9
- More patches related to CVE-2017-14491
* Mon Oct 02 2017 Petr Menšík <pemensik@redhat.com> - 2.77-8
- Security fix, CVE-2017-14491, DNS heap buffer overflow
- Security fix, CVE-2017-14492, DHCPv6 RA heap overflow
- Security fix, CVE-2017-14493, DHCPv6 - Stack buffer overflow
- Security fix, CVE-2017-14494, Infoleak handling DHCPv6
- Security fix, CVE-2017-14496, Integer underflow in DNS response creation
- Security fix, CVE-2017-14495, OOM in DNS response creation
- Misc code cleanups arising from Google analysis
- Do not include stdio.h before dnsmasq.h
* Thu Sep 14 2017 Petr Menšík <pemensik@redhat.com> - 2.77-7
- Fix CVE-2017-13704
* Mon Aug 14 2017 Petr Menšík <pemensik@redhat.com> - 2.77-6
- Own the /usr/share/dnsmasq dir (#1480856)
* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.77-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.77-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Wed Jun 07 2017 Petr Menšík <pemensik@redhat.com> - 2.77-3
- Update to 2.77
* Fri May 12 2017 Petr Menšík <pemensik@redhat.com> - 2.77-2.rc2
- Fix dhcp
* Thu May 11 2017 Petr Menšík <pemensik@redhat.com> - 2.77-1
- Update to 2.77rc2
* Thu May 11 2017 Petr Menšík <pemensik@redhat.com>
- Include dhcp_release6 tool and license in utils
- Support for IDN 2008 (#1449150)
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.76-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Wed Oct 19 2016 Pavel Šimerda <psimerda@redhat.com> - 2.76-2
- Resolves: #1373485 - dns not updated after sleep and resume laptop
* Fri Jul 15 2016 Pavel Šimerda <psimerda@redhat.com> - 2.76-1
- New version 2.76
* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 2.75-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Mon Jan 25 2016 Tomas Hozza <thozza@redhat.com> - 2.75-3
- Fixed minor bug in dnsmasq.conf (#1295143)
* Fri Oct 02 2015 Pavel Šimerda <psimerda@redhat.com> - 2.75-2
- Resolves: #1239256 - install trust-anchors.conf
* Wed Aug 05 2015 Pavel Šimerda <psimerda@redhat.com> - 2.75-1
- new version 2.75
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.72-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Mon Oct 06 2014 Nils Philippsen <nils@redhat.com> - 2.72-3
- don't include /etc/dnsmasq.d in triplicate, ignore RPM backup files instead
- package is dual-licensed GPL v2 or v3
- drop %%triggerun, we're not supposed to automatically migrate from SysV to
systemd anyway
* Mon Oct 06 2014 Tomas Hozza <thozza@redhat.com> - 2.72-2
- Fix typo in default configuration (#1149459)
* Thu Sep 25 2014 Tomas Hozza <thozza@redhat.com> - 2.72-1
- Update to 2.72 stable
* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.71-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.71-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Tue May 20 2014 Tomas Hozza <thozza@redhat.com> - 2.71-1
- Update to 2.71 stable
* Fri Apr 25 2014 Tomas Hozza <thozza@redhat.com> - 2.70-1
- Update to 2.70 stable
* Fri Apr 11 2014 Tomas Hozza <thozza@redhat.com> - 2.69-1
- Update to 2.69 stable
* Mon Mar 24 2014 Tomas Hozza <thozza@redhat.com> - 2.69-0.1.rc1
- Update to 2.69rc1
- enable DNSSEC implementation
* Mon Dec 09 2013 Tomas Hozza <thozza@redhat.com> - 2.68-1
- Update to 2.68 stable
* Tue Nov 26 2013 Tomas Hozza <thozza@redhat.com> - 2.68-0.1.rc3
- Update to 2.68rc3
* Fri Nov 01 2013 Tomas Hozza <thozza@redhat.com> - 2.67-1
- Update to 2.67 stable
- Include one post release upstream fix for CNAME
* Fri Oct 18 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.9.rc4
- update to 2.67rc4
* Wed Oct 02 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.8.rc2
- update to 2.67rc2
* Thu Sep 12 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.7.test13
- update to 2.67test13
- use .tar.xz upstream archives
* Thu Aug 15 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.6.test7
- Use SO_REUSEPORT and SO_REUSEADDR if possible for DHCPv4/6 (#981973)
* Mon Aug 12 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.5.test7
- Don't use SO_REUSEPORT on DHCPv4 socket to prevent conflicts with ISC DHCP (#981973)
* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.67-0.4.test7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
* Tue Jun 11 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.3.test7
- update to 2.67test7
- drop merged patch
- use _hardened_build macro instead of hardcoded flags
* Fri May 17 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.2.test4
- Fix failure to start with ENOTSOCK (#962874)
* Wed May 15 2013 Tomas Hozza <thozza@redhat.com> - 2.67-0.1.test4
- update to the latest testing release 2.67test4 (#962246)
- drop mergerd patches
* Tue Apr 30 2013 Tomas Hozza <thozza@redhat.com> - 2.66-5
- dnsmasq unit file cleanup
- drop forking Type and PIDfile and rather start dnsmasq with "-k" option
- drop After syslog.target as this is by default
* Thu Apr 25 2013 Tomas Hozza <thozza@redhat.com> - 2.66-4
- include several fixes from upstream repo:
- Send TCP DNS messages in one packet
- Fix crash on SERVFAIL when using --conntrack option
- Fix regression in dhcp_lease_time utility
- Man page typos fixes
- Note that dhcp_lease_time and dhcp_release work only for IPv4
- Fix for --dhcp-match option to work also with BOOTP protocol
* Sat Apr 20 2013 Tomas Hozza <thozza@redhat.com> - 2.66-3
- Use Full RELRO when linking the daemon
- compile the daemon with PIE
- include two fixes from upstream git repo
* Thu Apr 18 2013 Tomas Hozza <thozza@redhat.com> - 2.66-2
- New stable version dnsmasq-2.66
- Drop of merged patch
* Fri Apr 12 2013 Tomas Hozza <thozza@redhat.com> - 2.66-1.rc5
- Update to latest dnsmasq-2.66rc5
- Include fix for segfault when lease limit is reached
* Fri Mar 22 2013 Tomas Hozza <thozza@redhat.com> - 2.66-1.rc1
- Update to latest dnsmasq-2.66rc1
- Dropping unneeded patches
- Enable IDN support
* Fri Mar 15 2013 Tomas Hozza <thozza@redhat.com> - 2.65-5
- Allocate dhcp_buff-ers also if daemon->ra_contexts to prevent SIGSEGV (#920300)
* Thu Jan 31 2013 Tomas Hozza <thozza@redhat.com> - 2.65-4
- Handle locally-routed DNS Queries (#904940)
* Thu Jan 24 2013 Tomas Hozza <thozza@redhat.com> - 2.65-3
- build dnsmasq with $RPM_OPT_FLAGS, $RPM_LD_FLAGS explicitly (#903362)
* Tue Jan 22 2013 Tomas Hozza <thozza@redhat.com> - 2.65-2
- Fix for CVE-2013-0198 (checking of TCP connection interfaces) (#901555)
* Sat Dec 15 2012 Tomas Hozza <thozza@redhat.com> - 2.65-1
- new version 2.65
* Wed Dec 05 2012 Tomas Hozza <thozza@redhat.com> - 2.64-1
- New version 2.64
- Merged patches dropped
* Tue Nov 20 2012 Tomas Hozza <thozza@redhat.com> - 2.63-4
- Remove EnvironmentFile from service file (#878343)
* Mon Nov 19 2012 Tomas Hozza <thozza@redhat.com> - 2.63-3
- dhcp6 support fixes (#867054)
- removed "-s $HOSTNAME" from .service file (#753656, #822797)
* Tue Oct 23 2012 Tomas Hozza <thozza@redhat.com> - 2.63-2
- Introduce new systemd-rpm macros in dnsmasq spec file (#850096)
* Thu Aug 23 2012 Douglas Schilling Landgraf <dougsland@redhat.com> - 2.63-1
- Use .tar.gz compression, in upstream site there is no .lzma anymore
- New version 2.63
* Sat Feb 11 2012 Pádraig Brady <P@draigBrady.com> - 2.59-5
- Compile DHCP lease management utils with RPM_OPT_FLAGS
* Thu Feb 9 2012 Pádraig Brady <P@draigBrady.com> - 2.59-4
- Include DHCP lease management utils in a subpackage
* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.59-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
* Fri Aug 26 2011 Douglas Schilling Landgraf <dougsland@redhat.com> - 2.59-2
- do not enable service by default
* Fri Aug 26 2011 Douglas Schilling Landgraf <dougsland@redhat.com> - 2.59-1
- New version 2.59
- Fix regression in 2.58 (IPv6 issue) - bz 744814
* Fri Aug 26 2011 Douglas Schilling Landgraf <dougsland@redhat.com> - 2.58-1
- Fixed License
- New version 2.58
* Mon Aug 08 2011 Patrick "Jima" Laughton <jima@fedoraproject.org> - 2.52-5
- Include systemd unit file
* Mon Aug 08 2011 Patrick "Jima" Laughton <jima@fedoraproject.org> - 2.52-3
- Applied Jóhann's patch, minor cleanup
* Tue Jul 26 2011 Jóhann B. Guðmundsson <johannbg@gmail.com> - 2.52-3
- Introduce systemd unit file, drop SysV support
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.52-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
* Tue Jan 26 2010 Itamar Reis Peixoto <itamar@ispbrasil.com.br> - 2.52-1
- New Version 2.52
- fix condrestart() in initscript bz 547605
- fix sed to enable DBUS(the '*' need some escaping) bz 553161
* Sun Nov 22 2009 Itamar Reis Peixoto <itamar@ispbrasil.com.br> - 2.51-2
- fix bz 512664
* Sat Oct 17 2009 Itamar Reis Peixoto <itamar@ispbrasil.com.br> - 2.51-1
- move initscript from patch to a plain text file
- drop (dnsmasq-configuration.patch) and use sed instead
- enable /etc/dnsmasq.d fix bz 526703
- change requires to package name instead of file
- new version 2.51
* Mon Oct 5 2009 Mark McLoughlin <markmc@redhat.com> - 2.48-4
- Fix multiple TFTP server vulnerabilities (CVE-2009-2957, CVE-2009-2958)
* Wed Aug 12 2009 Ville Skyttä <ville.skytta@iki.fi> - 2.48-3
- Use lzma compressed upstream tarball.
* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.48-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
* Wed Jun 10 2009 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.48-1
- Bugfix/feature enhancement update
- Fixing BZ#494094
* Fri May 29 2009 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.47-1
- Bugfix/feature enhancement update
* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.46-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Mon Dec 29 2008 Matěj Cepl <mcepl@redhat.com> - 2.45-2
- rebuilt
* Mon Jul 21 2008 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.45-1
- Upstream release (bugfixes)
* Wed Jul 16 2008 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.43-2
- New upstream release, contains fixes for CVE-2008-1447/CERT VU#800113
- Dropped patch for newer glibc (merged upstream)
* Wed Feb 13 2008 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.41-0.8
- Added upstream-authored patch for newer glibc (thanks Simon!)
* Wed Feb 13 2008 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.41-0.7
- New upstream release
* Wed Jan 30 2008 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.41-0.6.rc1
- Release candidate
- Happy Birthday Isaac!
* Wed Jan 23 2008 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.41-0.5.test30
- Bugfix update
* Mon Dec 31 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.41-0.4.test26
- Bugfix/feature enhancement update
* Thu Dec 13 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.41-0.3.test24
- Upstream fix for fairly serious regression
* Tue Dec 04 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.41-0.2.test20
- New upstream test release
- Moving dnsmasq.leases to /var/lib/dnsmasq/ as per BZ#407901
- Ignoring dangerous-command-in-%%post rpmlint warning (as per above fix)
- Patch consolidation/cleanup
- Removed conditionals for Fedora <= 3 and Aurora 2.0
* Tue Sep 18 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.40-1
- Finalized upstream release
- Removing URLs from patch lines (CVS is the authoritative source)
- Added more magic to make spinning rc/test packages more seamless
* Sun Aug 26 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.40-0.1.rc2
- New upstream release candidate (feature-frozen), thanks Simon!
- License clarification
* Tue May 29 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.39-1
- New upstream version (bugfixes, enhancements)
* Mon Feb 12 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.38-1
- New upstream version with bugfix for potential hang
* Tue Feb 06 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.37-1
- New upstream version
* Wed Jan 24 2007 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.36-1
- New upstream version
* Mon Nov 06 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.35-2
- Stop creating /etc/sysconfig on %%install
- Create /etc/dnsmasq.d on %%install
* Mon Nov 06 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.35-1
- Update to 2.35
- Removed UPGRADING_to_2.0 from %%doc as per upstream change
- Enabled conf-dir in default config as per RFE BZ#214220 (thanks Chris!)
- Added %%dir /etc/dnsmasq.d to %%files as per above RFE
* Tue Oct 24 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.34-2
- Fixed BZ#212005
- Moved %%postun scriptlet to %%post, where it made more sense
- Render scriptlets safer
- Minor cleanup for consistency
* Thu Oct 19 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.34-1
- Hardcoded version in patches, as I'm getting tired of updating them
- Update to 2.34
* Mon Aug 28 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.33-2
- Rebuild for FC6
* Tue Aug 15 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.33-1
- Update
* Sat Jul 22 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.32-3
- Added pkgconfig BuildReq due to reduced buildroot
* Thu Jul 20 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.32-2
- Forced update due to dbus version bump
* Mon Jun 12 2006 Patrick "Jima" Laughton <jima@beer.tclug.org> 2.32-1
- Update from upstream
- Patch from Dennis Gilmore fixed the conditionals to detect Aurora Linux
* Mon May 8 2006 Patrick "Jima" Laughton <jima@auroralinux.org> 2.31-1
- Removed dbus config patch (now provided upstream)
- Patched in init script (no longer provided upstream)
- Added DBus-interface to docs
* Tue May 2 2006 Patrick "Jima" Laughton <jima@auroralinux.org> 2.30-4.2
- More upstream-recommended cleanups :)
- Killed sysconfig file (provides unneeded functionality)
- Tweaked init script a little more
* Tue May 2 2006 Patrick "Jima" Laughton <jima@auroralinux.org> 2.30-4
- Moved options out of init script and into /etc/sysconfig/dnsmasq
- Disabled DHCP_LEASE in sysconfig file, fixing bug #190379
- Simon Kelley provided dbus/dnsmasq.conf, soon to be part of the tarball
* Thu Apr 27 2006 Patrick "Jima" Laughton <jima@auroralinux.org> 2.30-3
- Un-enabled HAVE_ISC_READER, a hack to enable a deprecated feature (request)
- Split initscript & enable-dbus patches, conditionalized dbus for FC3
- Tweaked name field in changelog entries (trying to be consistent)
* Mon Apr 24 2006 Patrick "Jima" Laughton <jima@auroralinux.org> 2.30-2
- Disabled stripping of binary while installing (oops)
- Enabled HAVE_ISC_READER/HAVE_DBUS via patch
- Added BuildReq for dbus-devel
* Mon Apr 24 2006 Patrick "Jima" Laughton <jima@auroralinux.org> 2.30-1
- Initial Fedora Extras RPM