mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-07 16:01:41 +00:00
Compare commits
17
Commits
v2.64test6
...
v2.64rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d89fb4ed4f | ||
|
|
295a54eed3 | ||
|
|
2f38141f43 | ||
|
|
8e4b87918f | ||
|
|
83b2198e86 | ||
|
|
d1a5975f9b | ||
|
|
52002051ad | ||
|
|
b191a77901 | ||
|
|
23780dd577 | ||
|
|
d1e9a582ad | ||
|
|
819ff4dd0f | ||
|
|
de604c18a0 | ||
|
|
be6cfb42ab | ||
|
|
2022310f95 | ||
|
|
657ed09693 | ||
|
|
c99df938d7 | ||
|
|
cf568a3726 |
No files matched your search
@@ -19,9 +19,12 @@ version 2.64
|
|||||||
Flag DHCP or DHCPv6 in starup logging. Thanks to
|
Flag DHCP or DHCPv6 in starup logging. Thanks to
|
||||||
Vladislav Grishenko for the patch.
|
Vladislav Grishenko for the patch.
|
||||||
|
|
||||||
Add SetServersEX method in DBus interface. Thanks to Dan
|
Add SetServersEx method in DBus interface. Thanks to Dan
|
||||||
Williams for the patch.
|
Williams for the patch.
|
||||||
|
|
||||||
|
Add SetDomainServers method in DBus interface. Thanks to
|
||||||
|
Roy Marples for the patch.
|
||||||
|
|
||||||
Fix build with later Lua libraries. Thansk to Cristian
|
Fix build with later Lua libraries. Thansk to Cristian
|
||||||
Rodriguez for the patch.
|
Rodriguez for the patch.
|
||||||
|
|
||||||
@@ -32,6 +35,30 @@ version 2.64
|
|||||||
infinte loop at startup. Regression in 2.63. Thanks to
|
infinte loop at startup. Regression in 2.63. Thanks to
|
||||||
Haim Gelfenbeyn for spotting this.
|
Haim Gelfenbeyn for spotting this.
|
||||||
|
|
||||||
|
Set SO_REUSEADDRESS and SO_V6ONLY options on the DHCPv6
|
||||||
|
socket, this allows multiple instances of dnsmasq on a
|
||||||
|
single machine, in the same way as for DHCPv4. Thanks to
|
||||||
|
Gene Czarcinski and Vladislav Grishenko for work on this.
|
||||||
|
|
||||||
|
Fix DHCPv6 to do access control correctly when it's
|
||||||
|
configured with --listen-address. Thanks to
|
||||||
|
Gene Czarcinski for sorting this out.
|
||||||
|
|
||||||
|
Add a "wildcard" dhcp-range which works for any IPv6
|
||||||
|
subnet, --dhcp-range=::,static Useful for Stateless
|
||||||
|
DHCPv6. Thanks to Vladislav Grishenko for the patch.
|
||||||
|
|
||||||
|
Don't include lease-time in DHCPACK replies to DHCPINFORM
|
||||||
|
queries, since RFC-2131 says we shouldn't. Thanks to
|
||||||
|
Wouter Ibens for pointing this out.
|
||||||
|
|
||||||
|
Makefile tweak to do dependency checking on header files.
|
||||||
|
Thanks to Johan Peeters for the patch.
|
||||||
|
|
||||||
|
Check interface for outgoing unsolicited router
|
||||||
|
advertisements, rather than relying on interface address
|
||||||
|
configuration. Thanks to Gene Czarinski for the patch.
|
||||||
|
|
||||||
|
|
||||||
version 2.63
|
version 2.63
|
||||||
Do duplicate dhcp-host address check in --test mode.
|
Do duplicate dhcp-host address check in --test mode.
|
||||||
@@ -394,7 +421,7 @@ version 2.58
|
|||||||
|
|
||||||
Fix regression in TFTP server on *BSD platforms introduced
|
Fix regression in TFTP server on *BSD platforms introduced
|
||||||
in version 2.56, due to confusion with sockaddr
|
in version 2.56, due to confusion with sockaddr
|
||||||
length. Many thanks to Loïc Pefferkorn for finding this.
|
length. Many thanks to Loic Pefferkorn for finding this.
|
||||||
|
|
||||||
Support scope-ids in IPv6 addresses of nameservers from
|
Support scope-ids in IPv6 addresses of nameservers from
|
||||||
/etc/resolv.conf and in --server options. Eg
|
/etc/resolv.conf and in --server options. Eg
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ all : $(BUILDDIR)
|
|||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -f *~ $(BUILDDIR)/*.mo contrib/*/*~ */*~ $(BUILDDIR)/*.pot
|
rm -f *~ $(BUILDDIR)/*.mo contrib/*/*~ */*~ $(BUILDDIR)/*.pot
|
||||||
rm -f $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq core */core
|
rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq
|
||||||
|
rm -rf core */core
|
||||||
|
|
||||||
install : all install-common
|
install : all install-common
|
||||||
|
|
||||||
@@ -113,7 +114,11 @@ $(BUILDDIR):
|
|||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
|
|
||||||
# rules below are targets in recusive makes with cwd=$(SRC)
|
# rules below are targets in recusive makes with cwd=$(BUILDDIR)
|
||||||
|
|
||||||
|
.configured: $(hdrs)
|
||||||
|
@rm -f *.o
|
||||||
|
@touch $@
|
||||||
|
|
||||||
$(objs:.o=.c) $(hdrs):
|
$(objs:.o=.c) $(hdrs):
|
||||||
ln -s $(top)/$(SRC)/$@ .
|
ln -s $(top)/$(SRC)/$@ .
|
||||||
@@ -121,7 +126,7 @@ $(objs:.o=.c) $(hdrs):
|
|||||||
.c.o:
|
.c.o:
|
||||||
$(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<
|
$(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<
|
||||||
|
|
||||||
dnsmasq : $(hdrs) $(objs)
|
dnsmasq : .configured $(hdrs) $(objs)
|
||||||
$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
|
$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
|
||||||
|
|
||||||
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
|
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
|
||||||
|
|||||||
Executable
+43
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import dbus
|
||||||
|
|
||||||
|
bus = dbus.SystemBus()
|
||||||
|
p = bus.get_object("uk.org.thekelleys.dnsmasq", "/uk/org/thekelleys/dnsmasq")
|
||||||
|
l = dbus.Interface(p, dbus_interface="uk.org.thekelleys.dnsmasq")
|
||||||
|
|
||||||
|
# The new more flexible SetServersEx method
|
||||||
|
array = dbus.Array()
|
||||||
|
array.append(["1.2.3.5"])
|
||||||
|
array.append(["1.2.3.4#664", "foobar.com"])
|
||||||
|
array.append(["1003:1234:abcd::1%eth0", "eng.mycorp.com", "lab.mycorp.com"])
|
||||||
|
print l.SetServersEx(array)
|
||||||
|
|
||||||
|
# Must create a new object for dnsmasq as the introspection gives the wrong
|
||||||
|
# signature for SetServers (av) while the code only expects a bunch of arguments
|
||||||
|
# instead of an array of variants
|
||||||
|
p = bus.get_object("uk.org.thekelleys.dnsmasq", "/uk/org/thekelleys/dnsmasq", introspect=False)
|
||||||
|
l = dbus.Interface(p, dbus_interface="uk.org.thekelleys.dnsmasq")
|
||||||
|
|
||||||
|
# The previous method; all addresses in machine byte order
|
||||||
|
print l.SetServers(dbus.UInt32(16909060), # 1.2.3.5
|
||||||
|
dbus.UInt32(16909061), # 1.2.3.4
|
||||||
|
"foobar.com",
|
||||||
|
dbus.Byte(0x10), # 1003:1234:abcd::1
|
||||||
|
dbus.Byte(0x03),
|
||||||
|
dbus.Byte(0x12),
|
||||||
|
dbus.Byte(0x34),
|
||||||
|
dbus.Byte(0xab),
|
||||||
|
dbus.Byte(0xcd),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x00),
|
||||||
|
dbus.Byte(0x01),
|
||||||
|
"eng.mycorp.com",
|
||||||
|
"lab.mycorp.com")
|
||||||
|
|
||||||
@@ -137,6 +137,23 @@ Each call to SetServersEx completely replaces the set of servers
|
|||||||
specified by via the DBus, but it leaves any servers specified via the
|
specified by via the DBus, but it leaves any servers specified via the
|
||||||
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
|
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
|
||||||
|
|
||||||
|
|
||||||
|
SetDomainServers
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Yes another variation for setting DNS servers, with the capability of
|
||||||
|
SetServersEx, but without using arrays of arrays, which are not
|
||||||
|
sendable with dbus-send. The arguments are an array of strings which
|
||||||
|
are identical to the equivalent arguments --server, so the example
|
||||||
|
for SetServersEx is represented as
|
||||||
|
|
||||||
|
[
|
||||||
|
"/foobar.com/1.2.3.4"
|
||||||
|
"/eng.mycorp.com/lab.mycorp.com/1003:1234:abcd::1%eth0"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
2. SIGNALS
|
2. SIGNALS
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|||||||
@@ -480,7 +480,7 @@
|
|||||||
#tftp-no-blocksize
|
#tftp-no-blocksize
|
||||||
|
|
||||||
# Set the boot file name only when the "red" tag is set.
|
# Set the boot file name only when the "red" tag is set.
|
||||||
#dhcp-boot=net:red,pxelinux.red-net
|
#dhcp-boot=tag:red,pxelinux.red-net
|
||||||
|
|
||||||
# An example of dhcp-boot with an external TFTP server: the name and IP
|
# An example of dhcp-boot with an external TFTP server: the name and IP
|
||||||
# address of the server are given after the filename.
|
# address of the server are given after the filename.
|
||||||
@@ -621,6 +621,6 @@
|
|||||||
# Log lots of extra information about DHCP transactions.
|
# Log lots of extra information about DHCP transactions.
|
||||||
#log-dhcp
|
#log-dhcp
|
||||||
|
|
||||||
# Include a another lot of configuration options.
|
# Include another lot of configuration options.
|
||||||
#conf-file=/etc/dnsmasq.more.conf
|
#conf-file=/etc/dnsmasq.more.conf
|
||||||
#conf-dir=/etc/dnsmasq.d
|
#conf-dir=/etc/dnsmasq.d
|
||||||
+8
-2
@@ -83,7 +83,9 @@ or launchd.
|
|||||||
Debug mode: don't fork to the background, don't write a pid file,
|
Debug mode: don't fork to the background, don't write a pid file,
|
||||||
don't change user id, generate a complete cache dump on receipt on
|
don't change user id, generate a complete cache dump on receipt on
|
||||||
SIGUSR1, log to stderr as well as syslog, don't fork new processes
|
SIGUSR1, log to stderr as well as syslog, don't fork new processes
|
||||||
to handle TCP queries.
|
to handle TCP queries. Note that this option is for use in debugging
|
||||||
|
only, to stop dnsmasq daemonising in production, use
|
||||||
|
.B -k.
|
||||||
.TP
|
.TP
|
||||||
.B \-q, --log-queries
|
.B \-q, --log-queries
|
||||||
Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1.
|
Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1.
|
||||||
@@ -584,7 +586,11 @@ which tells dnsmasq to enable DHCP for the network specified, but not
|
|||||||
to dynamically allocate IP addresses: only hosts which have static
|
to dynamically allocate IP addresses: only hosts which have static
|
||||||
addresses given via
|
addresses given via
|
||||||
.B dhcp-host
|
.B dhcp-host
|
||||||
or from /etc/ethers will be served.
|
or from /etc/ethers will be served. A static-only subnet with address
|
||||||
|
all zeros may be used as a "catch-all" address to enable replies to all
|
||||||
|
Information-request packets on a subnet which is provided with
|
||||||
|
stateless DHCPv6, ie
|
||||||
|
.B --dhcp=range=::,static
|
||||||
|
|
||||||
For IPv4, the <mode> may be
|
For IPv4, the <mode> may be
|
||||||
.B proxy
|
.B proxy
|
||||||
|
|||||||
+123
-51
@@ -38,6 +38,9 @@ const char* introspection_xml_template =
|
|||||||
" <method name=\"SetServers\">\n"
|
" <method name=\"SetServers\">\n"
|
||||||
" <arg name=\"servers\" direction=\"in\" type=\"av\"/>\n"
|
" <arg name=\"servers\" direction=\"in\" type=\"av\"/>\n"
|
||||||
" </method>\n"
|
" </method>\n"
|
||||||
|
" <method name=\"SetDomainServers\">\n"
|
||||||
|
" <arg name=\"servers\" direction=\"in\" type=\"as\"/>\n"
|
||||||
|
" </method>\n"
|
||||||
" <method name=\"SetServersEx\">\n"
|
" <method name=\"SetServersEx\">\n"
|
||||||
" <arg name=\"servers\" direction=\"in\" type=\"aas\"/>\n"
|
" <arg name=\"servers\" direction=\"in\" type=\"aas\"/>\n"
|
||||||
" </method>\n"
|
" </method>\n"
|
||||||
@@ -292,11 +295,14 @@ static void dbus_read_servers(DBusMessage *message)
|
|||||||
cleanup_dbus();
|
cleanup_dbus();
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
|
static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||||
{
|
{
|
||||||
DBusMessageIter iter, array_iter, string_iter;
|
DBusMessageIter iter, array_iter, string_iter;
|
||||||
DBusMessage *error = NULL;
|
DBusMessage *error = NULL;
|
||||||
const char *addr_err;
|
const char *addr_err;
|
||||||
|
char *dup = NULL;
|
||||||
|
|
||||||
|
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
|
||||||
|
|
||||||
if (!dbus_message_iter_init(message, &iter))
|
if (!dbus_message_iter_init(message, &iter))
|
||||||
{
|
{
|
||||||
@@ -306,10 +312,10 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
|
|||||||
|
|
||||||
/* check that the message contains an array of arrays */
|
/* check that the message contains an array of arrays */
|
||||||
if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
|
if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
|
||||||
(dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY))
|
(dbus_message_iter_get_element_type(&iter) != (strings ? DBUS_TYPE_STRING : DBUS_TYPE_ARRAY)))
|
||||||
{
|
{
|
||||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||||
"Expected array of string arrays");
|
strings ? "Expected array of string" : "Expected array of string arrays");
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_dbus();
|
mark_dbus();
|
||||||
@@ -321,51 +327,91 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
|
|||||||
const char *str = NULL;
|
const char *str = NULL;
|
||||||
union mysockaddr addr, source_addr;
|
union mysockaddr addr, source_addr;
|
||||||
char interface[IF_NAMESIZE];
|
char interface[IF_NAMESIZE];
|
||||||
char *str_addr;
|
char *str_addr, *str_domain = NULL;
|
||||||
|
|
||||||
/* check the types of the struct and its elements */
|
if (strings)
|
||||||
if ((dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY) ||
|
{
|
||||||
(dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_STRING))
|
dbus_message_iter_get_basic(&array_iter, &str);
|
||||||
{
|
if (!str || !strlen (str))
|
||||||
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
{
|
||||||
"Expected inner array of strings");
|
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||||
break;
|
"Empty string");
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* string_iter points to each "s" element in the inner array */
|
/* dup the string because it gets modified during parsing */
|
||||||
dbus_message_iter_recurse(&array_iter, &string_iter);
|
if (!(dup = str_domain = whine_malloc(strlen(str)+1)))
|
||||||
if (dbus_message_iter_get_arg_type(&string_iter) != DBUS_TYPE_STRING)
|
break;
|
||||||
{
|
|
||||||
/* no IP address given */
|
|
||||||
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
|
||||||
"Expected IP address");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbus_message_iter_get_basic(&string_iter, &str);
|
strcpy(str_domain, str);
|
||||||
if (!str || !strlen (str))
|
|
||||||
{
|
/* point to address part of old string for error message */
|
||||||
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
if ((str_addr = strrchr(str, '/')))
|
||||||
"Empty IP address");
|
str = str_addr+1;
|
||||||
break;
|
|
||||||
}
|
if ((str_addr = strrchr(str_domain, '/')))
|
||||||
|
{
|
||||||
|
if (*str_domain != '/' || str_addr == str_domain)
|
||||||
|
{
|
||||||
|
error = dbus_message_new_error_printf(message,
|
||||||
|
DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"No domain terminator '%s'",
|
||||||
|
str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*str_addr++ = 0;
|
||||||
|
str_domain++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str_addr = str_domain;
|
||||||
|
str_domain = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* check the types of the struct and its elements */
|
||||||
|
if ((dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY) ||
|
||||||
|
(dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_STRING))
|
||||||
|
{
|
||||||
|
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"Expected inner array of strings");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* string_iter points to each "s" element in the inner array */
|
||||||
|
dbus_message_iter_recurse(&array_iter, &string_iter);
|
||||||
|
if (dbus_message_iter_get_arg_type(&string_iter) != DBUS_TYPE_STRING)
|
||||||
|
{
|
||||||
|
/* no IP address given */
|
||||||
|
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"Expected IP address");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_message_iter_get_basic(&string_iter, &str);
|
||||||
|
if (!str || !strlen (str))
|
||||||
|
{
|
||||||
|
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"Empty IP address");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dup the string because it gets modified during parsing */
|
||||||
|
if (!(dup = str_addr = whine_malloc(strlen(str)+1)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
strcpy(str_addr, str);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
memset(&source_addr, 0, sizeof(source_addr));
|
memset(&source_addr, 0, sizeof(source_addr));
|
||||||
memset(&interface, 0, sizeof(interface));
|
memset(&interface, 0, sizeof(interface));
|
||||||
|
|
||||||
/* dup the string because it gets modified during parsing */
|
|
||||||
str_addr = strdup(str);
|
|
||||||
if (!str_addr)
|
|
||||||
{
|
|
||||||
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
|
||||||
"Out of memory parsing IP address");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse the IP address */
|
/* parse the IP address */
|
||||||
addr_err = parse_server(str_addr, &addr, &source_addr, &interface, NULL);
|
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL);
|
||||||
free(str_addr);
|
|
||||||
|
|
||||||
if (addr_err)
|
if (addr_err)
|
||||||
{
|
{
|
||||||
@@ -375,18 +421,37 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jump past the address to the domain list (if any) */
|
if (strings)
|
||||||
dbus_message_iter_next (&string_iter);
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
/* parse domains and add each server/domain pair to the list */
|
do {
|
||||||
do {
|
if (str_domain)
|
||||||
str = NULL;
|
{
|
||||||
if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)
|
if ((p = strchr(str_domain, '/')))
|
||||||
dbus_message_iter_get_basic(&string_iter, &str);
|
*p++ = 0;
|
||||||
dbus_message_iter_next (&string_iter);
|
}
|
||||||
|
else
|
||||||
|
p = NULL;
|
||||||
|
|
||||||
add_update_server(&addr, &source_addr, interface, str);
|
add_update_server(&addr, &source_addr, interface, str_domain);
|
||||||
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
|
} while ((str_domain = p));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* jump past the address to the domain list (if any) */
|
||||||
|
dbus_message_iter_next (&string_iter);
|
||||||
|
|
||||||
|
/* parse domains and add each server/domain pair to the list */
|
||||||
|
do {
|
||||||
|
str = NULL;
|
||||||
|
if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)
|
||||||
|
dbus_message_iter_get_basic(&string_iter, &str);
|
||||||
|
dbus_message_iter_next (&string_iter);
|
||||||
|
|
||||||
|
add_update_server(&addr, &source_addr, interface, str);
|
||||||
|
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
/* jump to next element in outer array */
|
/* jump to next element in outer array */
|
||||||
dbus_message_iter_next(&array_iter);
|
dbus_message_iter_next(&array_iter);
|
||||||
@@ -394,6 +459,9 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
|
|||||||
|
|
||||||
cleanup_dbus();
|
cleanup_dbus();
|
||||||
|
|
||||||
|
if (dup)
|
||||||
|
free(dup);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,8 +500,12 @@ DBusHandlerResult message_handler(DBusConnection *connection,
|
|||||||
}
|
}
|
||||||
else if (strcmp(method, "SetServersEx") == 0)
|
else if (strcmp(method, "SetServersEx") == 0)
|
||||||
{
|
{
|
||||||
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
|
reply = dbus_read_servers_ex(message, 0);
|
||||||
reply = dbus_read_servers_ex(message);
|
check_servers();
|
||||||
|
}
|
||||||
|
else if (strcmp(method, "SetDomainServers") == 0)
|
||||||
|
{
|
||||||
|
reply = dbus_read_servers_ex(message, 1);
|
||||||
check_servers();
|
check_servers();
|
||||||
}
|
}
|
||||||
else if (strcmp(method, "ClearCache") == 0)
|
else if (strcmp(method, "ClearCache") == 0)
|
||||||
|
|||||||
+8
-8
@@ -435,14 +435,14 @@ void bindtodevice(int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
strcpy(ifr.ifr_name, found->name);
|
strcpy(ifr.ifr_name, found->name);
|
||||||
/* only allowed by root. */
|
/* only allowed by root. */
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) == -1 &&
|
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) == -1 &&
|
||||||
errno != EPERM)
|
errno != EPERM)
|
||||||
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
|
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+54
-12
@@ -21,7 +21,7 @@
|
|||||||
struct iface_param {
|
struct iface_param {
|
||||||
struct dhcp_context *current;
|
struct dhcp_context *current;
|
||||||
struct in6_addr fallback;
|
struct in6_addr fallback;
|
||||||
int ind;
|
int ind, addr_match;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int complete_context6(struct in6_addr *local, int prefix,
|
static int complete_context6(struct in6_addr *local, int prefix,
|
||||||
@@ -36,15 +36,31 @@ void dhcp6_init(void)
|
|||||||
#if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
|
#if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
|
||||||
int class = IPTOS_CLASS_CS6;
|
int class = IPTOS_CLASS_CS6;
|
||||||
#endif
|
#endif
|
||||||
|
int oneopt = 1;
|
||||||
|
|
||||||
if ((fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1 ||
|
if ((fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1 ||
|
||||||
#if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
|
#if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
|
||||||
setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &class, sizeof(class)) == -1 ||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &class, sizeof(class)) == -1 ||
|
||||||
#endif
|
#endif
|
||||||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &oneopt, sizeof(oneopt)) == -1 ||
|
||||||
!fix_fd(fd) ||
|
!fix_fd(fd) ||
|
||||||
!set_ipv6pktinfo(fd))
|
!set_ipv6pktinfo(fd))
|
||||||
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
|
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
|
||||||
|
|
||||||
|
/* When bind-interfaces is set, there might be more than one dnmsasq
|
||||||
|
instance binding port 547. That's OK if they serve different networks.
|
||||||
|
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
|
||||||
|
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
|
||||||
|
{
|
||||||
|
#ifdef SO_REUSEPORT
|
||||||
|
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
|
||||||
|
#else
|
||||||
|
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
|
||||||
|
#endif
|
||||||
|
if (rc == -1)
|
||||||
|
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&saddr, 0, sizeof(saddr));
|
memset(&saddr, 0, sizeof(saddr));
|
||||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||||
saddr.sin6_len = sizeof(struct sockaddr_in6);
|
saddr.sin6_len = sizeof(struct sockaddr_in6);
|
||||||
@@ -71,7 +87,6 @@ void dhcp6_packet(time_t now)
|
|||||||
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
|
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
|
||||||
} control_u;
|
} control_u;
|
||||||
struct sockaddr_in6 from;
|
struct sockaddr_in6 from;
|
||||||
struct all_addr dest;
|
|
||||||
ssize_t sz;
|
ssize_t sz;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
@@ -98,33 +113,52 @@ void dhcp6_packet(time_t now)
|
|||||||
p.c = CMSG_DATA(cmptr);
|
p.c = CMSG_DATA(cmptr);
|
||||||
|
|
||||||
if_index = p.p->ipi6_ifindex;
|
if_index = p.p->ipi6_ifindex;
|
||||||
dest.addr.addr6 = p.p->ipi6_addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
|
if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!iface_check(AF_INET6, (struct all_addr *)&dest, ifr.ifr_name))
|
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
||||||
return;
|
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* unlinked contexts are marked by context->current == context */
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
|
||||||
{
|
|
||||||
context->current = context;
|
|
||||||
memset(&context->local6, 0, IN6ADDRSZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
parm.current = NULL;
|
parm.current = NULL;
|
||||||
parm.ind = if_index;
|
parm.ind = if_index;
|
||||||
|
parm.addr_match = 0;
|
||||||
memset(&parm.fallback, 0, IN6ADDRSZ);
|
memset(&parm.fallback, 0, IN6ADDRSZ);
|
||||||
|
|
||||||
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
|
if (IN6_IS_ADDR_UNSPECIFIED(&context->start6) && context->prefix == 0)
|
||||||
|
{
|
||||||
|
/* wildcard context for DHCP-stateless only */
|
||||||
|
parm.current = context;
|
||||||
|
context->current = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* unlinked contexts are marked by context->current == context */
|
||||||
|
context->current = context;
|
||||||
|
memset(&context->local6, 0, IN6ADDRSZ);
|
||||||
|
}
|
||||||
|
|
||||||
if (!iface_enumerate(AF_INET6, &parm, complete_context6))
|
if (!iface_enumerate(AF_INET6, &parm, complete_context6))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (daemon->if_names || daemon->if_addrs)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
||||||
|
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!tmp && !parm.addr_match)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lease_prune(NULL, now); /* lose any expired leases */
|
lease_prune(NULL, now); /* lose any expired leases */
|
||||||
|
|
||||||
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
|
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
|
||||||
@@ -151,6 +185,7 @@ static int complete_context6(struct in6_addr *local, int prefix,
|
|||||||
{
|
{
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
struct iface_param *param = vparam;
|
struct iface_param *param = vparam;
|
||||||
|
struct iname *tmp;
|
||||||
|
|
||||||
(void)scope; /* warning */
|
(void)scope; /* warning */
|
||||||
(void)dad;
|
(void)dad;
|
||||||
@@ -160,6 +195,13 @@ static int complete_context6(struct in6_addr *local, int prefix,
|
|||||||
!IN6_IS_ADDR_LINKLOCAL(local) &&
|
!IN6_IS_ADDR_LINKLOCAL(local) &&
|
||||||
!IN6_IS_ADDR_MULTICAST(local))
|
!IN6_IS_ADDR_MULTICAST(local))
|
||||||
{
|
{
|
||||||
|
/* if we have --listen-address config, see if the
|
||||||
|
arrival interface has a matching address. */
|
||||||
|
for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
|
||||||
|
if (tmp->addr.sa.sa_family == AF_INET6 &&
|
||||||
|
IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
|
||||||
|
param->addr_match = 1;
|
||||||
|
|
||||||
/* Determine a globally address on the arrival interface, even
|
/* Determine a globally address on the arrival interface, even
|
||||||
if we have no matching dhcp-context, because we're only
|
if we have no matching dhcp-context, because we're only
|
||||||
allocating on remote subnets via relays. This
|
allocating on remote subnets via relays. This
|
||||||
|
|||||||
+1
-1
@@ -891,7 +891,7 @@ void safe_pipe(int *fd, int read_noblock);
|
|||||||
void *whine_malloc(size_t size);
|
void *whine_malloc(size_t size);
|
||||||
int sa_len(union mysockaddr *addr);
|
int sa_len(union mysockaddr *addr);
|
||||||
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
|
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
|
||||||
int hostname_isequal(char *a, char *b);
|
int hostname_isequal(const char *a, const char *b);
|
||||||
time_t dnsmasq_time(void);
|
time_t dnsmasq_time(void);
|
||||||
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
|
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
|
|||||||
+2
-2
@@ -371,9 +371,9 @@ static int nl_async(struct nlmsghdr *h)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_DHCP6
|
|
||||||
else if (h->nlmsg_type == RTM_NEWADDR)
|
else if (h->nlmsg_type == RTM_NEWADDR)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
/* force RAs to sync new network and pick up new interfaces. */
|
/* force RAs to sync new network and pick up new interfaces. */
|
||||||
if (daemon->ra_contexts)
|
if (daemon->ra_contexts)
|
||||||
{
|
{
|
||||||
@@ -383,9 +383,9 @@ static int nl_async(struct nlmsghdr *h)
|
|||||||
iface_enumerate and can't re-enter it now */
|
iface_enumerate and can't re-enter it now */
|
||||||
send_alarm(0, 0);
|
send_alarm(0, 0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 1; /* clever bind mode - rescan */
|
return 1; /* clever bind mode - rescan */
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2116,6 +2116,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
new->prefix = 64; /* default */
|
new->prefix = 64; /* default */
|
||||||
new->end6 = new->start6;
|
new->end6 = new->start6;
|
||||||
|
|
||||||
|
/* dhcp-range=:: enables DHCP stateless on any interface */
|
||||||
|
if (IN6_IS_ADDR_UNSPECIFIED(&new->start6))
|
||||||
|
new->prefix = 0;
|
||||||
|
|
||||||
for (leasepos = 1; leasepos < k; leasepos++)
|
for (leasepos = 1; leasepos < k; leasepos++)
|
||||||
{
|
{
|
||||||
if (strcmp(a[leasepos], "static") == 0)
|
if (strcmp(a[leasepos], "static") == 0)
|
||||||
|
|||||||
+2
-1
@@ -482,7 +482,8 @@ time_t periodic_ra(time_t now)
|
|||||||
ever be able to send ra's and satistfy it. */
|
ever be able to send ra's and satistfy it. */
|
||||||
if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
||||||
context->ra_time = 0;
|
context->ra_time = 0;
|
||||||
else if (indextoname(daemon->icmp6fd, param.iface, interface))
|
else if (indextoname(daemon->icmp6fd, param.iface, interface) &&
|
||||||
|
iface_check(AF_LOCAL, NULL, interface))
|
||||||
send_ra(param.iface, interface, NULL);
|
send_ra(param.iface, interface, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-10
@@ -1387,6 +1387,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
|
|
||||||
if (lease)
|
if (lease)
|
||||||
{
|
{
|
||||||
|
lease_set_interface(lease, int_index, now);
|
||||||
if (override.s_addr != 0)
|
if (override.s_addr != 0)
|
||||||
lease->override = override;
|
lease->override = override;
|
||||||
else
|
else
|
||||||
@@ -1397,16 +1398,6 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
|
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_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
|
||||||
|
|
||||||
if (lease)
|
|
||||||
{
|
|
||||||
if (lease->expires == 0)
|
|
||||||
time = 0xffffffff;
|
|
||||||
else
|
|
||||||
time = (unsigned int)difftime(lease->expires, now);
|
|
||||||
option_put(mess, end, OPTION_LEASE_TIME, 4, time);
|
|
||||||
lease_set_interface(lease, int_index, now);
|
|
||||||
}
|
|
||||||
|
|
||||||
do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
|
do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
|
||||||
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
|
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
|
||||||
|
|
||||||
|
|||||||
+9
-2
@@ -194,8 +194,8 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
iface_id.next = tags;
|
iface_id.next = tags;
|
||||||
tags = &iface_id;
|
tags = &iface_id;
|
||||||
|
|
||||||
/* set tag "DHCPv6" */
|
/* set tag "dhcpv6" */
|
||||||
v6_id.net = "DHCPv6";
|
v6_id.net = "dhcpv6";
|
||||||
v6_id.next = tags;
|
v6_id.next = tags;
|
||||||
tags = &v6_id;
|
tags = &v6_id;
|
||||||
|
|
||||||
@@ -1010,6 +1010,13 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
|
|
||||||
case DHCP6IREQ:
|
case DHCP6IREQ:
|
||||||
{
|
{
|
||||||
|
/* We can't discriminate contexts based on address, as we don't know it.
|
||||||
|
If there is only one possible context, we can use its tags */
|
||||||
|
if (context && !context->current)
|
||||||
|
{
|
||||||
|
context->netid.next = NULL;
|
||||||
|
context_tags = &context->netid;
|
||||||
|
}
|
||||||
log6_packet("DHCPINFORMATION-REQUEST", clid, clid_len, NULL, xid, iface_name, ignore ? "ignored" : hostname);
|
log6_packet("DHCPINFORMATION-REQUEST", clid, clid_len, NULL, xid, iface_name, ignore ? "ignored" : hostname);
|
||||||
if (ignore)
|
if (ignore)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+1
-1
@@ -280,7 +280,7 @@ int sa_len(union mysockaddr *addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* don't use strcasecmp and friends here - they may be messed up by LOCALE */
|
/* don't use strcasecmp and friends here - they may be messed up by LOCALE */
|
||||||
int hostname_isequal(char *a, char *b)
|
int hostname_isequal(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
unsigned int c1, c2;
|
unsigned int c1, c2;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user