chiark / gitweb /
timesyncd: keep order of NTP servers
[elogind.git] / src / timesync / timesyncd.c
index bbffbbd863952c71684d13d4a251bedd9b435591..1c0f113778ecf6982e356f4e1db2064bc74cae4b 100644 (file)
@@ -32,6 +32,7 @@
 #include <sys/timerfd.h>
 #include <sys/timex.h>
 #include <sys/socket.h>
+#include <resolv.h>
 
 #include "missing.h"
 #include "util.h"
@@ -40,6 +41,7 @@
 #include "socket-util.h"
 #include "list.h"
 #include "ratelimit.h"
+#include "strv.h"
 #include "sd-event.h"
 #include "sd-resolve.h"
 #include "sd-daemon.h"
@@ -86,7 +88,7 @@
 
 #define RETRY_USEC (30*USEC_PER_SEC)
 #define RATELIMIT_INTERVAL_USEC (10*USEC_PER_SEC)
-#define RATELIMIT_BURST 5
+#define RATELIMIT_BURST 10
 
 struct ntp_ts {
         be32_t sec;
@@ -245,8 +247,10 @@ static int manager_send_request(Manager *m) {
         if (len == sizeof(ntpmsg)) {
                 m->pending = true;
                 log_debug("Sent NTP request to %s (%s)", pretty, m->current_server_name->string);
-        } else
+        } else {
                 log_debug("Sending NTP request to %s (%s) failed: %m", pretty, m->current_server_name->string);
+                return manager_connect(m);
+        }
 
         /* re-arm timer with incresing timeout, in case the packets never arrive back */
         if (m->retry_interval > 0) {
@@ -611,7 +615,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
                 return manager_connect(m);
         }
 
-        if (NTP_FIELD_VERSION(ntpmsg.field) != 4) {
+        if (NTP_FIELD_VERSION(ntpmsg.field) != 4 && NTP_FIELD_VERSION(ntpmsg.field) != 3) {
                 log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
                 return manager_connect(m);
         }
@@ -910,6 +914,10 @@ static int manager_connect(Manager *m) {
                         m->current_server_name = m->servers;
                 }
 
+                /* Tell the resolver to reread /etc/resolv.conf, in
+                 * case it changed. */
+                res_init();
+
                 r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m);
                 if (r < 0) {
                         log_error("Failed to create resolver: %s", strerror(-r));
@@ -927,7 +935,7 @@ static int manager_connect(Manager *m) {
 }
 
 static int manager_add_server(Manager *m, const char *server) {
-        ServerName *n;
+        ServerName *n, *tail;
 
         assert(m);
         assert(server);
@@ -942,7 +950,12 @@ static int manager_add_server(Manager *m, const char *server) {
                 return -ENOMEM;
         }
 
-        LIST_PREPEND(names, m->servers, n);
+        if (m->servers) {
+                LIST_FIND_TAIL(names, m->servers, tail);
+                LIST_INSERT_AFTER(names, m->servers, tail, n);
+        } else
+                LIST_PREPEND(names, m->servers, n);
+
         return 0;
 }
 
@@ -1017,6 +1030,7 @@ static void manager_free(Manager *m) {
 
 int main(int argc, char *argv[]) {
         _cleanup_manager_free_ Manager *m = NULL;
+        const char *x;
         int r;
 
         log_set_target(LOG_TARGET_AUTO);
@@ -1033,10 +1047,12 @@ int main(int argc, char *argv[]) {
 
         sd_notify(false, "READY=1");
 
-        r = manager_add_server(m, "time1.google.com");
-        if (r < 0) {
-                log_error("Failed to add server: %s", strerror(-r));
-                goto out;
+        FOREACH_STRING(x, "time1.google.com", "time2.google.com", "time3.google.com", "time4.google.com", "0.fedora.pool.ntp.org") {
+                r = manager_add_server(m, x);
+                if (r < 0) {
+                        log_error("Failed to add server %s: %s", x, strerror(-r));
+                        goto out;
+                }
         }
 
         r = manager_connect(m);