test median smoothing
This commit is contained in:
parent
7c7d6e576f
commit
d6dd113a96
4 changed files with 52 additions and 15 deletions
|
@ -1898,7 +1898,7 @@ protocol babel [<name>] {
|
|||
rtt cost <number>;
|
||||
rtt min <time>;
|
||||
rtt max <time>;
|
||||
rtt decay <number>;
|
||||
rtt winlen <number>;
|
||||
send timestamps <switch>;
|
||||
authentication none|mac [permissive];
|
||||
password "<text>";
|
||||
|
@ -2037,10 +2037,10 @@ protocol babel [<name>] {
|
|||
The maximum RTT above which the full RTT cost will start be applied.
|
||||
Default: 120 ms
|
||||
|
||||
<tag><label id="babel-rtt-decay">rtt decay <m/number/</tag>
|
||||
The decay factor used for the exponentional moving average of the RTT
|
||||
samples from each neighbour, in units of 1/256. Higher values discards old
|
||||
RTT samples faster. Must be between 1 and 256. Default: 42
|
||||
<tag><label id="babel-rtt-winlen">rtt winlen <m/number/</tag>
|
||||
The window length user to calculate median of the RTT
|
||||
samples from each neighbour, Lower values discards old
|
||||
RTT samples faster. Must be between 1 and 65535. Default: 100
|
||||
|
||||
<tag><label id="babel-send-timestamps">send timestamps <m/switch/</tag>
|
||||
Whether to send the timestamps used for RTT calculation on this interface.
|
||||
|
|
|
@ -536,6 +536,10 @@ babel_get_neighbor(struct babel_iface *ifa, ip_addr addr)
|
|||
init_list(&nbr->requests);
|
||||
add_tail(&ifa->neigh_list, NODE nbr);
|
||||
|
||||
nbr->srtt_pool = mb_allocz(ifa->pool, ifa->cf->rtt_win_len*sizeof(btime));
|
||||
nbr->srtt_pool_sorted = mb_allocz(ifa->pool, ifa->cf->rtt_win_len*sizeof(btime));
|
||||
nbr->srtt_poll_idx = nbr->srtt_pool_len = 0;
|
||||
|
||||
return nbr;
|
||||
}
|
||||
|
||||
|
@ -560,6 +564,8 @@ babel_flush_neighbor(struct babel_proto *p, struct babel_neighbor *nbr)
|
|||
|
||||
nbr->ifa = NULL;
|
||||
rem_node(NODE nbr);
|
||||
mb_free(nbr->srtt_pool);
|
||||
mb_free(nbr->srtt_pool_sorted);
|
||||
mb_free(nbr);
|
||||
}
|
||||
|
||||
|
@ -1304,6 +1310,21 @@ babel_handle_hello(union babel_msg *m, struct babel_iface *ifa)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
babel_btime_cmp(const void *b1, const void *b2)
|
||||
{
|
||||
btime r;
|
||||
switch (r = *(btime*)b1 - *(btime*)b2)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return r > (btime)0 ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
babel_handle_ihu(union babel_msg *m, struct babel_iface *ifa)
|
||||
{
|
||||
|
@ -1341,12 +1362,24 @@ babel_handle_ihu(union babel_msg *m, struct babel_iface *ifa)
|
|||
|
||||
if (n->srtt)
|
||||
{
|
||||
uint decay = n->ifa->cf->rtt_decay;
|
||||
|
||||
n->srtt = (decay * rtt_sample + (256 - decay) * n->srtt) / 256;
|
||||
}
|
||||
u16 pool_idx = n->srtt_poll_idx % n->ifa->cf->rtt_win_len;
|
||||
n->srtt_poll_idx = pool_idx + 1;
|
||||
*(n->srtt_pool + pool_idx) = rtt_sample;
|
||||
if (n->srtt_pool_len < n->ifa->cf->rtt_win_len)
|
||||
n->srtt_pool_len++;
|
||||
memcpy(n->srtt_pool_sorted, n->srtt_pool, (size_t)n->srtt_pool_len*sizeof(btime));
|
||||
// use qsort for now for testing
|
||||
qsort(n->srtt_pool_sorted, (size_t)n->srtt_pool_len, sizeof(btime), babel_btime_cmp);
|
||||
int mid = n->srtt_pool_len / (u16)2;
|
||||
if (!n->srtt_pool_len || n->srtt_pool_len % (u16)2)
|
||||
n->srtt = *(n->srtt_pool_sorted + mid);
|
||||
else
|
||||
n->srtt = rtt_sample;
|
||||
n->srtt = (*(n->srtt_pool_sorted + mid - (u16)1) + *(n->srtt_pool_sorted + mid)) / (u16)2;
|
||||
}
|
||||
else {
|
||||
*(n->srtt_pool) = n->srtt = rtt_sample;
|
||||
n->srtt_poll_idx = n->srtt_pool_len = 1;
|
||||
}
|
||||
|
||||
TRACE(D_EVENTS, "RTT sample for neighbour %I on %s: %u us (srtt %u.%03u ms)",
|
||||
n->addr, ifa->ifname, rtt_sample, n->srtt/1000, n->srtt%1000);
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#define BABEL_RTT_MAX_VALUE (600 S_)
|
||||
#define BABEL_RTT_MIN (10 MS_)
|
||||
#define BABEL_RTT_MAX (120 MS_)
|
||||
#define BABEL_RTT_DECAY 42
|
||||
#define BABEL_RTT_WINLEN 100
|
||||
|
||||
/*
|
||||
* Constants for calculating metric smoothing. Chosen so that:
|
||||
|
@ -163,7 +163,7 @@ struct babel_iface_config {
|
|||
btime rtt_min; /* rtt above which to start penalising metric */
|
||||
btime rtt_max; /* max rtt metric penalty applied above this */
|
||||
u16 rtt_cost; /* metric penalty to apply at rtt_max */
|
||||
u16 rtt_decay; /* decay of neighbour RTT (units of 1/256) */
|
||||
u16 rtt_win_len; /* smoothing windows length */
|
||||
u8 rtt_send; /* whether to send timestamps on this interface */
|
||||
|
||||
u16 rx_buffer; /* RX buffer size, 0 for MTU */
|
||||
|
@ -256,6 +256,10 @@ struct babel_neighbor {
|
|||
u32 last_tstamp;
|
||||
btime last_tstamp_rcvd;
|
||||
btime srtt;
|
||||
btime *srtt_pool; // an array of btime
|
||||
btime *srtt_pool_sorted;
|
||||
u16 srtt_pool_len; // initial length
|
||||
u16 srtt_poll_idx; // head
|
||||
|
||||
u32 auth_pc;
|
||||
u8 auth_passed;
|
||||
|
|
|
@ -26,7 +26,7 @@ CF_KEYWORDS(BABEL, INTERFACE, METRIC, RXCOST, HELLO, UPDATE, INTERVAL, PORT,
|
|||
TYPE, WIRED, WIRELESS, TUNNEL, RX, TX, BUFFER, PRIORITY, LENGTH, CHECK,
|
||||
LINK, NEXT, HOP, IPV4, IPV6, BABEL_METRIC, SHOW, INTERFACES, NEIGHBORS,
|
||||
ENTRIES, RANDOMIZE, ROUTER, ID, AUTHENTICATION, NONE, MAC, PERMISSIVE,
|
||||
RTT, MIN, MAX, DECAY, SEND, TIMESTAMPS)
|
||||
RTT, MIN, MAX, DECAY, WINLEN, SEND, TIMESTAMPS)
|
||||
|
||||
CF_GRAMMAR
|
||||
|
||||
|
@ -77,7 +77,7 @@ babel_iface_start:
|
|||
BABEL_IFACE->tx_priority = sk_priority_control;
|
||||
BABEL_IFACE->rtt_min = BABEL_RTT_MIN;
|
||||
BABEL_IFACE->rtt_max = BABEL_RTT_MAX;
|
||||
BABEL_IFACE->rtt_decay = BABEL_RTT_DECAY;
|
||||
BABEL_IFACE->rtt_win_len = BABEL_RTT_WINLEN;
|
||||
BABEL_IFACE->rtt_send = 1;
|
||||
BABEL_IFACE->check_link = 1;
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ babel_iface_item:
|
|||
| RTT MIN expr_us { BABEL_IFACE->rtt_min = $3; }
|
||||
| RTT MAX expr_us { BABEL_IFACE->rtt_max = $3; }
|
||||
| RTT COST expr { BABEL_IFACE->rtt_cost = $3; if ($3 >= BABEL_INFINITY) cf_error("RTT cost must be < 65535"); }
|
||||
| RTT DECAY expr { BABEL_IFACE->rtt_decay = $3; if (($3 < 1) || ($3 > 256)) cf_error("RTT decay must be between 1-256"); }
|
||||
| RTT WINLEN expr { BABEL_IFACE->rtt_win_len = $3; if (($3 < 1) || ($3 > 65535)) cf_error("RTT winlen must be between 1-65535"); }
|
||||
| SEND TIMESTAMPS bool { BABEL_IFACE->rtt_send = $3; }
|
||||
| password_list
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue