]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Replace random() with jrand48()
authorIgor Putovny <igor.putovny@nic.cz>
Tue, 3 Mar 2026 19:49:21 +0000 (20:49 +0100)
committerMaria Matejka <mq@ucw.cz>
Mon, 11 May 2026 20:15:08 +0000 (22:15 +0200)
In BIRD 3, every random() call locks. Converting these to jrand48()
with thread-local context buffers. The change starts in BIRD 2
though, to keep the code aligned better.

Edited-By: Maria Matejka <mq@jmq.cz>
Issue: #312

lib/birdlib.h
lib/timer.c
proto/babel/babel.c
proto/bfd/io.c
proto/bgp/bgp.c
proto/radv/radv.c
proto/rip/rip.c
sysdep/unix/main.c
sysdep/unix/random.c
test/birdtest.c

index 5687f10bd2f5467e9f63081ad1b6a38a2f66bd4d..6481c905be446843232d4ee3f4dfb72276423cd9 100644 (file)
@@ -215,8 +215,10 @@ asm(
 
 /* Pseudorandom numbers */
 
+long brandom(void);
 u32 random_u32(void);
 void random_init(void);
+void random_init_thread(void);
 void random_bytes(void *buf, size_t size);
 
 
index b94c43ca085ee558d579151865696595955476f3..3d4303a4976578735685807151c7ea1cb21ed295 100644 (file)
@@ -221,7 +221,7 @@ timers_fire(struct timeloop *loop)
        when = loop->last_time + t->recurrent;
 
       if (t->randomize)
-       when += random() % (t->randomize + 1);
+       when += brandom() % (t->randomize + 1);
 
       tm_set(t, when);
     }
index cc9bc7647eed114b438eb836a9cd7ceac00ea0e5..f5d3b012a13b304108069715578cf29b2b966e40 100644 (file)
@@ -1775,8 +1775,8 @@ babel_iface_start(struct babel_iface *ifa)
 
   TRACE(D_EVENTS, "Starting interface %s", ifa->ifname);
 
-  ifa->next_hello = current_time() + (random() % ifa->cf->hello_interval);
-  ifa->next_regular = current_time() + (random() % ifa->cf->update_interval);
+  ifa->next_hello = current_time() + (brandom() % ifa->cf->hello_interval);
+  ifa->next_regular = current_time() + (brandom() % ifa->cf->update_interval);
   ifa->next_triggered = current_time() + MIN(1 S, ifa->cf->update_interval / 2);
   ifa->want_triggered = 0;     /* We send an immediate update (below) */
   tm_start(ifa->timer, 100 MS);
