Update rate every ms
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
70
mud.c
70
mud.c
@@ -81,7 +81,7 @@
|
|||||||
#define MUD_TIME_BITS (48)
|
#define MUD_TIME_BITS (48)
|
||||||
#define MUD_TIME_MASK(X) ((X) & ((UINT64_C(1) << MUD_TIME_BITS) - 2))
|
#define MUD_TIME_MASK(X) ((X) & ((UINT64_C(1) << MUD_TIME_BITS) - 2))
|
||||||
|
|
||||||
#define MUD_WINDOW_TIMEOUT ( 50 * MUD_ONE_MSEC)
|
#define MUD_WINDOW_TIMEOUT (MUD_ONE_MSEC)
|
||||||
#define MUD_KEYX_TIMEOUT ( 60 * MUD_ONE_MIN)
|
#define MUD_KEYX_TIMEOUT ( 60 * MUD_ONE_MIN)
|
||||||
#define MUD_KEYX_RESET_TIMEOUT (200 * MUD_ONE_MSEC)
|
#define MUD_KEYX_RESET_TIMEOUT (200 * MUD_ONE_MSEC)
|
||||||
#define MUD_TIME_TOLERANCE ( 10 * MUD_ONE_MIN)
|
#define MUD_TIME_TOLERANCE ( 10 * MUD_ONE_MIN)
|
||||||
@@ -569,7 +569,6 @@ mud_update_rate(struct mud *mud, struct mud_path *path, uint64_t rate)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
path->rate_tx = rate;
|
path->rate_tx = rate;
|
||||||
path->window_size = (rate * MUD_WINDOW_TIMEOUT) / MUD_ONE_SEC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -795,7 +794,7 @@ mud_set_state(struct mud *mud, struct sockaddr *addr,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (rate_tx)
|
if (rate_tx)
|
||||||
mud_update_rate(mud, path, rate_tx);
|
path->rate_tx = rate_tx;
|
||||||
|
|
||||||
if (rate_rx)
|
if (rate_rx)
|
||||||
path->rate_rx = rate_rx;
|
path->rate_rx = rate_rx;
|
||||||
@@ -1293,7 +1292,7 @@ mud_recv_msg(struct mud *mud, struct mud_path *path,
|
|||||||
} else {
|
} else {
|
||||||
mud_keyx_init(mud, now);
|
mud_keyx_init(mud, now);
|
||||||
path->state = (enum mud_state)msg->state;
|
path->state = (enum mud_state)msg->state;
|
||||||
mud_update_rate(mud, path, mud_read48(msg->rate));
|
path->rate_tx = mud_read48(msg->rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int rem = memcmp(msg->pub,
|
const int rem = memcmp(msg->pub,
|
||||||
@@ -1427,9 +1426,15 @@ mud_path_timeout(struct mud_path *path)
|
|||||||
return rtt > MUD_MSG_MIN_RTT ? rtt : MUD_MSG_MIN_RTT;
|
return rtt > MUD_MSG_MIN_RTT ? rtt : MUD_MSG_MIN_RTT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
mud_update(struct mud *mud, uint64_t now)
|
mud_update(struct mud *mud)
|
||||||
{
|
{
|
||||||
|
uint64_t window = 0;
|
||||||
|
size_t mtu = 0;
|
||||||
|
unsigned ret = 0;
|
||||||
|
|
||||||
|
uint64_t now = mud_now(mud);
|
||||||
|
|
||||||
if (mud->peer.set) {
|
if (mud->peer.set) {
|
||||||
mud_keyx_init(mud, now);
|
mud_keyx_init(mud, now);
|
||||||
|
|
||||||
@@ -1437,8 +1442,7 @@ mud_update(struct mud *mud, uint64_t now)
|
|||||||
mud_keyx_reset(mud);
|
mud_keyx_reset(mud);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t window = 0;
|
now = mud_now(mud);
|
||||||
size_t mtu = 0;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < mud->count; i++) {
|
for (unsigned i = 0; i < mud->count; i++) {
|
||||||
struct mud_path *path = &mud->paths[i];
|
struct mud_path *path = &mud->paths[i];
|
||||||
@@ -1479,9 +1483,13 @@ mud_update(struct mud *mud, uint64_t now)
|
|||||||
if (!mtu || mtu > path->mtu.ok) {
|
if (!mtu || mtu > path->mtu.ok) {
|
||||||
mtu = path->mtu.ok;
|
mtu = path->mtu.ok;
|
||||||
}
|
}
|
||||||
if (mud_timeout(now, path->window_time, MUD_WINDOW_TIMEOUT)) {
|
if (path->window_time + MUD_WINDOW_TIMEOUT <= now) {
|
||||||
path->window = path->window_size;
|
path->window += (path->rate_tx * (now - path->window_time))
|
||||||
|
/ MUD_ONE_SEC;
|
||||||
path->window_time = now;
|
path->window_time = now;
|
||||||
|
const uint64_t rate_tx_max = path->rate_tx >> 2; // use rtt
|
||||||
|
if (path->window > rate_tx_max)
|
||||||
|
path->window = rate_tx_max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1490,49 +1498,25 @@ mud_update(struct mud *mud, uint64_t now)
|
|||||||
mud_send_msg(mud, path, now, 0, 0, 0, path->mtu.probe);
|
mud_send_msg(mud, path, now, 0, 0, 0, path->mtu.probe);
|
||||||
}
|
}
|
||||||
|
|
||||||
window += path->window;
|
if (path->window >= 1500)
|
||||||
|
window += path->window;
|
||||||
|
|
||||||
|
ret++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mud->window = window;
|
mud->window = window;
|
||||||
mud->mtu = mtu ?: MUD_MTU_MIN;
|
mud->mtu = mtu ?: MUD_MTU_MIN;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
long
|
long
|
||||||
mud_send_wait(struct mud *mud)
|
mud_send_wait(struct mud *mud)
|
||||||
{
|
{
|
||||||
const uint64_t now = mud_now(mud);
|
if (!mud_update(mud))
|
||||||
|
return -1;
|
||||||
|
|
||||||
mud_update(mud, now);
|
return !mud->window;
|
||||||
|
|
||||||
if (mud->window)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
long dt = MUD_ONE_SEC - 1;
|
|
||||||
unsigned not_down = 0;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < mud->count; i++) {
|
|
||||||
struct mud_path *path = &mud->paths[i];
|
|
||||||
|
|
||||||
if (path->state <= MUD_DOWN)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
not_down++;
|
|
||||||
|
|
||||||
if (!path->ok)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
uint64_t elapsed = MUD_TIME_MASK(now - path->window_time);
|
|
||||||
|
|
||||||
if (elapsed >= MUD_WINDOW_TIMEOUT)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
uint64_t new_dt = MUD_WINDOW_TIMEOUT - elapsed;
|
|
||||||
|
|
||||||
if ((uint64_t)dt > new_dt)
|
|
||||||
dt = (long)new_dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return not_down ? dt : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
Reference in New Issue
Block a user