diff options
author | Alok Barsode <alok.barsode@linux.intel.com> | 2012-02-03 20:26:00 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-02-04 01:15:36 +0100 |
commit | 8f3c51386929c432af4d78c1e8ab1d82a1f6ac8b (patch) | |
tree | 5c4f10d0a52f75cb8ddf2da311b29a6460accabd /src/timeserver.c | |
parent | 1db29a8c79e10f801d8d9ce0c861bf8b0a972f4d (diff) | |
download | connman-8f3c51386929c432af4d78c1e8ab1d82a1f6ac8b.tar.gz connman-8f3c51386929c432af4d78c1e8ab1d82a1f6ac8b.tar.bz2 connman-8f3c51386929c432af4d78c1e8ab1d82a1f6ac8b.zip |
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.
Diffstat (limited to 'src/timeserver.c')
-rw-r--r-- | src/timeserver.c | 142 |
1 files changed, 133 insertions, 9 deletions
diff --git a/src/timeserver.c b/src/timeserver.c index 3bdc74fd..2af173d8 100644 --- a/src/timeserver.c +++ b/src/timeserver.c @@ -26,12 +26,24 @@ #include <errno.h> #include <glib.h> +#include <stdlib.h> +#include <gweb/gresolv.h> #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; } |