summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrik Flykt <patrik.flykt@linux.intel.com>2013-05-21 10:32:14 (GMT)
committerPatrik Flykt <patrik.flykt@linux.intel.com>2013-05-31 08:06:34 (GMT)
commit3b70a3d5a93fb229c2caacf6b2df43dd9ea5b6bd (patch)
treeb74993ade65f8edb971fa923dd532f291ada02a8
parentbac356ff03abd450b471ae19036d5069171007c2 (diff)
downloadconnman-3b70a3d5a93fb229c2caacf6b2df43dd9ea5b6bd.zip
connman-3b70a3d5a93fb229c2caacf6b2df43dd9ea5b6bd.tar.gz
connman-3b70a3d5a93fb229c2caacf6b2df43dd9ea5b6bd.tar.bz2
timeserver: Periodically wake up to recheck timeservers
The current situation is that a failed timeserver name resolution removes the timeserver immediately from the list of used timeservers and failing to connect to the nameserver IP address removes the timeserver after a 2 second delay. Currently no mechanism exists to re-create the list of nameservers once the list has been exhausted or the more preferred timeservers have been removed from it. This implementation combats both problems where less used timeservers further away end up being used despite a more optimal closer one becoming available as well as the problem of exhausting the nameserver list. This is done by periodially waking up and checking the timeserver in use. If the timeserver in use is not the most preferred one or the list of timeservers is empty, the timeserver list is recreated and the timeserver polling procedure is restarted.
-rw-r--r--src/timeserver.c82
1 files changed, 72 insertions, 10 deletions
diff --git a/src/timeserver.c b/src/timeserver.c
index 970b8eb..f3c1220 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -32,7 +32,11 @@
#include "connman.h"
+#define TS_RECHECK_INTERVAL 7200
+
static GSList *ts_list = NULL;
+static char *ts_current = NULL;
+static int ts_recheck_id = 0;
static GResolv *resolv = NULL;
static int resolv_id = 0;
@@ -117,7 +121,10 @@ static void resolv_result(GResolvResultStatus status, char **results, gpointer u
*/
void __connman_timeserver_sync_next()
{
- char *server;
+ if (ts_current != NULL) {
+ g_free(ts_current);
+ ts_current = NULL;
+ }
__connman_ntp_stop();
@@ -125,27 +132,24 @@ void __connman_timeserver_sync_next()
if (ts_list == NULL)
return;
- server = ts_list->data;
+ ts_current = ts_list->data;
ts_list = g_slist_delete_link(ts_list, ts_list);
/* if its a IP , directly query it. */
- if (connman_inet_check_ipaddress(server) > 0) {
- DBG("Using timeserver %s", server);
+ if (connman_inet_check_ipaddress(ts_current) > 0) {
+ DBG("Using timeserver %s", ts_current);
- __connman_ntp_start(server);
+ __connman_ntp_start(ts_current);
- g_free(server);
return;
}
- DBG("Resolving server %s", server);
+ DBG("Resolving server %s", ts_current);
- resolv_id = g_resolv_lookup_hostname(resolv, server,
+ resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
resolv_result, NULL);
- g_free(server);
-
return;
}
@@ -227,6 +231,58 @@ GSList *__connman_timeserver_get_all(struct connman_service *service)
return g_slist_reverse(list);
}
+static gboolean ts_recheck(void *user_data)
+{
+ GSList *ts;
+
+ ts = __connman_timeserver_get_all(__connman_service_get_default());
+
+ if (ts == NULL) {
+ DBG("timeservers disabled");
+
+ return TRUE;
+ }
+
+ if (g_strcmp0(ts_current, ts->data) != 0) {
+ DBG("current %s preferred %s", ts_current, (char *)ts->data);
+
+ g_slist_free_full(ts, g_free);
+
+ __connman_timeserver_sync(NULL);
+
+ return FALSE;
+ }
+
+ DBG("");
+
+ g_slist_free_full(ts, g_free);
+
+ return TRUE;
+}
+
+static void ts_recheck_disable(void)
+{
+ if (ts_recheck_id == 0)
+ return;
+
+ g_source_remove(ts_recheck_id);
+ ts_recheck_id = 0;
+
+ if (ts_current != NULL) {
+ g_free(ts_current);
+ ts_current = NULL;
+ }
+}
+
+static void ts_recheck_enable(void)
+{
+ if (ts_recheck_id > 0)
+ return;
+
+ ts_recheck_id = g_timeout_add_seconds(TS_RECHECK_INTERVAL, ts_recheck,
+ NULL);
+}
+
/*
* This function must be called everytime the default service changes, the
* service timeserver(s) or gatway changes or the global timeserver(s) changes.
@@ -252,6 +308,8 @@ int __connman_timeserver_sync(struct connman_service *default_service)
__connman_ntp_stop();
+ ts_recheck_disable();
+
if (resolv_id > 0)
g_resolv_cancel_lookup(resolv, resolv_id);
@@ -266,6 +324,8 @@ int __connman_timeserver_sync(struct connman_service *default_service)
return 0;
}
+ ts_recheck_enable();
+
__connman_timeserver_sync_next();
return 0;
@@ -327,6 +387,8 @@ static void timeserver_stop()
ts_list = NULL;
__connman_ntp_stop();
+
+ ts_recheck_disable();
}
int __connman_timeserver_system_set(char **servers)