Compare commits

...

7 Commits

Author SHA1 Message Date
Simon Kelley
4441cf762c Fix DNS server fd garbage collection.
If we're talking to upstream servers from a fixed port, specified by query-port
we create the fds to do this once, before dropping root, so that ports <1024 can be used.

But we call check_servers() before reading /etc/resolv.conf, so if the only servers
are in resolv.conf, at that point there will be no servers, and the fds get garbage
collected away, only to be recreated (but without root) after we read /etc/resolv.conf

Make pre-allocated server fds immortal, to avoid this problem.
2018-04-10 21:39:54 +01:00
Simon Kelley
e83915d10d Set V6ONLY on DNS upstream socket.
If query-port is set, we create sockets bound to the wildcard address and the query port for
IPv4 and IPv6, but the IPv6 one fails, because is covers IPv4 as well, and an IPv4 socket
already exists (it gets created first). Set V6ONLY to avoid this.
2018-04-10 21:27:26 +01:00
Kevin Darbyshire-Bryant
6d37924b86 Makefile: Stop creating '-d' directory
Install-common section was creating superfluous '-d' directory in build
location.

Split the directory creation into individual install commands to cope
with cross platform differences of interpreting subsequent '-d'
arguments.  e.g. GNU appears to be fine.  Apple creates the stray
directory.

Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
2018-04-07 23:00:56 +01:00
Simon Kelley
f3d7974e86 Fixed bug number in changelog s/833596/883596/ 2018-03-26 13:23:59 +01:00
Simon Kelley
734d53176f Add RFC4039 rapid commit support. 2018-03-23 23:09:53 +00:00
Simon Kelley
9a7be47614 Add lintian override in Debian package. 2018-03-23 20:45:53 +00:00
Simon Kelley
26e27d0015 Symbolic link for /usr/share/doc/dnsmasq-base-lua in Debian package. 2018-03-18 17:29:12 +00:00
13 changed files with 74 additions and 19 deletions

View File

@@ -1,3 +1,8 @@
version 2.80
Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
for the initial patch and motivation.
version 2.79
Fix parsing of CNAME arguments, which are confused by extra spaces.
Thanks to Diego Aguirre for spotting the bug.

View File

@@ -100,7 +100,8 @@ clean : mostly_clean
install : all install-common
install-common :
$(INSTALL) -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -d $(DESTDIR)$(BINDIR)
$(INSTALL) -d $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR)

2
debian/changelog vendored
View File

