Hi Patrik,

I have question about the nameservers information update question.  There are ipv4 and ipv6 2 configurations for each service.  And the name server information is updated through d-bus in the "dns_changed" function which is called in the service_indicate_state function when the configuration becomes ready state.

But only the first "ready" configuration(either ipv4 or ipv6) is updated because there is a status check in the service_indicate_state function like below.

if (old_state == new_state)
                return -EALREADY;

For example, ipv6 configuration became ready first, the service_indicate_state function will be called and ipv6 dns server is updated by dns_changed.  Later ipv4 configuration become ready, it will NOT call dns_changed function because the service state is already "ready". Thus the ipv4 nameservers are NOT updated.

Can we move this dns_changed function to "__connman_service_ipconfig_indicate_state" like below.

if (!is_connected_state(service, old_state) &&
is_connected_state(service, new_state)) {
nameserver_add_all(service, type);
                dns_changed(service);  /* Function moved here */
        }

Thanks,

Feng



On Fri, Oct 14, 2016 at 5:33 AM, Patrik Flykt <patrik.flykt@linux.intel.com> wrote:
Automatically update nameserver information when they are appended
or removed. Create a zero second timeout so that nameservers can
be appended or removed in a loop one by one with only one D-Bus
PropertyChanged signal being sent.

Verify that the service is either connected or the nameservers have
been removed when the service is inactive before sending the
PropertyChanged signal.
---

        Hi,

Here is a patch that updates nameserver info also if it changes while a
service is connected. The issue was reported by Thomas Green a long time
ago end of August, but at that point I had a bit wrong idea on how to fix
the issue. So here is hopefully a solution that works in all cases.

Please test,

       Patrik


src/service.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/src/service.c b/src/service.c
index ee10e6c..6877b9a 100644
--- a/src/service.c
+++ b/src/service.c
@@ -92,6 +92,7 @@ struct connman_service {
        char **nameservers;
        char **nameservers_config;
        char **nameservers_auto;
+       int nameservers_timeout;
        char **domains;
        char *hostname;
        char *domainname;
@@ -133,6 +134,7 @@ static struct connman_ipconfig *create_ip4config(struct connman_service *service
                int index, enum connman_ipconfig_method method);
 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
                int index);
+static void dns_changed(struct connman_service *service);

 struct find_data {
        const char *path;
@@ -922,6 +924,24 @@ static bool is_connected_state(const struct connman_service *service,
        return false;
 }

+static bool is_idle(struct connman_service *service)
+{
+       switch (service->state) {
+       case CONNMAN_SERVICE_STATE_IDLE:
+       case CONNMAN_SERVICE_STATE_DISCONNECT:
+       case CONNMAN_SERVICE_STATE_FAILURE:
+               return true;
+       case CONNMAN_SERVICE_STATE_UNKNOWN:
+       case CONNMAN_SERVICE_STATE_ASSOCIATION:
+       case CONNMAN_SERVICE_STATE_CONFIGURATION:
+       case CONNMAN_SERVICE_STATE_READY:
+       case CONNMAN_SERVICE_STATE_ONLINE:
+               break;
+       }
+
+       return false;
+}
+
 static bool is_connecting(struct connman_service *service)
 {
        return is_connecting_state(service, service->state);
@@ -932,6 +952,29 @@ static bool is_connected(struct connman_service *service)
        return is_connected_state(service, service->state);
 }

+
+static int nameservers_changed_cb(void *user_data)
+{
+       struct connman_service *service = user_data;
+
+       DBG("service %p", service);
+
+       service->nameservers_timeout = 0;
+       if ((is_idle(service) && !service->nameservers) ||
+                       is_connected(service))
+               dns_changed(service);
+
+       return FALSE;
+}
+
+static void nameservers_changed(struct connman_service *service)
+{
+       if (!service->nameservers_timeout)
+               service->nameservers_timeout = g_timeout_add_seconds(0,
+                                                       nameservers_changed_cb,
+                                                       service);
+}
+
 static bool nameserver_available(struct connman_service *service,
                                enum connman_ipconfig_type type,
                                const char *ns)
@@ -1139,6 +1182,8 @@ int __connman_service_nameserver_append(struct connman_service *service,
                nameserver_add(service, CONNMAN_IPCONFIG_TYPE_ALL, nameserver);
        }

+       nameservers_changed(service);
+
        searchdomain_add_all(service);

        return 0;
@@ -1207,6 +1252,8 @@ set_servers:
                                nameserver);
        }

+       nameservers_changed(service);
+
        return 0;
 }

@@ -4500,6 +4547,11 @@ static void service_free(gpointer user_data)

        reply_pending(service, ENOENT);

+       if (service->nameservers_timeout) {
+               g_source_remove(service->nameservers_timeout);
+               dns_changed(service);
+       }
+
        __connman_notifier_service_remove(service);
        service_schedule_removed(service);

@@ -5440,7 +5492,7 @@ static int service_indicate_state(struct connman_service *service)
                g_get_current_time(&service->modified);
                service_save(service);

-               dns_changed(service);
+               nameservers_changed(service);
                domain_changed(service);
                proxy_changed(service);

@@ -5481,7 +5533,7 @@ static int service_indicate_state(struct connman_service *service)

                __connman_wpad_stop(service);

-               dns_changed(service);
+               nameservers_changed(service);
                domain_changed(service);
                proxy_changed(service);

--
2.9.3

_______________________________________________
connman mailing list
connman@lists.01.org
https://lists.01.org/mailman/listinfo/connman