Commit dabc3f3d authored by Matthieu Boutier's avatar Matthieu Boutier Committed by Juliusz Chroboczek

Fix RTT-related overflows.

parent 44050f84
...@@ -597,8 +597,9 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -597,8 +597,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
/* We can calculate the RTT to this neighbour. */ /* We can calculate the RTT to this neighbour. */
if(have_hello_rtt && hello_send_us && hello_rtt_receive_time) { if(have_hello_rtt && hello_send_us && hello_rtt_receive_time) {
int remote_waiting_us, local_waiting_us; int remote_waiting_us, local_waiting_us;
int rtt, smoothed_rtt; unsigned int rtt, smoothed_rtt;
int old_rttcost, changed = 0; unsigned int old_rttcost;
int changed = 0;
remote_waiting_us = neigh->hello_send_us - hello_rtt_receive_time; remote_waiting_us = neigh->hello_send_us - hello_rtt_receive_time;
local_waiting_us = time_us(neigh->hello_rtt_receive_time) - local_waiting_us = time_us(neigh->hello_rtt_receive_time) -
hello_send_us; hello_send_us;
...@@ -608,14 +609,14 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -608,14 +609,14 @@ parse_packet(const unsigned char *from, struct interface *ifp,
remote_waiting_us > 600000000 || local_waiting_us > 600000000) remote_waiting_us > 600000000 || local_waiting_us > 600000000)
return; return;
rtt = local_waiting_us - remote_waiting_us; rtt = MAX(0, local_waiting_us - remote_waiting_us);
debugf("RTT to %s on %s sample result: %d us.\n", debugf("RTT to %s on %s sample result: %d us.\n",
format_address(from), ifp->name, rtt); format_address(from), ifp->name, rtt);
old_rttcost = neighbour_rttcost(neigh); old_rttcost = neighbour_rttcost(neigh);
if (valid_rtt(neigh)) { if (valid_rtt(neigh)) {
/* Running exponential average. */ /* Running exponential average. */
smoothed_rtt = (ifp->rtt_exponential_decay * MAX(rtt, 0) smoothed_rtt = (ifp->rtt_exponential_decay * rtt
+ (256 - ifp->rtt_exponential_decay) * neigh->rtt); + (256 - ifp->rtt_exponential_decay) * neigh->rtt);
/* Rounding (up or down) to get closer to the sample. */ /* Rounding (up or down) to get closer to the sample. */
neigh->rtt = (neigh->rtt >= rtt) ? smoothed_rtt / 256 : neigh->rtt = (neigh->rtt >= rtt) ? smoothed_rtt / 256 :
...@@ -623,7 +624,8 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -623,7 +624,8 @@ parse_packet(const unsigned char *from, struct interface *ifp,
} else { } else {
/* We prefer to be conservative with new neighbours /* We prefer to be conservative with new neighbours
(higher RTT) */ (higher RTT) */
neigh->rtt = MAX(2*rtt, 0); assert(rtt <= 0x7FFFFFFF);
neigh->rtt = 2*rtt;
} }
changed = (neighbour_rttcost(neigh) == old_rttcost ? 0 : 1); changed = (neighbour_rttcost(neigh) == old_rttcost ? 0 : 1);
update_neighbour_metric(neigh, changed); update_neighbour_metric(neigh, changed);
......
...@@ -25,6 +25,7 @@ THE SOFTWARE. ...@@ -25,6 +25,7 @@ THE SOFTWARE.
#include <stdio.h> #include <stdio.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <assert.h>
#include "babeld.h" #include "babeld.h"
#include "util.h" #include "util.h"
...@@ -309,8 +310,12 @@ neighbour_rttcost(struct neighbour *neigh) ...@@ -309,8 +310,12 @@ neighbour_rttcost(struct neighbour *neigh)
if(neigh->rtt <= ifp->rtt_min) { if(neigh->rtt <= ifp->rtt_min) {
return 0; return 0;
} else if(neigh->rtt <= ifp->rtt_max) { } else if(neigh->rtt <= ifp->rtt_max) {
return (ifp->max_rtt_penalty * (neigh->rtt - ifp->rtt_min) / unsigned long long tmp =
(ifp->rtt_max - ifp->rtt_min)); (unsigned long long)ifp->max_rtt_penalty *
(neigh->rtt - ifp->rtt_min) /
(ifp->rtt_max - ifp->rtt_min);
assert((tmp & 0x7FFFFFFF) == tmp);
return tmp;
} else { } else {
return ifp->max_rtt_penalty; return ifp->max_rtt_penalty;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment