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

Reply via email to