diff options
Diffstat (limited to 'bgpd/bgp_fsm.c')
-rw-r--r-- | bgpd/bgp_fsm.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 9b63e9d2..03266369 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -36,6 +36,7 @@ #include "lib/qtimers.h" #include "lib/sockunion.h" +#include "lib/qrand.h" #include "bgpd/bgp_debug.h" #include "bgpd/bgp_network.h" @@ -1539,7 +1540,7 @@ bgp_fsm_event(bgp_connection connection, bgp_fsm_event_t event) */ static void -bgp_hold_timer_set(bgp_connection connection, unsigned secs) ; +bgp_hold_timer_set(bgp_connection connection, uint secs) ; /*------------------------------------------------------------------------------ * Null action -- do nothing at all. @@ -2282,27 +2283,43 @@ static qtimer_action bgp_keepalive_timer_action ; */ enum { - no_jitter = 0, - with_jitter = 1, + no_jitter = false, + with_jitter = true, } ; +static qrand_seq_t jseq = QRAND_SEQ_INIT(314159265) ; + /*------------------------------------------------------------------------------ * Start or reset given qtimer with given interval, in seconds. * * If the interval is zero, unset the timer. */ static void -bgp_timer_set(bgp_connection connection, qtimer timer, unsigned secs, - int jitter, qtimer_action* action) +bgp_timer_set(bgp_connection connection, qtimer timer, uint secs, + bool jitter, qtimer_action* action) { if (secs == 0) qtimer_unset(timer) ; else { - secs *= 40 ; /* a bit of resolution for jitter */ - if (jitter != no_jitter) - secs -= ((rand() % ((int)secs + 1)) / 4) ; - qtimer_set_interval(timer, QTIME(secs) / 40, action) ; + qtime_t interval ; + + if (jitter) + { + /* Jitter as recommended in RFC 4271, Section 10 + * + * We expect secs to be relatively small, so we can multiply it by + * some number 750..1000 without overflow ! + */ + qassert(secs <= (UINT_MAX / 1000)) ; + + secs *= 750 + qrand(jseq, 250 + 1) ; + interval = QTIME(secs) / 1000 ; + } + else + interval = QTIME(secs) ; + + qtimer_set_interval(timer, interval, action) ; } ; } ; @@ -2313,7 +2330,7 @@ bgp_timer_set(bgp_connection connection, qtimer timer, unsigned secs, * Setting 0 will unset the HoldTimer. */ static void -bgp_hold_timer_set(bgp_connection connection, unsigned secs) +bgp_hold_timer_set(bgp_connection connection, uint secs) { bgp_timer_set(connection, connection->hold_timer, secs, no_jitter, bgp_hold_timer_action) ; |