chiark / gitweb /
resolved: when picking a new hostname make sure two hosts pick different ones
authorLennart Poettering <lennart@poettering.net>
Sun, 10 Aug 2014 21:10:08 +0000 (23:10 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 11 Aug 2014 13:06:22 +0000 (15:06 +0200)
This way we can avoid always picking the same replacement hostnames when
picking one.

src/resolve/resolved-manager.c

index 1d33c2ae19cc473bcd112237c1a263433e161190..988aa6e3b1a2fec802c848fddb84bef0345c9d9c 100644 (file)
@@ -1646,7 +1646,7 @@ void manager_refresh_rrs(Manager *m) {
 
 int manager_next_hostname(Manager *m) {
         const char *p;
 
 int manager_next_hostname(Manager *m) {
         const char *p;
-        uint64_t u;
+        uint64_t u, a;
         char *h;
 
         assert(m);
         char *h;
 
         assert(m);
@@ -1664,7 +1664,15 @@ int manager_next_hostname(Manager *m) {
         if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
                 u = 1;
 
         if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
                 u = 1;
 
-        u++;
+        /* Add a random number to the old value. This way we can avoid
+         * that two hosts pick the same hostname, win on IPv4 and lose
+         * on IPv6 (or vice versa), and pick the same hostname
+         * replacement hostname, ad infinitum. We still want the
+         * numbers to go up monotonically, hence we just add a random
+         * value 1..10 */
+
+        random_bytes(&a, sizeof(a));
+        u += 1 + a % 10;
 
         if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
                 return -ENOMEM;
 
         if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
                 return -ENOMEM;