@@ -2046,10 +2046,10 @@ babel_reconfigure_iface(struct babel_proto *p, struct babel_iface *ifa, struct b
     log(L_WARN "%s: Missing IPv4 next hop address for %s", p->p.name, ifa->ifname);
 
   if (ifa->next_hello > (current_time() + new->hello_interval))
-    ifa->next_hello = current_time() + (random() % new->hello_interval);
+    ifa->next_hello = current_time() + (brandom() % new->hello_interval);
 
   if (ifa->next_regular > (current_time() + new->update_interval))
-    ifa->next_regular = current_time() + (random() % new->update_interval);
+    ifa->next_regular = current_time() + (brandom() % new->update_interval);
 
   if (new->check_link != old->check_link)
     babel_iface_update_state(ifa);
@@ -2557,7 +2557,7 @@ static inline void
 babel_randomize_router_id(struct babel_proto *p)
 {
   p->router_id &= (u64) 0xffffffff;
-  p->router_id |= ((u64) random()) << 32;
+  p->router_id |= ((u64) brandom()) << 32;
   TRACE(D_EVENTS, "Randomized router ID to %lR", p->router_id);
 }
 
index e696cc8970a70d1985bc5d1034783f47b548b94e..a0f552a728aea9cf1a5f232f7862bab78a8621ce 100644 (file)
@@ -480,6 +480,8 @@ birdloop_main(void *arg)
   timer *t;
   int rv, timeout;
 
+  random_init_thread();
+
   birdloop_set_current(loop);
 
   tmp_init(loop->pool);
index fe243ac092b39ac455ae9ef10ab6ab318900de5b..20267208ff78453034d40d93625e810ed3f88427 100644 (file)
@@ -931,7 +931,7 @@ bgp_start_timer(timer *t, uint value)
   {
     /* The randomization procedure is specified in RFC 4271 section 10 */
     btime time = value S;
-    btime randomize = random() % ((time / 4) + 1);
+    btime randomize = brandom() % ((time / 4) + 1);
     tm_start(t, time - randomize);
   }
   else
index 9a0434a15b10111165a6b98cacabc4eaa97906f6..7c2e89535047aa3e27ea4f3b65f56835080b5d9c 100644 (file)
@@ -67,7 +67,7 @@ radv_timer(timer *tm)
   ifa->last = now;
   btime t = ifa->cf->min_ra_int S;
   btime r = (ifa->cf->max_ra_int - ifa->cf->min_ra_int) S;
-  t += random() % (r + 1);
+  t += brandom() % (r + 1);
 
   if (ifa->initial)
   {
index b70b6e8ec9c80c6997c1a047a57bff38bccab953..1213a71624d14da25a33caaa1765cfc6fa15f9cb 100644 (file)
@@ -557,7 +557,7 @@ rip_iface_start(struct rip_iface *ifa)
 
   if (! ifa->cf->demand_circuit)
   {
-    ifa->next_regular = current_time() + (random() % ifa->cf->update_time) + 100 MS;
+    ifa->next_regular = current_time() + (brandom() % ifa->cf->update_time) + 100 MS;
     tm_set(ifa->timer, ifa->next_regular);
   }
   else
@@ -766,7 +766,7 @@ rip_reconfigure_iface(struct rip_proto *p, struct rip_iface *ifa, struct rip_ifa
 
   if ((! ifa->cf->demand_circuit) &&
       (ifa->next_regular > (current_time() + new->update_time)))
-    ifa->next_regular = current_time() + (random() % new->update_time) + 100 MS;
+    ifa->next_regular = current_time() + (brandom() % new->update_time) + 100 MS;
 
   if (ifa->up && new->demand_circuit && (new->passive != old->passive))
   {
index deb108c30370b4fe282f9e07c0333e497a971690..53fb3a38c7725a4d6d759b6258bc491ab79e07b5 100644 (file)
@@ -1022,6 +1022,7 @@ main(int argc, char **argv)
   log_switch(1, NULL, NULL);
 
   random_init();
+  random_init_thread();
   resource_init();
   timer_init();
   olock_init();
index 4e64e56b8a9c0a2468196ca709cc073d1e6ef3af..d0f2d49c72fe0bb2a4e476c5350ffd959f7e58de 100644 (file)
 #include <sys/random.h>
 #endif
 
+_Thread_local unsigned short random_state[3];
+
+long
+brandom(void)
+{
+  return jrand48(random_state);
+}
 
 u32
 random_u32(void)
 {
   long int rand_low, rand_high;
 
-  rand_low = random();
-  rand_high = random();
+  rand_low = brandom();
+  rand_high = brandom();
   return (rand_low & 0xffff) | ((rand_high & 0xffff) << 16);
 }
 
@@ -56,12 +63,14 @@ read_urandom_fd(void *buf, uint count)
 void
 random_init(void)
 {
-  uint seed;
-
-  /* Get random bytes to trip any errors early and to seed random() */
-  random_bytes(&seed, sizeof(seed));
+  /* No global init needed */
+}
 
-  srandom(seed);
+void
+random_init_thread(void)
+{
+  /* Initialize thread-local random structure */
+  random_bytes(random_state, sizeof random_state);
 }
 
 void
index 24c3fae4cd098a213c5b77b0bcd12a1bdcddf545..fb268be12286574ed91a8cb44de771849ea6d725 100644 (file)
@@ -127,6 +127,9 @@ bt_init(int argc, char *argv[])
   log_init_debug("");
   log_switch(1, NULL, NULL);
 
+  random_init();
+  random_init_thread();
+
   resource_init();
   ev_init_list(&global_event_list);