From 8f3c51386929c432af4d78c1e8ab1d82a1f6ac8b Mon Sep 17 00:00:00 2001 From: Alok Barsode Date: Fri, 3 Feb 2012 20:26:00 +0200 Subject: [PATCH] Add __connman_timerserver_sync() to resolve a list of timeservers __connman_timerserver_sync() resolves system timeservers one at a time and queries the resolved server or the 1st of the resolved servers for time correction. If the resolution fails it resolves the next one. __connman_timerserver_sync_next() resolves the next system timeserver. __connman_timerserver_stop() stops this query.If the user modifies the system timeserver list, we restart the ntp process. --- include/timeserver.h | 1 - src/connman.h | 4 ++ src/ntp.c | 2 +- src/service.c | 7 +-- src/timeserver.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 142 insertions(+), 14 deletions(-) diff --git a/include/timeserver.h b/include/timeserver.h index 3749482..e37fada 100644 --- a/include/timeserver.h +++ b/include/timeserver.h @@ -38,7 +38,6 @@ extern "C" { int connman_timeserver_append(const char *server); int connman_timeserver_remove(const char *server); -void connman_timeserver_sync(void); int __connman_timeserver_system_append(const char *server); int __connman_timeserver_system_remove(const char *server); diff --git a/src/connman.h b/src/connman.h index 5c63503..dcde0f3 100644 --- a/src/connman.h +++ b/src/connman.h @@ -321,6 +321,10 @@ void __connman_timeserver_cleanup(void); char **__connman_timeserver_system_get(); +int __connman_timeserver_sync(struct connman_service *service); +void __connman_timeserver_sync_next(); +void __connman_timeserver_stop(); + typedef void (* dhcp_cb) (struct connman_network *network, connman_bool_t success); int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback); diff --git a/src/ntp.c b/src/ntp.c index f70dfc7..4d3cd88 100644 --- a/src/ntp.c +++ b/src/ntp.c @@ -329,7 +329,7 @@ send: int __connman_ntp_start(char *server) { - DBG(""); + DBG("%s", server); if (server == NULL) return -EINVAL; diff --git a/src/service.c b/src/service.c index 42117a3..2fe93fc 100644 --- a/src/service.c +++ b/src/service.c @@ -3992,9 +3992,8 @@ static int service_indicate_state(struct connman_service *service) } } - if (new_state == CONNMAN_SERVICE_STATE_ONLINE) { - connman_timeserver_sync(); - } + if (new_state == CONNMAN_SERVICE_STATE_ONLINE) + __connman_timeserver_sync(service); if (new_state == CONNMAN_SERVICE_STATE_IDLE) { connman_bool_t reconnect; @@ -4065,6 +4064,8 @@ static int service_indicate_state(struct connman_service *service) dns_changed(service); domain_changed(service); + __connman_timeserver_stop(); + __connman_notifier_disconnect(service->type); /* diff --git a/src/timeserver.c b/src/timeserver.c index 3bdc74f..2af173d 100644 --- a/src/timeserver.c +++ b/src/timeserver.c @@ -26,12 +26,24 @@ #include #include +#include +#include #include "connman.h" static GSList *driver_list = NULL; static GHashTable *server_hash = NULL; +static char **system_timeservers = NULL; + +static GResolv *resolv = NULL; +static int resolv_id = 0; +static volatile int count; + +static void resolv_debug(const char *str, void *data) +{ + connman_info("%s: %s\n", (const char *) data, str); +} static void save_timeservers(char **servers) { GKeyFile *keyfile; @@ -182,20 +194,128 @@ int connman_timeserver_remove(const char *server) return driver->remove(server); } -void connman_timeserver_sync(void) +/* Restart NTP procedure */ +static void connman_timeserver_restart() { - GSList *list; + if (resolv == NULL) { + DBG("No online service."); + return; + } - DBG(""); + /* Cancel current lookup */ + if(resolv_id > 0) + g_resolv_cancel_lookup(resolv, resolv_id); - for (list = driver_list; list; list = list->next) { - struct connman_timeserver_driver *driver = list->data; + /* Reload system timeserver list */ + if (system_timeservers != NULL) { + g_strfreev(system_timeservers); + system_timeservers = NULL; + } - if (driver->sync == NULL) - continue; + system_timeservers = load_timeservers(); + + if (system_timeservers == NULL) + return; + + __connman_ntp_stop(); + + count = 0; + + __connman_timeserver_sync_next(); +} + +static void resolv_result(GResolvResultStatus status, char **results, gpointer user_data) +{ + int i; + + DBG("status %d", status); + + if (status == G_RESOLV_RESULT_STATUS_SUCCESS) { + if (results != NULL) { + for (i = 0; results[i]; i++) + DBG("result: %s", results[i]); + + __connman_ntp_start(results[0]); + + return; + } + } + __sync_fetch_and_add(&count, 1); + __connman_timeserver_sync_next(); +} + +void __connman_timeserver_sync_next() +{ + if (system_timeservers == NULL || + system_timeservers[count] == NULL) + return; + + DBG("Trying timeserver %s", system_timeservers[count]); + + if (resolv) + resolv_id = g_resolv_lookup_hostname(resolv, + system_timeservers[count], resolv_result, + NULL); +} + +int __connman_timeserver_sync(struct connman_service *service) +{ + char **nameservers = NULL; + int i; + + DBG("service %p", service); + + i = __connman_service_get_index(service); + if (i < 0) + return -EINVAL; + + nameservers = connman_service_get_nameservers(service); + if (nameservers == NULL) + return -EINVAL; - driver->sync(); + resolv = g_resolv_new(i); + if (resolv == NULL) + return -ENOMEM; + + if (getenv("CONNMAN_RESOLV_DEBUG")) + g_resolv_set_debug(resolv, resolv_debug, "RESOLV"); + + for (i = 0; nameservers[i] != NULL; i++) + g_resolv_add_nameserver(resolv, nameservers[i], 53, 0); + + count = 0; + + system_timeservers = load_timeservers(); + + if (system_timeservers == NULL || system_timeservers[count] == NULL) { + DBG("No timeservers set."); + return 0; } + + DBG("Trying server %s", system_timeservers[count]); + + resolv_id = g_resolv_lookup_hostname(resolv, system_timeservers[count], + resolv_result, NULL); + return 0; +} + +void __connman_timeserver_stop() +{ + DBG(" "); + + if (resolv != NULL) { + g_resolv_unref(resolv); + resolv = NULL; + } + + if (system_timeservers != NULL) { + g_strfreev(system_timeservers); + system_timeservers = NULL; + } + + count = 0; + + __connman_ntp_stop(); } int __connman_timeserver_system_append(const char *server) @@ -205,7 +325,7 @@ int __connman_timeserver_system_append(const char *server) if (server == NULL) { save_timeservers(servers); - return 0; + goto restart; } DBG("server %s", server); @@ -237,6 +357,8 @@ int __connman_timeserver_system_append(const char *server) save_timeservers(servers); g_strfreev(servers); +restart: + connman_timeserver_restart(); return 0; } @@ -291,6 +413,8 @@ int __connman_timeserver_system_remove(const char *server) save_timeservers(servers); g_strfreev(servers); + connman_timeserver_restart(); + return 0; } -- 2.7.4