summaryrefslogtreecommitdiff
path: root/src/timeserver.c
diff options
context:
space:
mode:
authorAlok Barsode <alok.barsode@linux.intel.com>2012-02-03 20:26:00 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2012-02-04 01:15:36 +0100
commit8f3c51386929c432af4d78c1e8ab1d82a1f6ac8b (patch)
tree5c4f10d0a52f75cb8ddf2da311b29a6460accabd /src/timeserver.c
parent1db29a8c79e10f801d8d9ce0c861bf8b0a972f4d (diff)
downloadconnman-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.c142
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;
}