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. Re: [PATCH 1/2] resolver: add support for systemd-resolved.
(Daniel Wagner)
2. Re: [PATCH 2/2] service: add mDNS support on per-interface
basis. (Daniel Wagner)
----------------------------------------------------------------------
Message: 1
Date: Sun, 01 Oct 2017 15:25:00 +0200
From: Daniel Wagner <[email protected]>
To: Ismo Puustinen <[email protected]>
Cc: [email protected]
Subject: Re: [PATCH 1/2] resolver: add support for systemd-resolved.
Message-ID: <[email protected]>
Content-Type: text/plain
Hi Ismo,
Ismo Puustinen <[email protected]> writes:
> 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.
I tried this patch with 'connmand -s -n -d' and systemd-reoslvd is
running in the background. DNS resolve didn't work anymore. Do I need to
change anything on my setup to get this working?
Anyway a few nitpicks below.
> ---
> 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;
> +}
We use the gbooleans 'natively', that is 'if (!val)' instead
of 'if (val == FALSE)'
Also you don't need to introduce here a local variable. Just write
static int resolved_remove_all(int index)
{
if (!g_dbus_proxy_method_call(resolved_proxy, "RevertLink",
revertlink_append, NULL, &index, NULL))
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;
This shold also be part of the declartion block. No new line.
> +
> + 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)) {
No need for g_list_first(). The rest of this file is also using it
without it.
> + entry = list->data;
> +
> + DBG("setlinkdns_append: index: %d, server: %s, domain: %s",
> + entry->index, entry->server ? entry->server :
> "NULL",
> + entry->domain ? entry->domain : "NULL");
No need to add the setlinksdns_append, DBG() adds the function name on
its own:
connmand[23146]: src/resolver.c:setlinkdns_append() setlinkdns_append: index:
2, server: 192.168.154.1, domain: NULL
connmand[23146]: src/resolver.c:setlinkdns_append() setlinkdns_append: index:
2, server: NULL, domain: localdomain
connmand[23146]: src/resolver.c:setlinkdns_append() setlinkdns_append: index:
17, server: 192.168.154.1, domain: NULL
connmand[23146]: src/resolver.c:setlinkdns_append() setlinkdns_append: index:
17, server: NULL, domain: localdomain
> +
> + 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 {
indention should be
} else {
but I rather have an explicit test to 'if (type == AF_INET6)'
I suggest to move the bodies of the if condition into a function. The
lines are too long and the function is a bit too long.
> + 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);
> +}
You should also add some new lines.
> +
> +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");
> +
No function name needed as prefix in the DBG().
> + 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;
if (!g_dbus_proxy_method_call(...))
return -EINVAL;
> +
> + result = g_dbus_proxy_method_call(resolved_proxy, "SetLinkDomains",
> + setlinkdomains_append, NULL, &index, NULL);
> + if (result == FALSE)
> + return -EINVAL;
same here
> +
> + 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)
Use bool here instead of gboolean. We only use gboolean where we have to
because of glib. Internally we just use C99 bools.
And the line is too long.
> {
> 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 */
The 'else' is useless.
if (remove_from_resolved)
return resolved_export(index);
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);
You can just write '..., index < 0)' that make the line short enough to
fit below the 80 chars limit.
> }
>
> 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");
Is this a proper error? In this case use connman_warn() or
connman_error().
> + 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
} else {
> + DBG("Failed to initialize proxy for
> systemd-resolved");
Same here.
And the lines are a bit long.
> + }
> + }
> + }
>
> /* 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;
> + }
> }
Thanks,
Daniel
------------------------------
Message: 2
Date: Sun, 01 Oct 2017 15:45:50 +0200
From: Daniel Wagner <[email protected]>
To: Ismo Puustinen <[email protected]>
Cc: [email protected]
Subject: Re: [PATCH 2/2] service: add mDNS support on per-interface
basis.
Message-ID: <[email protected]>
Content-Type: text/plain
Hi Ismo,
Ismo Puustinen <[email protected]> writes:
> 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
Could you also extend the connmanctl tool? Also having a simple test
script would hurt.
On my system I get for the above command:
Method "SetProperty" with signature "sv" on interface "net.connman.Service"
doesn't exist
Any idea what is going wrong?
And my usual nitpicking:
> ---
> 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).
You need also to update the man page accordingly.
>
> 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.
> +
Limit the block to 80 chars, please.
> + 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,
> };
>
> +
no new line here.
> 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. */\
> +
So can you ever decide this question?
Comment style:
/*
*
*/
> 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)
if (!val)
> + val = ""; /* use system default */
> +
> + DBG("SetLinkMulticastDNS: %d/%s", data->index, val);
DBG("index %d %s", ...)
> +
> + 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;
if (!g_dbus_proxy_method_call(...))
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));
line length
> + 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;
Thanks,
Daniel
------------------------------
Subject: Digest Footer
_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman
------------------------------
End of connman Digest, Vol 24, Issue 1
**************************************