Compare commits

...
10 Commits
20 changed files with 191 additions and 94 deletions

No files matched your search

+21
View File
@@ -1,3 +1,16 @@
version 2.64
Handle DHCP FQDN options with all flag bits zero and
--dhcp-client-update set. Thanks to Bernd Krumbroeck for
spotting the problem.
Finesse the check for /etc/hosts names which conflict with
DHCP names. Previously a name/address pair in /etc/hosts
which didn't match the name/address of a DHCP lease would
generate a warning. Now that only happesn if there is not
also a match. This allows multiple addresses for a name in
/etc/hosts with one of them assigned via DHCP.
version 2.63
Do duplicate dhcp-host address check in --test mode.
@@ -40,6 +53,14 @@ version 2.63
Update French translation. Thanks to Gildas Le Nadan.
Allow a DBus service name to be given with --enable-dbus
which overrides the default,
uk.org.thekelleys.dnsmasq. Thanks to Mathieu
Trudel-Lapierre for the patch.
Set the "prefix on-link" bit in Router
Advertisements. Thanks to Gui Iribarren for the patch.
version 2.62
Update German translation. Thanks to Conrad Kostecki.
+3 -1
View File
@@ -8,6 +8,8 @@
# which has a set of references substituted into it by git.
# If we can find one which matches $v[0-9].* then we assume it's
# a version-number tag, else we just use the whole string.
# If there is more than one v[0-9].* tag, sort them and use the
# first. This favours, eg v2.63 over 2.63rc6.
if which git >/dev/null 2>&1 && [ -d $1/.git ]; then
cd $1; git describe
@@ -18,7 +20,7 @@ else
vers=`cat $1/VERSION | sed 's/[(), ]/,/ g' | tr ',' '\n' | grep $v[0-9]`
if [ $? -eq 0 ]; then
echo "${vers}" | head -n 1 | sed 's/^v//'
echo "${vers}" | sort | head -n 1 | sed 's/^v//'
else
cat $1/VERSION
fi
+2 -1
View File
@@ -19,7 +19,8 @@ and avoids startup races with the provider of nameserver information.
Dnsmasq provides one service on the DBus: uk.org.thekelleys.dnsmasq
and a single object: /uk/org/thekelleys/dnsmasq
and a single object: /uk/org/thekelleys/dnsmasq
The name of the service may be changed by giving an argument to --enable-dbus.
1. METHODS
----------
+16
View File
@@ -1,3 +1,19 @@
dnsmasq (2.64-1) unstable; urgency=low
* New upstream.
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 28 Aug 2012 16:19:15 +0000
dnsmasq (2.63-2) unstable; urgency=low
* Fix version script to report correct version.
* Unbotch move of dbus config file by using correct versions in
Replaces: and Breaks: lines. (closes: #685204)
* Create dnsmasq user in dnsmasq-base so that Dbus doesn't complain if
only dnsmasq-base is installed. (closes: #685987)
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 28 Aug 2012 16:18:35 +0000
dnsmasq (2.63-1) unstable; urgency=low
* New upstream.
+2 -2
View File
@@ -23,8 +23,8 @@ Description: Small caching DNS proxy and DHCP/TFTP server
Package: dnsmasq-base
Architecture: any
Depends: ${shlibs:Depends}
Breaks: dnsmasq (<< 2.62-3)
Replaces: dnsmasq (<< 2.62-3)
Breaks: dnsmasq (<< 2.63-1~)
Replaces: dnsmasq (<< 2.63-1~)
Description: Small caching DNS proxy and DHCP/TFTP server
This package contains the dnsmasq executable and documentation, but
not the infrastructure required to run it as a system daemon. For
+24
View File
@@ -0,0 +1,24 @@
#!/bin/sh
set -e
# Create the dnsmasq user in dnsmasq-base, so that Dbus doesn't complain.
# create a user to run as (code stolen from dovecot-common)
if [ "$1" = "configure" ]; then
if [ -z "`id -u dnsmasq 2> /dev/null`" ]; then
adduser --system --home /var/lib/misc --gecos "dnsmasq" \
--no-create-home --disabled-password \
--quiet dnsmasq || true
fi
# Make the directory where we keep the pid file - this
# has to be owned by "dnsmasq" so that the file can be unlinked.
# This is only actually used by the dnsmasq binary package, not
# dnsmasq-base, but it's much easier to create it here so that
# we don't have synchronisation issues with the creation of the
# dnsmasq user.
if [ ! -d /var/run/dnsmasq ]; then
mkdir /var/run/dnsmasq
chown dnsmasq:nogroup /var/run/dnsmasq
fi
fi
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
set -e
if [ purge = "$1" ]; then
if [ -x "$(command -v deluser)" ]; then
deluser --quiet --system dnsmasq > /dev/null || true
else
echo >&2 "not removing dnsmasq system account because deluser command was not found"
fi
rm -rf /var/run/dnsmasq
fi
-27
View File
@@ -1,27 +1,6 @@
#!/bin/sh
set -e
# create a user to run as (code stolen from dovecot-common)
if [ "$1" = "configure" ]; then
if [ -z "`id -u dnsmasq 2> /dev/null`" ]; then
adduser --system --home /var/lib/misc --gecos "dnsmasq" \
--no-create-home --disabled-password \
--quiet dnsmasq || true
fi
# Make the directory where we keep the pid file - this
# has to be owned by "dnsmasq" do that the file can be unlinked.
if [ ! -d /var/run/dnsmasq ]; then
mkdir /var/run/dnsmasq
chown dnsmasq:nogroup /var/run/dnsmasq
fi
# handle new location of pidfile during an upgrade
if [ -e /var/run/dnsmasq.pid ]; then
mv /var/run/dnsmasq.pid /var/run/dnsmasq
fi
fi
if [ -x /etc/init.d/dnsmasq ]; then
update-rc.d dnsmasq defaults 15 85 >/dev/null
@@ -40,10 +19,4 @@ if [ -x /etc/init.d/dnsmasq ]; then
fi
fi
# dpkg can botch the change of /usr/share/doc/dnsmasq from
# directory to symlink. Fix up here.
if [ ! -h /usr/share/doc/dnsmasq ] && { rmdir /usr/share/doc/dnsmasq; }; then
cd /usr/share/doc/
ln -s /usr/share/doc/dnsmasq-base dnsmasq
fi
-6
View File
@@ -3,10 +3,4 @@ set -e
if [ purge = "$1" ]; then
update-rc.d dnsmasq remove >/dev/null
if [ -x "$(command -v deluser)" ]; then
deluser --quiet --system dnsmasq > /dev/null || true
else
echo >&2 "not removing dnsmasq system account because deluser command was not found"
fi
rm -rf /var/run/dnsmasq
fi
+2
View File
@@ -129,6 +129,8 @@ ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS)))
gzip -9 debian/base/usr/share/doc/$(package)/DBus-interface
endif
install -m 644 debian/dnsmasq-base.conffiles debian/base/DEBIAN/conffiles
install -m 755 debian/dnsmasq-base.postinst debian/base/DEBIAN/postinst
install -m 755 debian/dnsmasq-base.postrm debian/base/DEBIAN/postrm
install -m 644 debian/changelog debian/base/usr/share/doc/$(package)/changelog.Debian
gzip -9 debian/base/usr/share/doc/$(package)/changelog.Debian
install -m 644 debian/readme debian/base/usr/share/doc/$(package)/README.Debian
+4 -2
View File
@@ -271,11 +271,13 @@ time is the one used.
Don't read /etc/resolv.conf. Get upstream servers only from the command
line or the dnsmasq configuration file.
.TP
.B \-1, --enable-dbus
.B \-1, --enable-dbus[=<service-name>]
Allow dnsmasq configuration to be updated via DBus method calls. The
configuration which can be changed is upstream DNS servers (and
corresponding domains) and cache clear. Requires that dnsmasq has
been built with DBus support.
been built with DBus support. If the service name is given, dnsmasq
provides service at that name, rather than the default which is
.B uk.org.thekelleys.dnsmasq
.TP
.B \-o, --strict-order
By default, dnsmasq will send queries to any of the upstream servers
+34 -28
View File
@@ -1042,7 +1042,7 @@ static void add_dhcp_cname(struct crec *target, time_t ttd)
void cache_add_dhcp_entry(char *host_name, int prot,
struct all_addr *host_address, time_t ttd)
{
struct crec *crec = NULL;
struct crec *crec = NULL, *fail_crec = NULL;
unsigned short flags = F_IPV4;
int in_hosts = 0;
size_t addrlen = sizeof(struct in_addr);
@@ -1055,28 +1055,21 @@ void cache_add_dhcp_entry(char *host_name, int prot,
}
#endif
inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME)))
{
/* check all addresses associated with name */
if (crec->flags & F_HOSTS)
{
/* if in hosts, don't need DHCP record */
in_hosts = 1;
inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
if (crec->flags & F_CNAME)
my_syslog(MS_DHCP | LOG_WARNING,
_("%s is a CNAME, not giving it to the DHCP lease of %s"),
host_name, daemon->addrbuff);
else if (memcmp(&crec->addr.addr, host_address, addrlen) != 0)
{
inet_ntop(prot, &crec->addr.addr, daemon->namebuff, MAXDNAME);
my_syslog(MS_DHCP | LOG_WARNING,
_("not giving name %s to the DHCP lease of %s because "
"the name exists in %s with address %s"),
host_name, daemon->addrbuff,
record_source(crec->uid), daemon->namebuff);
}
else if (memcmp(&crec->addr.addr, host_address, addrlen) == 0)
in_hosts = 1;
else
fail_crec = crec;
}
else if (!(crec->flags & F_DHCP))
{
@@ -1086,21 +1079,34 @@ void cache_add_dhcp_entry(char *host_name, int prot,
}
}
if (in_hosts)
/* if in hosts, don't need DHCP record */
if (in_hosts)
return;
if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, flags)))
{
if (crec->flags & F_NEG)
{
flags |= F_REVERSE;
cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags);
}
}
else
flags |= F_REVERSE;
if ((crec = dhcp_spare))
/* Name in hosts, address doesn't match */
if (fail_crec)
{
inet_ntop(prot, &fail_crec->addr.addr, daemon->namebuff, MAXDNAME);
my_syslog(MS_DHCP | LOG_WARNING,
_("not giving name %s to the DHCP lease of %s because "
"the name exists in %s with address %s"),
host_name, daemon->addrbuff,
record_source(fail_crec->uid), daemon->namebuff);
return;
}
if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, flags)))
{
if (crec->flags & F_NEG)
{
flags |= F_REVERSE;
cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags);
}
}
else
flags |= F_REVERSE;
if ((crec = dhcp_spare))
dhcp_spare = dhcp_spare->next;
else /* need new one */
crec = whine_malloc(sizeof(struct crec));
+1 -1
View File
@@ -40,7 +40,7 @@
#define LOG_MAX 5 /* log-queue length */
#define RANDFILE "/dev/urandom"
#define EDNS0_OPTION_MAC 5 /* dyndns.org temporary assignment */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* DBUS interface specifics */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
/* compile-time options: uncomment below to enable or do eg.
+21 -9
View File
@@ -20,7 +20,7 @@
#include <dbus/dbus.h>
const char* introspection_xml =
const char* introspection_xml_template =
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
"<node name=\"" DNSMASQ_PATH "\">\n"
@@ -29,7 +29,7 @@ const char* introspection_xml =
" <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
" </method>\n"
" </interface>\n"
" <interface name=\"" DNSMASQ_SERVICE "\">\n"
" <interface name=\"%s\">\n"
" <method name=\"ClearCache\">\n"
" </method>\n"
" <method name=\"GetVersion\">\n"
@@ -56,6 +56,8 @@ const char* introspection_xml =
" </interface>\n"
"</node>\n";
static char *introspection_xml = NULL;
struct watch {
DBusWatch *watch;
struct watch *next;
@@ -266,11 +268,21 @@ DBusHandlerResult message_handler(DBusConnection *connection,
if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
{
DBusMessage *reply = dbus_message_new_method_return(message);
DBusMessage *reply;
dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection_xml, DBUS_TYPE_INVALID);
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
/* string length: "%s" provides space for termination zero */
if (!introspection_xml &&
(introspection_xml = whine_malloc(strlen(introspection_xml_template) + strlen(daemon->dbus_name))))
sprintf(introspection_xml, introspection_xml_template, daemon->dbus_name);
if (introspection_xml)
{
reply = dbus_message_new_method_return(message);
dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection_xml, DBUS_TYPE_INVALID);
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
}
}
else if (strcmp(method, "GetVersion") == 0)
{
@@ -315,7 +327,7 @@ char *dbus_init(void)
dbus_connection_set_watch_functions(connection, add_watch, remove_watch,
NULL, NULL, NULL);
dbus_error_init (&dbus_error);
dbus_bus_request_name (connection, DNSMASQ_SERVICE, 0, &dbus_error);
dbus_bus_request_name (connection, daemon->dbus_name, 0, &dbus_error);
if (dbus_error_is_set (&dbus_error))
return (char *)dbus_error.message;
@@ -325,7 +337,7 @@ char *dbus_init(void)
daemon->dbus = connection;
if ((message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, "Up")))
if ((message = dbus_message_new_signal(DNSMASQ_PATH, daemon->dbus_name, "Up")))
{
dbus_connection_send(connection, message, NULL);
dbus_message_unref(message);
@@ -430,7 +442,7 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
else
return;
if (!(message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, action_str)))
if (!(message = dbus_message_new_signal(DNSMASQ_PATH, daemon->dbus_name, action_str)))
return;
dbus_message_iter_init_append(message, &args);
+1
View File
@@ -777,6 +777,7 @@ extern struct daemon {
struct tftp_prefix *if_prefix; /* per-interface TFTP prefixes */
unsigned int duid_enterprise, duid_config_len;
unsigned char *duid_config;
char *dbus_name;
/* globally used stuff for DNS */
char *packet; /* packet buffer */
+14 -4
View File
@@ -338,13 +338,22 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
sprintf(daemon->addrbuff, "port %d", port);
s = _("failed to create listening socket for %s: %s");
if (fd != -1)
close (fd);
if (dienow)
die(s, daemon->addrbuff, EC_BADNET);
{
/* failure to bind addresses given by --listen-address at this point
is OK if we're doing bind-dynamic */
if (!option_bool(OPT_CLEVERBIND))
die(s, daemon->addrbuff, EC_BADNET);
}
else
my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
my_syslog(LOG_ERR, s, daemon->addrbuff, strerror(errno));
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd))
goto err;
@@ -513,7 +522,8 @@ void create_bound_listeners(int dienow)
no interface with a matching address. These may be valid: eg it's possible
to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
If the address isn't valid the bind() will fail and we'll die().
If the address isn't valid the bind() will fail and we'll die()
(except in bind-dynamic mode, when we'll complain but keep trying.)
The resulting listeners have the ->iface field NULL, and this has to be
handled by the DNS and TFTP code. It disables --localise-queries processing
+10 -2
View File
@@ -184,7 +184,7 @@ static const struct myoption opts[] =
{ "localise-queries", 0, 0, 'y' },
{ "txt-record", 1, 0, 'Y' },
{ "dns-rr", 1, 0, LOPT_RR },
{ "enable-dbus", 0, 0, '1' },
{ "enable-dbus", 2, 0, '1' },
{ "bootp-dynamic", 2, 0, '3' },
{ "dhcp-mac", 1, 0, '4' },
{ "no-ping", 0, 0, '5' },
@@ -326,7 +326,7 @@ static struct {
{ LOPT_INTNAME, ARG_DUP, "<name>,<interface>", gettext_noop("Give DNS name to IPv4 address of interface."), NULL },
{ 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL },
{ 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
{ '1', OPT_DBUS, NULL, gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
{ '1', ARG_ONE, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
{ '2', ARG_DUP, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL },
{ '3', ARG_DUP, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL },
{ '4', ARG_DUP, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL },
@@ -1285,6 +1285,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break;
}
case '1': /* --enable-dbus */
set_option_bool(OPT_DBUS);
if (arg)
daemon->dbus_name = opt_string_alloc(arg);
else
daemon->dbus_name = DNSMASQ_SERVICE;
break;
case '8': /* --log-facility */
/* may be a filename */
if (strchr(arg, '/') || strcmp (arg, "-") == 0)
+2 -2
View File
@@ -412,8 +412,8 @@ static int add_prefixes(struct in6_addr *local, int prefix,
opt->type = ICMP6_OPT_PREFIX;
opt->len = 4;
opt->prefix_len = prefix;
/* autonomous only if we're not doing dhcp */
opt->flags = do_slaac ? 0x40 : 0x00;
/* autonomous only if we're not doing dhcp, always set "on-link" */
opt->flags = do_slaac ? 0xC0 : 0x80;
opt->valid_lifetime = htonl(time);
opt->preferred_lifetime = htonl(deprecate ? 0 : time);
opt->reserved = 0;
+17 -6
View File
@@ -515,11 +515,22 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
op += 3;
pp = op;
/* Always force update, since the client has no way to do it itself. */
if (!option_bool(OPT_FQDN_UPDATE) && !(fqdn_flags & 0x01))
fqdn_flags |= 0x03;
fqdn_flags &= ~0x08;
/* NB, the following always sets at least one bit */
if (option_bool(OPT_FQDN_UPDATE))
{
if (fqdn_flags & 0x01)
{
fqdn_flags |= 0x02; /* set O */
fqdn_flags &= ~0x01; /* clear S */
}
fqdn_flags |= 0x08; /* set N */
}
else
{
if (!(fqdn_flags & 0x01))
fqdn_flags |= 0x03; /* set S and O */
fqdn_flags &= ~0x08; /* clear N */
}
if (fqdn_flags & 0x04)
while (*op != 0 && ((op + (*op) + 1) - pp) < len)
@@ -2261,7 +2272,7 @@ static void do_options(struct dhcp_context *context,
if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len)))
{
*(p++) = fqdn_flags;
*(p++) = fqdn_flags & 0x0f; /* MBZ bits to zero */
*(p++) = 255;
*(p++) = 255;
+6 -3
View File
@@ -113,7 +113,6 @@ void tftp_request(struct listener *listen, time_t now)
else
{
struct cmsghdr *cmptr;
int check;
if (msg.msg_controllen < sizeof(struct cmsghdr))
return;
@@ -193,10 +192,14 @@ void tftp_request(struct listener *listen, time_t now)
#ifdef HAVE_IPV6
if (listen->family == AF_INET6)
check = iface_check(AF_INET6, (struct all_addr *)&addr.in6.sin6_addr, name);
{
if (!iface_check(AF_INET6, (struct all_addr *)&addr.in6.sin6_addr, name))
return;
}
else
#endif
check = iface_check(AF_INET, (struct all_addr *)&addr.in.sin_addr, name);
if (!iface_check(AF_INET, (struct all_addr *)&addr.in.sin_addr, name))
return;
#ifdef HAVE_DHCP
/* allowed interfaces are the same as for DHCP */