test median smoothing

This commit is contained in:
JerryXiao 2022-12-07 13:02:20 +08:00
parent d9763bd7a0
commit 6269f404fc
Signed by: Jerry
GPG key ID: 22618F758B5BE2E5
4 changed files with 52 additions and 15 deletions

View file

@ -1925,7 +1925,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 "&lt;text&gt;";
@ -2064,10 +2064,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.

View file

@ -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);
}
@ -1321,6 +1327,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)
{
@ -1358,12 +1379,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);

View file

@ -59,7 +59,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:
@ -164,7 +164,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 */
@ -257,6 +257,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;

View file

@ -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
;