SetDomainServers Dbus method.

This commit is contained in:
Simon Kelley
2012-12-01 21:02:15 +00:00
parent 2f38141f43
commit 295a54eed3
3 changed files with 148 additions and 56 deletions

View File

@@ -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.

View File

@@ -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
---------- ----------

View File

@@ -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,8 +327,51 @@ 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;
if (strings)
{
dbus_message_iter_get_basic(&array_iter, &str);
if (!str || !strlen (str))
{
error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
"Empty string");
break;
}
/* dup the string because it gets modified during parsing */
if (!(dup = str_domain = whine_malloc(strlen(str)+1)))
break;
strcpy(str_domain, str);
/* point to address part of old string for error message */
if ((str_addr = strrchr(str, '/')))
str = str_addr+1;
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 */ /* check the types of the struct and its elements */
if ((dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY) || 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_element_type(&array_iter) != DBUS_TYPE_STRING))
@@ -350,22 +399,19 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
break; 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, (char *) &interface, NULL); addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL);
free(str_addr);
if (addr_err) if (addr_err)
{ {
@@ -375,6 +421,24 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
break; break;
} }
if (strings)
{
char *p;
do {
if (str_domain)
{
if ((p = strchr(str_domain, '/')))
*p++ = 0;
}
else
p = NULL;
add_update_server(&addr, &source_addr, interface, str_domain);
} while ((str_domain = p));
}
else
{
/* jump past the address to the domain list (if any) */ /* jump past the address to the domain list (if any) */
dbus_message_iter_next (&string_iter); dbus_message_iter_next (&string_iter);
@@ -387,6 +451,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message)
add_update_server(&addr, &source_addr, interface, str); add_update_server(&addr, &source_addr, interface, str);
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING); } 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)