@@ -2,7 +2,7 @@ dnsmasq (2.79-1) unstable; urgency=low
* New upstream. (closes: #888200)
* Fix trust-anchor regex in init script. (closes: #884347)
* Fix exit code for dhcp_release6 (closes: #833596)
* Fix exit code for dhcp_release6 (closes: #883596)
* Add project homepage to control file. (closes: #887764)
* New binary package dnsmasq-base-lua, includes Lua support.
* Remove hardwired shlibs dependency for libnettle 3.3 and

3
debian/lintian-override vendored Normal file
View File

@@ -0,0 +1,3 @@
# dnsmasq-base and dnsmasq-base-lua are mutually exclusive and both
# provide /usr/share/doc/dnsmasq-base
dnsmasq-base-lua binary: usr-share-doc-symlink-without-dependency dnsmasq-base

3
debian/rules vendored
View File

@@ -217,9 +217,12 @@ else
rm -rf debian/trees/lua-base/usr/share/man
endif
$(call add_files,debian/trees/lua-base)
install -m 755 -d debian/trees/lua-base/usr/share/lintian/overrides
install -m 644 debian/lintian-override debian/trees/lua-base/usr/share/lintian/overrides/dnsmasq-base-lua
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/trees/lua-base/usr/sbin/dnsmasq
endif
ln -s $(package) debian/trees/lua-base/usr/share/doc/dnsmasq-base-lua
cd debian/trees/lua-base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-shlibdeps --warnings=1 debian/trees/lua-base/usr/sbin/dnsmasq
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base-lua -Pdebian/trees/lua-base

View File

@@ -547,6 +547,14 @@
# http://www.isc.org/files/auth.html
#dhcp-authoritative
# Set the DHCP server to enable DHCPv4 Rapid Commit Option per RFC 4039.
# In this mode it will respond to a DHCPDISCOVER message including a Rapid Commit
# option with a DHCPACK including a Rapid Commit option and fully committed address
# and configuration information. This must only be enabled if either the server is
# the only server for the subnet, or multiple servers are present and they each
# commit a binding for all clients.
#dhcp-rapid-commit
# Run an executable when a DHCP lease is created or destroyed.
# The arguments sent to the script are "add" or "del",
# then the MAC address, the IP address and finally the hostname

View File

@@ -1452,6 +1452,13 @@ allows dnsmasq to rebuild its lease database without each client needing to
reacquire a lease, if the database is lost. For DHCPv6 it sets the
priority in replies to 255 (the maximum) instead of 0 (the minimum).
.TP
.B --dhcp-rapid-commit
Enable DHCPv4 Rapid Commit Option specified in RFC 4039. When enabled, dnsmasq
will respond to a DHCPDISCOVER message including a Rapid Commit
option with a DHCPACK including a Rapid Commit option and fully committed
address and configuration information. Should only be enabled if either the
server is the only server for the subnet, or multiple servers are present and they each commit a binding for all clients.
.TP
.B --dhcp-alternate-port[=<server port>[,<client port>]]
(IPv4 only) Change the ports used for DHCP from the default. If this option is
given alone, without arguments, it changes the ports used for DHCP

View File

@@ -556,6 +556,7 @@ static const struct opttab_t {
{ "nntp-server", 71, OT_ADDR_LIST },
{ "irc-server", 74, OT_ADDR_LIST },
{ "user-class", 77, 0 },
{ "rapid-commit", 80, 0 },
{ "FQDN", 81, OT_INTERNAL },
{ "agent-id", 82, OT_INTERNAL },
{ "client-arch", 93, 2 | OT_DEC },

View File

@@ -54,6 +54,7 @@
#define OPTION_SNAME 66
#define OPTION_FILENAME 67
#define OPTION_USER_CLASS 77
#define OPTION_RAPID_COMMIT 80
#define OPTION_CLIENT_FQDN 81
#define OPTION_AGENT_ID 82
#define OPTION_ARCH 93

View File

@@ -250,7 +250,8 @@ struct event_desc {
#define OPT_MAC_B64 54
#define OPT_MAC_HEX 55
#define OPT_TFTP_APREF_MAC 56
#define OPT_LAST 57
#define OPT_RAPID_COMMIT 57
#define OPT_LAST 58
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
@@ -505,7 +506,7 @@ struct serverfd {
int fd;
union mysockaddr source_addr;
char interface[IF_NAMESIZE+1];
unsigned int ifindex, used;
unsigned int ifindex, used, preallocated;
struct serverfd *next;
};

View File

@@ -1234,7 +1234,8 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
struct serverfd *sfd;
unsigned int ifindex = 0;
int errsave;
int opt = 1;
/* when using random ports, servers which would otherwise use
the INADDR_ANY/port0 socket have sfd set to NULL */
if (!daemon->osport && intname[0] == 0)
@@ -1274,10 +1275,11 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
free(sfd);
return NULL;
}
if (!local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd))
if ((addr->sa.sa_family == AF_INET6 && setsockopt(sfd->fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1) ||
!local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd))
{
errsave = errno; /* save error from bind. */
errsave = errno; /* save error from bind/setsockopt. */
close(sfd->fd);
free(sfd);
errno = errsave;
@@ -1288,6 +1290,7 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
sfd->source_addr = *addr;
sfd->next = daemon->sfds;
sfd->ifindex = ifindex;
sfd->preallocated = 0;
daemon->sfds = sfd;
return sfd;
@@ -1298,6 +1301,7 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
void pre_allocate_sfds(void)
{
struct server *srv;
struct serverfd *sfd;
if (daemon->query_port != 0)
{
@@ -1309,7 +1313,8 @@ void pre_allocate_sfds(void)
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in.sin_len = sizeof(struct sockaddr_in);
#endif
allocate_sfd(&addr, "");
if ((sfd = allocate_sfd(&addr, "")))
sfd->preallocated = 1;
#ifdef HAVE_IPV6
memset(&addr, 0, sizeof(addr));
addr.in6.sin6_family = AF_INET6;
@@ -1318,7 +1323,8 @@ void pre_allocate_sfds(void)
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
#endif
allocate_sfd(&addr, "");
if ((sfd = allocate_sfd(&addr, "")))
sfd->preallocated = 1;
#endif
}
@@ -1471,9 +1477,10 @@ void check_servers(void)
/* interface may be new since startup */
if (!option_bool(OPT_NOWILD))
enumerate_interfaces(0);
/* don't garbage collect pre-allocated sfds. */
for (sfd = daemon->sfds; sfd; sfd = sfd->next)
sfd->used = 0;
sfd->used = sfd->preallocated;
for (count = 0, serv = daemon->servers; serv; serv = serv->next)
{

View File

@@ -160,6 +160,7 @@ struct myoption {
#define LOPT_DHCPTTL 348
#define LOPT_TFTP_MTU 349
#define LOPT_REPLY_DELAY 350
#define LOPT_RAPID_COMMIT 351
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -325,6 +326,7 @@ static const struct myoption opts[] =
{ "script-arp", 0, 0, LOPT_SCRIPT_ARP },
{ "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
{ "dhcp-reply-delay", 1, 0, LOPT_REPLY_DELAY },
{ "dhcp-rapid-commit", 0, 0, LOPT_RAPID_COMMIT },
{ NULL, 0, 0, 0 }
};
@@ -497,6 +499,7 @@ static struct {
{ LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL },
{ LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL },
{ LOPT_REPLY_DELAY, ARG_ONE, "<integer>", gettext_noop("Delay DHCP replies for at least number of seconds."), NULL },
{ LOPT_RAPID_COMMIT, OPT_RAPID_COMMIT, NULL, gettext_noop("Enables DHCPv4 Rapid Commit option."), NULL },
{ 0, 0, NULL, NULL, NULL }
};

View File

@@ -75,7 +75,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
struct dhcp_vendor *vendor;
struct dhcp_mac *mac;
struct dhcp_netid_list *id_list;
int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0, pxearch = -1;
int clid_len = 0, ignore = 0, do_classes = 0, rapid_commit = 0, selecting = 0, pxearch = -1;
struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
unsigned char *end = (unsigned char *)(mess + 1);
unsigned char *real_end = (unsigned char *)(mess + 1);
@@ -1073,6 +1073,13 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
log_tags(tagif_netid, ntohl(mess->xid));
apply_delay(mess->xid, recvtime, tagif_netid);
if (option_bool(OPT_RAPID_COMMIT) && option_find(mess, sz, OPTION_RAPID_COMMIT, 0))
{
rapid_commit = 1;
goto rapid_commit;
}
log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
@@ -1085,7 +1092,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
return dhcp_packet_size(mess, agent_id, real_end);
case DHCPREQUEST:
if (ignore || have_config(config, CONFIG_DISABLE))
return 0;
@@ -1183,9 +1191,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
fuzz = rand16();
mess->yiaddr = mess->ciaddr;
}
log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
rapid_commit:
if (!message)
{
struct dhcp_config *addr_config;
@@ -1256,7 +1265,11 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
if (message)
{
log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
log_packet(rapid_commit ? "NOANSWER" : "DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
/* rapid commit case: lease allocate failed but don't send DHCPNAK */
if (rapid_commit)
return 0;
mess->yiaddr.s_addr = 0;
clear_packet(mess, end);
@@ -1414,12 +1427,14 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
override = lease->override;
log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
clear_packet(mess, end);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
option_put(mess, end, OPTION_LEASE_TIME, 4, time);
do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
if (rapid_commit)
option_put(mess, end, OPTION_RAPID_COMMIT, 0, 0);
do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
}