Send connman mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."
Today's Topics:
1. Fw: Re: Connman coredump (Cliff McDiarmid)
2. Re: Fw: Re: Connman coredump (Daniel Wagner)
3. [PATCH 1/2] resolver: add support for systemd-resolved.
(Ismo Puustinen)
4. [PATCH 2/2] service: add mDNS support on per-interface basis.
(Ismo Puustinen)
----------------------------------------------------------------------
Message: 1
Date: Tue, 26 Sep 2017 21:24:00 +0200
From: "Cliff McDiarmid" <[email protected]>
To: [email protected]
Subject: Fw: Re: Connman coredump
Message-ID:
<trinity-1b7c72fe-bd46-4fc2-9728-27f7b5fe6cba-1506453840779@3c-app-mailcom-lxa06>
Content-Type: text/plain; charset=UTF-8
Sent:?Tuesday, September 26, 2017 at 8:18 PM
From:?"Cliff McDiarmid" <[email protected]>
To:?"Daniel Wagner" <[email protected]>
Subject:?Re: Connman coredump
Sent:?Monday, September 25, 2017 at 8:20 PM
From:?"Daniel Wagner" <[email protected]>
To:?"Cliff McDiarmid" <[email protected]>, [email protected]
Subject:?Re: Connman coredump
>connmand[3059]: src/stats.c:__connman_stats_update() ring buffer is full,
>update history file
>When the buffer is full, ConnMan creates a summary and adds it
>to the history file.
>connmand[3059]: src/stats.c:stats_file_remap() file 0x7ffe2ee42090 size 4096
>addr (nil) len 0
>So this looks still okay. The first remap is the history file open (empty
>.file), the secon remap is a the temporay new history file (also empty).
>(connmand:3059): GLib-CRITICAL **: g_date_set_time_t: assertion
>g_date_valid_dmy (date->day, date->month, date->year)' failed
>Since the first glib message is about g_data_set_time_t(), it could be that
>glib is not happy with the timezone settings.
>https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html#g-date-set-time-t[https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html#g-date-set-time-t[https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html#g-date-set-time-t]]
>g_data_set_time_t() calls g_date_valid_dmy eventually which is pretty unhappy:
>/**
>* g_date_valid_dmy:
>@day: day
>* @month: month
>* @year: year
>*
>* Returns %TRUE if the day-month-year triplet forms a valid, existing day
>* in the range of days #GDate understands (Year 1 or later, no more than
>* a few thousand years in the future).
>*
>* Returns: %TRUE if the date is a valid one
>*/
>gboolean
>g_date_valid_dmy (GDateDay d,
>GDateMonth m,
>GDateYear y)
>{
>return ( (m > G_DATE_BAD_MONTH) &&
>(m < 13) &&
>(d > G_DATE_BAD_DAY) &&
>(y > G_DATE_BAD_YEAR) && /* must check before using g_date_is_leap_year */
>(d <= (g_date_is_leap_year (y) ?
>days_in_months[1][m] : days_in_months[0][m])) );
>}
>Can you check if your time settings are correct on your platform?
?
Thanks Daniel for the advice.?? My time and zone settings look okay:
?
'timedatectl status' gives
?
???? Local time: Tue 2017-09-26 19:30:34 BST
Universal time: Tue 2017-09-26 18:30:34 UTC
????? RTC time: Tue 2017-09-26 18:30:34
????? Time zone: Europe/London (BST, +0100)
Network time on: no
NTP synchronized: no
RTC in local TZ: no
?
Is it possible that this is a bug and ugrading Gilb might help?
?
Connman has been a breeze to run in the past.? This IS my first 64bit system.
?
Cliff
?
?
------------------------------
Message: 2
Date: Wed, 27 Sep 2017 09:34:32 +0200
From: Daniel Wagner <[email protected]>
To: Cliff McDiarmid <[email protected]>, [email protected]
Subject: Re: Fw: Re: Connman coredump
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8; format=flowed
Hi Cliff,
> 'timedatectl status' gives
>
>
> ???? Local time: Tue 2017-09-26 19:30:34 BST
> Universal time: Tue 2017-09-26 18:30:34 UTC
> ????? RTC time: Tue 2017-09-26 18:30:34
> ????? Time zone: Europe/London (BST, +0100)
> Network time on: no
> NTP synchronized: no
> RTC in local TZ: no
>
> Is it possible that this is a bug and ugrading Gilb might help?
Maybe, but unlikely. But if it is easy to upgrade or try a different
version it might be worth to try.
> Connman has been a breeze to run in the past.? This IS my first 64bit system.
What kind of distro are you using? Did you upgrade from a 32bit
installation to 64bit and keeping the /var/lib/connman directory? If so,
we just might have to problem, that the history files etc are in 32bit
and not in 64bit. Just a wild guess.
Thanks,
Daniel
------------------------------
Message: 3
Date: Wed, 27 Sep 2017 15:05:39 +0300
From: Ismo Puustinen <[email protected]>
To: [email protected]
Subject: [PATCH 1/2] resolver: add support for systemd-resolved.
Message-ID: <[email protected]>
If systemd-resolved is running, use it for DNS address resolution. In
this case just deliver the DNS addresses to systemd-resolved and do not
run our own DNS proxy. The systemd-resolved support is selected to
be used if command line option "-s" is passed to connmand. This
implicitly disables connmand's DNS proxy.
---
src/connman.h | 2 +-
src/main.c | 5 +-
src/resolver.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 229 insertions(+), 12 deletions(-)
diff --git a/src/connman.h b/src/connman.h
index 21b70802..1f7afdbc 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -249,7 +249,7 @@ char **__connman_inet_get_pnp_nameservers(const char
*pnp_file);
#include <connman/resolver.h>
-int __connman_resolver_init(gboolean dnsproxy);
+int __connman_resolver_init(gboolean dnsproxy, gboolean resolved);
void __connman_resolver_cleanup(void);
void __connman_resolver_append_fallback_nameservers(void);
int __connman_resolvfile_append(int index, const char *domain, const char
*server);
diff --git a/src/main.c b/src/main.c
index b78a0461..2cb5c56e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -511,6 +511,7 @@ static gchar *option_noplugin = NULL;
static gchar *option_wifi = NULL;
static gboolean option_detach = TRUE;
static gboolean option_dnsproxy = TRUE;
+static gboolean option_resolved = FALSE;
static gboolean option_backtrace = TRUE;
static gboolean option_version = FALSE;
@@ -572,6 +573,8 @@ static GOptionEntry options[] = {
{ "nodnsproxy", 'r', G_OPTION_FLAG_REVERSE,
G_OPTION_ARG_NONE, &option_dnsproxy,
"Don't enable DNS Proxy" },
+ { "resolvedproxy", 's', 0, G_OPTION_ARG_NONE, &option_resolved,
+ "Use systemd-resolved for DNS management" },
{ "nobacktrace", 0, G_OPTION_FLAG_REVERSE,
G_OPTION_ARG_NONE, &option_backtrace,
"Don't print out backtrace information" },
@@ -762,7 +765,7 @@ int main(int argc, char *argv[])
__connman_plugin_init(option_plugin, option_noplugin);
- __connman_resolver_init(option_dnsproxy);
+ __connman_resolver_init(option_dnsproxy, option_resolved);
__connman_rtnl_start();
__connman_dhcp_init();
__connman_dhcpv6_init();
diff --git a/src/resolver.c b/src/resolver.c
index 75ea5ba6..62abb4a2 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -32,11 +32,15 @@
#include <sys/stat.h>
#include <resolv.h>
#include <netdb.h>
+#include <gdbus.h>
+#include <connman/dbus.h>
#include "connman.h"
#define RESOLV_CONF_STATEDIR STATEDIR"/resolv.conf"
#define RESOLV_CONF_ETC "/etc/resolv.conf"
+#define SYSTEMD_RESOLVED_SERVICE "org.freedesktop.resolve1"
+#define SYSTEMD_RESOLVED_PATH "/org/freedesktop/resolve1"
#define RESOLVER_FLAG_PUBLIC (1 << 0)
@@ -58,6 +62,9 @@ struct entry_data {
static GSList *entry_list = NULL;
static bool dnsproxy_enabled = false;
+static DBusConnection *connection = NULL;
+static GDBusClient *client = NULL;
+static GDBusProxy *resolved_proxy = NULL;
struct resolvfile_entry {
int index;
@@ -67,6 +74,154 @@ struct resolvfile_entry {
static GList *resolvfile_list = NULL;
+static void revertlink_append(DBusMessageIter *iter, void *user_data)
+{
+ int *index = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, index);
+}
+
+static int resolved_remove_all(int index)
+{
+ gboolean result;
+
+ result = g_dbus_proxy_method_call(resolved_proxy, "RevertLink",
+ revertlink_append, NULL, &index, NULL);
+
+ if (result == FALSE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void setlinkdns_append(DBusMessageIter *iter, void *user_data)
+{
+ struct resolvfile_entry *entry = NULL;
+ int result, *index = user_data;
+ unsigned i;
+ int type;
+ char ipv4_bytes[4];
+ char ipv6_bytes[16];
+ GList *list;
+
+ DBusMessageIter address_array, struct_array, byte_array;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, index);
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(iay)",
+ &address_array);
+
+ for (list = g_list_first(resolvfile_list); list; list =
g_list_next(list)) {
+ entry = list->data;
+
+ DBG("setlinkdns_append: index: %d, server: %s, domain: %s",
+ entry->index, entry->server ? entry->server :
"NULL",
+ entry->domain ? entry->domain : "NULL");
+
+ if (entry->index != *index || entry->server == NULL)
+ continue;
+
+ dbus_message_iter_open_container(&address_array,
DBUS_TYPE_STRUCT, NULL,
+ &struct_array);
+
+ type = connman_inet_check_ipaddress(entry->server);
+
+ if (type == AF_INET) {
+ result = inet_pton(type, entry->server, ipv4_bytes);
+ if (!result) {
+ DBG("Failed to parse IPv4 address: %s",
entry->server);
+ return;
+ }
+ dbus_message_iter_append_basic(&struct_array,
DBUS_TYPE_INT32,
+ &type);
+ dbus_message_iter_open_container(&struct_array,
DBUS_TYPE_ARRAY,
+ "y", &byte_array);
+ for (i = 0; i < sizeof(ipv4_bytes); i++) {
+ dbus_message_iter_append_basic(&byte_array,
DBUS_TYPE_BYTE,
+ &(ipv4_bytes[i]));
+ }
+ dbus_message_iter_close_container(&struct_array,
&byte_array);
+ }
+ else {
+ result = inet_pton(type, entry->server, ipv6_bytes);
+ if (!result) {
+ DBG("Failed to parse IPv4 address: %s",
entry->server);
+ return;
+ }
+ dbus_message_iter_append_basic(&struct_array,
DBUS_TYPE_INT32,
+ &type);
+ dbus_message_iter_open_container(&struct_array,
DBUS_TYPE_ARRAY,
+ "y", &byte_array);
+ for (i = 0; i < sizeof(ipv6_bytes); i++) {
+ dbus_message_iter_append_basic(&byte_array,
DBUS_TYPE_BYTE,
+ &(ipv6_bytes[i]));
+ }
+ dbus_message_iter_close_container(&struct_array,
&byte_array);
+ }
+ dbus_message_iter_close_container(&address_array,
&struct_array);
+ }
+
+ dbus_message_iter_close_container(iter, &address_array);
+}
+
+static void setlinkdomains_append(DBusMessageIter *iter, void *user_data)
+{
+ struct resolvfile_entry *entry;
+ int *index = user_data;
+ DBusMessageIter domain_array, struct_array;
+ gboolean only_routing = FALSE;
+ GList *list;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, index);
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(sb)",
+ &domain_array);
+
+ for (list = g_list_first(resolvfile_list); list; list =
g_list_next(list)) {
+ entry = list->data;
+
+ DBG("setlinkdomains_append: index: %d, server: %s, domain: %s",
+ entry->index, entry->server ? entry->server :
"NULL",
+ entry->domain ? entry->domain : "NULL");
+
+ if (entry->index != *index || entry->domain == NULL)
+ continue;
+
+ dbus_message_iter_open_container(&domain_array,
DBUS_TYPE_STRUCT, NULL,
+ &struct_array);
+
+ dbus_message_iter_append_basic(&struct_array, DBUS_TYPE_STRING,
+ &entry->domain);
+ dbus_message_iter_append_basic(&struct_array, DBUS_TYPE_BOOLEAN,
+ &only_routing);
+
+ dbus_message_iter_close_container(&domain_array, &struct_array);
+ }
+ dbus_message_iter_close_container(iter, &domain_array);
+}
+
+static int resolved_export(int index)
+{
+ gboolean result;
+
+ if (!resolved_proxy)
+ return -ENOENT;
+
+ /* No async error processing -- just fire and forget */
+
+ result = g_dbus_proxy_method_call(resolved_proxy, "SetLinkDNS",
+ setlinkdns_append, NULL, &index, NULL);
+ if (result == FALSE)
+ return -EINVAL;
+
+ result = g_dbus_proxy_method_call(resolved_proxy, "SetLinkDomains",
+ setlinkdomains_append, NULL, &index, NULL);
+ if (result == FALSE)
+ return -EINVAL;
+
+ return 0;
+}
+
static void resolvfile_remove_entries(GList *entries)
{
GList *list;
@@ -188,11 +343,14 @@ int __connman_resolvfile_append(int index, const char
*domain,
resolvfile_list = g_list_append(resolvfile_list, entry);
+ if (resolved_proxy)
+ return resolved_export(index);
+
return resolvfile_export();
}
-int __connman_resolvfile_remove(int index, const char *domain,
- const char *server)
+static int __connman_resolvfile_remove_entry(int index, const char *domain,
+ const char *server,
gboolean remove_from_resolved)
{
GList *list, *matches = NULL;
@@ -215,9 +373,22 @@ int __connman_resolvfile_remove(int index, const char
*domain,
resolvfile_remove_entries(matches);
+ if (resolved_proxy) {
+ if (remove_from_resolved)
+ return resolved_export(index);
+ else
+ return 0; /* whole link is reset later */
+ }
+
return resolvfile_export();
}
+int __connman_resolvfile_remove(int index, const char *domain,
+ const char *server)
+{
+ return __connman_resolvfile_remove_entry(index, domain, server, TRUE);
+}
+
void __connman_resolver_append_fallback_nameservers(void)
{
GSList *list;
@@ -269,7 +440,7 @@ static void remove_fallback_nameservers(void)
}
}
-static void remove_entries(GSList *entries)
+static void remove_entries(GSList *entries, int index)
{
GSList *list;
@@ -282,8 +453,8 @@ static void remove_entries(GSList *entries)
__connman_dnsproxy_remove(entry->index, entry->domain,
entry->server);
} else {
- __connman_resolvfile_remove(entry->index, entry->domain,
- entry->server);
+ __connman_resolvfile_remove_entry(entry->index,
entry->domain,
+ entry->server, index <
0 ? TRUE : FALSE);
}
if (entry->timeout)
@@ -295,6 +466,9 @@ static void remove_entries(GSList *entries)
g_slist_free(entries);
+ if (resolved_proxy && index >= 0)
+ resolved_remove_all(index);
+
__connman_resolver_append_fallback_nameservers();
}
@@ -316,7 +490,7 @@ static gboolean resolver_expire_cb(gpointer user_data)
entry->server, true);
}
- remove_entries(list);
+ remove_entries(list, -1);
return FALSE;
}
@@ -538,7 +712,7 @@ int connman_resolver_remove(int index, const char *domain,
const char *server)
if (!matches)
return -ENOENT;
- remove_entries(matches);
+ remove_entries(matches, -1);
return 0;
}
@@ -570,7 +744,10 @@ int connman_resolver_remove_all(int index)
if (!matches)
return -ENOENT;
- remove_entries(matches);
+ if (resolved_proxy)
+ return resolved_remove_all(index);
+
+ remove_entries(matches, index);
return 0;
}
@@ -652,12 +829,34 @@ static void free_resolvfile(gpointer data)
g_free(entry);
}
-int __connman_resolver_init(gboolean dnsproxy)
+int __connman_resolver_init(gboolean dnsproxy, gboolean resolved)
{
int i;
char **ns;
- DBG("dnsproxy %d", dnsproxy);
+ DBG("dnsproxy %d, resolved %d", dnsproxy, resolved);
+
+ if (resolved) {
+ connection = connman_dbus_get_connection();
+
+ if (connection) {
+ client = g_dbus_client_new(connection,
+ SYSTEMD_RESOLVED_SERVICE,
SYSTEMD_RESOLVED_PATH);
+ if (!client)
+ DBG("Failed to initialize proxy for
systemd-resolved");
+ else {
+ resolved_proxy = g_dbus_proxy_new(client,
SYSTEMD_RESOLVED_PATH,
+
"org.freedesktop.resolve1.Manager");
+
+ if (resolved_proxy) {
+ /* setup succeeded, disable dnsproxy */
+ dnsproxy = FALSE;
+ }
+ else
+ DBG("Failed to initialize proxy for
systemd-resolved");
+ }
+ }
+ }
/* get autoip nameservers */
ns = __connman_inet_get_pnp_nameservers(NULL);
@@ -706,4 +905,19 @@ void __connman_resolver_cleanup(void)
g_slist_free(entry_list);
entry_list = NULL;
}
+
+ if (resolved_proxy) {
+ g_dbus_proxy_unref(resolved_proxy);
+ resolved_proxy = NULL;
+ }
+
+ if (client) {
+ g_dbus_client_unref(client);
+ client = NULL;
+ }
+
+ if (connection) {
+ dbus_connection_unref(connection);
+ connection = NULL;
+ }
}
--
2.13.5
------------------------------
Message: 4
Date: Wed, 27 Sep 2017 15:05:40 +0300
From: Ismo Puustinen <[email protected]>
To: [email protected]
Subject: [PATCH 2/2] service: add mDNS support on per-interface basis.
Message-ID: <[email protected]>
Currently mDNS support requires systemd-resolved. However, there's
nothing to prevent other mDNS backends. The mDNS state is exposed over
D-Bus for service objects.
The mDNS activation is triggered via "Method" key for mDNS.Configuration
property. Allowed string values are "enabled", "disabled", and
"resolve_only". Value "enabled" means that mDNS domains are resolved by
systemd-resolved and current host name is registered. Value "no" means
that mDNS is turned off for the service. Value "resolve_only" means that
the hostname is not registered, but mDNS resolving is supported.
You can test this by enabling mDNS support for service "service_name"
with the following command:
busctl call net.connman /net/connman/service/service_name \
net.connman.Service SetProperty sv mDNS.Configuration \
a{sv} 1 Method s enabled
---
doc/config-format.txt | 7 ++
doc/service-api.txt | 18 +++++
include/service.h | 8 +++
src/config.c | 15 ++++
src/connman.h | 3 +
src/resolver.c | 49 +++++++++++++
src/service.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 293 insertions(+)
diff --git a/doc/config-format.txt b/doc/config-format.txt
index ed3123aa..68e5bf2e 100644
--- a/doc/config-format.txt
+++ b/doc/config-format.txt
@@ -63,6 +63,13 @@ Allowed fields:
- SearchDomains: Comma separated list of DNS search domains
- Timeservers: Comma separated list of timeservers
- Domain: Domain name to be used
+- mDNS.Method: Supported values are "enabled", "disabled", or
+ "only_resolve". The "only_resolve" value doesn't register the hostname
+ for mDNS, but allows resolving of mDNS domains. Value "enabled" means
+ support for both resolving and hostname registration, and "disabled"
+ means that mDNS support is disabled. Note that mDNS support requires
+ at the moment using systemd-resolved for DNS (use -s command line option
+ for connmand).
If IPv4 address is missing then DHCP is used. If IPv6 address is missing,
then SLAAC or DHCPv6 is used.
diff --git a/doc/service-api.txt b/doc/service-api.txt
index 6cdb0bb5..dbdada59 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -500,3 +500,21 @@ Properties string State [readonly]
Possible values are "half" and "full".
This information is not available.
+
+ dict mDNS [readonly]
+
+ string Method [readonly]
+
+ Possible values are "enabled", "disabled", and
+ "only_resolve".
+
+ If both mDNS resolving and hostname
registration are needed,
+ "enabled" should be selected. If only mDNS
resolving is
+ required, select "only_resolve". Select
"disabled" if mDNS
+ should be disabled for this service.
+
+ dict mDNS.Configuration [readwrite]
+
+ Same values as mDNS property. The mDNS represents
+ the actual system configuration while this allows
+ user configuration.
diff --git a/include/service.h b/include/service.h
index 958e7fd1..5475b26a 100644
--- a/include/service.h
+++ b/include/service.h
@@ -89,6 +89,13 @@ enum connman_service_proxy_method {
CONNMAN_SERVICE_PROXY_METHOD_AUTO = 3,
};
+enum connman_service_mdns_method {
+ CONNMAN_SERVICE_MDNS_METHOD_UNKNOWN = 0,
+ CONNMAN_SERVICE_MDNS_METHOD_ENABLED = 1,
+ CONNMAN_SERVICE_MDNS_METHOD_ONLY_RESOLVE = 2,
+ CONNMAN_SERVICE_MDNS_METHOD_DISABLED = 3,
+};
+
enum connman_service_connect_reason {
CONNMAN_SERVICE_CONNECT_REASON_NONE = 0,
CONNMAN_SERVICE_CONNECT_REASON_AUTO = 1,
@@ -96,6 +103,7 @@ enum connman_service_connect_reason {
CONNMAN_SERVICE_CONNECT_REASON_SESSION = 3,
};
+
struct connman_service;
struct connman_network;
diff --git a/src/config.c b/src/config.c
index a8c3da89..5f6abb19 100644
--- a/src/config.c
+++ b/src/config.c
@@ -72,6 +72,7 @@ struct connman_config_service {
char *ipv6_gateway;
char *ipv6_privacy;
char *mac;
+ char *mdns;
char **nameservers;
char **search_domains;
char **timeservers;
@@ -112,6 +113,7 @@ static bool cleanup = false;
#define SERVICE_KEY_PASSPHRASE "Passphrase"
#define SERVICE_KEY_SECURITY "Security"
#define SERVICE_KEY_HIDDEN "Hidden"
+#define SERVICE_KEY_MDNS "mDNS.Method"
#define SERVICE_KEY_IPv4 "IPv4"
#define SERVICE_KEY_IPv6 "IPv6"
@@ -152,6 +154,7 @@ static const char *service_possible_keys[] = {
SERVICE_KEY_IPv6,
SERVICE_KEY_IPv6_PRIVACY,
SERVICE_KEY_MAC,
+ SERVICE_KEY_MDNS,
SERVICE_KEY_NAMESERVERS,
SERVICE_KEY_SEARCH_DOMAINS,
SERVICE_KEY_TIMESERVERS,
@@ -254,6 +257,7 @@ free_only:
g_free(config_service->ipv6_gateway);
g_free(config_service->ipv6_privacy);
g_free(config_service->mac);
+ g_free(config_service->mdns);
g_strfreev(config_service->nameservers);
g_strfreev(config_service->search_domains);
g_strfreev(config_service->timeservers);
@@ -514,6 +518,13 @@ static bool load_service_generic(GKeyFile *keyfile,
g_strfreev(strlist);
}
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_MDNS, NULL);
+ if (str) {
+ g_free(service->mdns);
+ service->mdns = str;
+ }
+
return true;
err:
@@ -525,6 +536,7 @@ err:
g_free(service->ipv6_address);
g_free(service->ipv6_gateway);
g_free(service->mac);
+ g_free(service->mdns);
g_free(service);
return false;
@@ -1377,6 +1389,9 @@ static int try_provision_service(struct
connman_config_service *config,
__connman_service_set_search_domains(service,
config->search_domains);
+ if (config->mdns)
+ __connman_service_set_mdns(service, config->mdns);
+
if (config->timeservers)
__connman_service_set_timeservers(service,
config->timeservers);
diff --git a/src/connman.h b/src/connman.h
index 1f7afdbc..bebe2420 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -255,6 +255,7 @@ void __connman_resolver_append_fallback_nameservers(void);
int __connman_resolvfile_append(int index, const char *domain, const char
*server);
int __connman_resolvfile_remove(int index, const char *domain, const char
*server);
int __connman_resolver_redo_servers(int index);
+int __connman_resolver_set_mdns(int index, const char *mdns);
GKeyFile *__connman_storage_open_global(void);
GKeyFile *__connman_storage_load_global(void);
@@ -704,6 +705,8 @@ int __connman_service_set_ignore(struct connman_service
*service,
bool ignore);
void __connman_service_set_search_domains(struct connman_service *service,
char **domains);
+int __connman_service_set_mdns(struct connman_service *service,
+ const char *mdns);
void __connman_service_set_string(struct connman_service *service,
const char *key, const char *value);
diff --git a/src/resolver.c b/src/resolver.c
index 62abb4a2..f6f7fab6 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -72,6 +72,11 @@ struct resolvfile_entry {
char *server;
};
+struct mdns_data {
+ int index;
+ const char *mdns;
+};
+
static GList *resolvfile_list = NULL;
static void revertlink_append(DBusMessageIter *iter, void *user_data)
@@ -85,6 +90,10 @@ static int resolved_remove_all(int index)
{
gboolean result;
+ /* FIXME: Reverting the link also removes the current mDNS settings.
+ * However, it's not clear whether the purpose is to disable DNS
+ * resolution fully when connman_resolver_remove_all is called. */
+
result = g_dbus_proxy_method_call(resolved_proxy, "RevertLink",
revertlink_append, NULL, &index, NULL);
@@ -222,6 +231,46 @@ static int resolved_export(int index)
return 0;
}
+static void setlinkmulticastdns_append(DBusMessageIter *iter, void *user_data)
+{
+ struct mdns_data *data = user_data;
+ char *val = NULL;
+
+ if (strcmp(data->mdns, "enabled") == 0)
+ val = "yes";
+ else if (strcmp(data->mdns, "disabled") == 0)
+ val = "no";
+ else if (strcmp(data->mdns, "only_resolve") == 0)
+ val = "resolve";
+ if (val == NULL)
+ val = ""; /* use system default */
+
+ DBG("SetLinkMulticastDNS: %d/%s", data->index, val);
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &data->index);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &val);
+}
+
+int __connman_resolver_set_mdns(int index, const char *mdns)
+{
+ gboolean result;
+ struct mdns_data data = { index, mdns };
+
+ /* Currently supported only for systemd-resolved */
+ if (!resolved_proxy)
+ return -ENOENT;
+
+ if (mdns == NULL || index < 0)
+ return -EINVAL;
+
+ result = g_dbus_proxy_method_call(resolved_proxy, "SetLinkMulticastDNS",
+ setlinkmulticastdns_append, NULL, &data, NULL);
+ if (result == FALSE)
+ return -EINVAL;
+
+ return 0;
+}
+
static void resolvfile_remove_entries(GList *entries)
{
GList *list;
diff --git a/src/service.c b/src/service.c
index 02cd51f2..4e8cbed4 100644
--- a/src/service.c
+++ b/src/service.c
@@ -94,6 +94,8 @@ struct connman_service {
char **nameservers_auto;
int nameservers_timeout;
char **domains;
+ enum connman_service_mdns_method mdns;
+ enum connman_service_mdns_method mdns_config;
char *hostname;
char *domainname;
char **timeservers;
@@ -355,6 +357,34 @@ static enum connman_service_proxy_method
string2proxymethod(const char *method)
return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
}
+static const char * mdnsmethod2string(enum connman_service_mdns_method method)
+{
+ switch (method) {
+ case CONNMAN_SERVICE_MDNS_METHOD_ENABLED:
+ return "enabled";
+ case CONNMAN_SERVICE_MDNS_METHOD_DISABLED:
+ return "disabled";
+ case CONNMAN_SERVICE_MDNS_METHOD_ONLY_RESOLVE:
+ return "only_resolve";
+ case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
+ return "unknown";
+ }
+
+ return NULL;
+}
+
+static enum connman_service_mdns_method string2mdnsmethod(const char *method)
+{
+ if (g_strcmp0(method, "enabled") == 0)
+ return CONNMAN_SERVICE_MDNS_METHOD_ENABLED;
+ else if (g_strcmp0(method, "disabled") == 0)
+ return CONNMAN_SERVICE_MDNS_METHOD_DISABLED;
+ else if (g_strcmp0(method, "only_resolve") == 0)
+ return CONNMAN_SERVICE_MDNS_METHOD_ONLY_RESOLVE;
+ else
+ return CONNMAN_SERVICE_MDNS_METHOD_UNKNOWN;
+}
+
static void set_split_routing(struct connman_service *service, bool value)
{
if (service->type != CONNMAN_SERVICE_TYPE_VPN)
@@ -594,6 +624,13 @@ static int service_load(struct connman_service *service)
service->pac = str;
}
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "mDNS.Method", NULL);
+ if (str)
+ service->mdns_config = string2mdnsmethod(str);
+
+ g_free(str);
+
service->hidden_service = g_key_file_get_boolean(keyfile,
service->identifier, "Hidden", NULL);
@@ -774,6 +811,13 @@ static int service_save(struct connman_service *service)
g_key_file_remove_key(keyfile, service->identifier,
"Proxy.URL", NULL);
+ if (service->mdns_config != CONNMAN_SERVICE_MDNS_METHOD_UNKNOWN)
+ g_key_file_set_string(keyfile, service->identifier,
+ "mDNS.Method",
mdnsmethod2string(service->mdns_config));
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "mDNS.Method", NULL);
+
if (service->hidden_service)
g_key_file_set_boolean(keyfile, service->identifier, "Hidden",
TRUE);
@@ -1942,6 +1986,28 @@ static void append_proxyconfig(DBusMessageIter *iter,
void *user_data)
DBUS_TYPE_STRING, &method);
}
+static void append_mdnsconfig(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
+ const char *method;
+
+ method = mdnsmethod2string(service->mdns_config);
+
+ connman_dbus_dict_append_basic(iter, "Method",
+ DBUS_TYPE_STRING, &method);
+}
+
+static void append_mdns(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
+ const char *method;
+
+ method = mdnsmethod2string(service->mdns);
+
+ connman_dbus_dict_append_basic(iter, "Method",
+ DBUS_TYPE_STRING, &method);
+}
+
static void append_provider(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
@@ -2075,6 +2141,47 @@ static void proxy_configuration_changed(struct
connman_service *service)
proxy_changed(service);
}
+static void mdns_changed(struct connman_service *service)
+{
+ if (!allow_property_changed(service))
+ return;
+
+ connman_dbus_property_changed_dict(service->path,
+ CONNMAN_SERVICE_INTERFACE, "mDNS",
+ append_mdns, service);
+}
+
+static void mdns_configuration_changed(struct connman_service *service)
+{
+ if (!allow_property_changed(service))
+ return;
+
+ connman_dbus_property_changed_dict(service->path,
+ CONNMAN_SERVICE_INTERFACE, "mDNS.Configuration",
+ append_mdnsconfig, service);
+}
+
+static int set_mdns(struct connman_service *service,
+ enum connman_service_mdns_method method)
+{
+ int result;
+
+ if (method == CONNMAN_SERVICE_MDNS_METHOD_UNKNOWN)
+ return -EINVAL;
+
+ result =
__connman_resolver_set_mdns(__connman_service_get_index(service),
+ mdnsmethod2string(method));
+
+ if (result == 0) {
+ if (service->mdns != method) {
+ service->mdns = method;
+ mdns_changed(service);
+ }
+ }
+
+ return result;
+}
+
static void timeservers_configuration_changed(struct connman_service *service)
{
if (!allow_property_changed(service))
@@ -2452,6 +2559,11 @@ static void append_properties(DBusMessageIter *dict,
dbus_bool_t limited,
connman_dbus_dict_append_dict(dict, "Proxy.Configuration",
append_proxyconfig, service);
+ connman_dbus_dict_append_dict(dict, "mDNS", append_mdns, service);
+
+ connman_dbus_dict_append_dict(dict, "mDNS.Configuration",
+ append_mdnsconfig, service);
+
connman_dbus_dict_append_dict(dict, "Provider",
append_provider, service);
}
@@ -3257,6 +3369,59 @@ error:
return -EINVAL;
}
+static int update_mdns_configuration(struct connman_service *service,
+ DBusMessageIter *array)
+{
+ DBusMessageIter dict;
+ enum connman_service_mdns_method method;
+
+ method = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
+
+ dbus_message_iter_recurse(array, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, variant;
+ const char *key;
+ int type;
+
+ dbus_message_iter_recurse(&dict, &entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+ goto error;
+
+ dbus_message_iter_recurse(&entry, &variant);
+
+ type = dbus_message_iter_get_arg_type(&variant);
+
+ if (g_str_equal(key, "Method")) {
+ const char *val;
+
+ if (type != DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_get_basic(&variant, &val);
+ method = string2mdnsmethod(val);
+
+ if (method == CONNMAN_SERVICE_MDNS_METHOD_UNKNOWN)
+ goto error;
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ service->mdns_config = method;
+ return 0;
+
+error:
+ return -EINVAL;
+}
+
int __connman_service_reset_ipconfig(struct connman_service *service,
enum connman_ipconfig_type type, DBusMessageIter *array,
enum connman_service_state *new_state)
@@ -3571,6 +3736,25 @@ static DBusMessage *set_property(DBusConnection *conn,
__connman_notifier_proxy_changed(service);
service_save(service);
+ } else if (g_str_equal(name, "mDNS.Configuration")) {
+ int err;
+
+ if (service->immutable)
+ return __connman_error_not_supported(msg);
+
+ if (type != DBUS_TYPE_ARRAY)
+ return __connman_error_invalid_arguments(msg);
+
+ err = update_mdns_configuration(service, &value);
+
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+
+ mdns_configuration_changed(service);
+
+ set_mdns(service, service->mdns_config);
+
+ service_save(service);
} else if (g_str_equal(name, "IPv4.Configuration") ||
g_str_equal(name, "IPv6.Configuration")) {
@@ -5273,6 +5457,14 @@ void __connman_service_set_search_domains(struct
connman_service *service,
searchdomain_add_all(service);
}
+int __connman_service_set_mdns(struct connman_service *service,
+ const char *mdns)
+{
+ /* double conversion for validating input */
+
+ return set_mdns(service, string2mdnsmethod(mdns));
+}
+
static void report_error_cb(void *user_context, bool retry,
void *user_data)
{
@@ -6001,6 +6193,7 @@ int __connman_service_ipconfig_indicate_state(struct
connman_service *service,
"Default service remains in READY state.");
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
service_rp_filter(service, true);
+ set_mdns(service, service->mdns_config);
break;
case CONNMAN_SERVICE_STATE_ONLINE:
break;
--
2.13.5
------------------------------
Subject: Digest Footer
_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman
------------------------------
End of connman Digest, Vol 23, Issue 18
***************************************