From b2e4bc1b8ffaeacce4c85289ee864e2fd693ba1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Gallou=C3=ABt?= Date: Sat, 21 Apr 2018 12:25:52 +0000 Subject: [PATCH] Compute latency-smoothed maximum rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adrien Gallouët --- mud.c | 27 +++++++++++++++++++++++++-- mud.h | 4 ++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mud.c b/mud.c index 89d2d61..6ee3aa7 100644 --- a/mud.c +++ b/mud.c @@ -146,6 +146,7 @@ struct mud_packet { } conf; struct { unsigned char rate[MUD_U48_SIZE]; + unsigned char ratemax[MUD_U48_SIZE]; unsigned char rms[MUD_U48_SIZE]; unsigned char rmt[MUD_U48_SIZE]; } stat; @@ -1100,6 +1101,7 @@ mud_packet_send(struct mud *mud, struct mud_path *path, mud_write48(packet->data.stat.rms, path->recv_max); mud_write48(packet->data.stat.rmt, path->recv_max_time); mud_write48(packet->data.stat.rate, path->recv.rate); + mud_write48(packet->data.stat.ratemax, path->recv.ratemax); break; case mud_fake: size = path->mtu.probe - MUD_PACKET_SIZE(0); @@ -1258,6 +1260,7 @@ mud_packet_recv(struct mud *mud, struct mud_path *path, path->r_rms = mud_read48(packet->data.stat.rms); path->r_rmt = mud_read48(packet->data.stat.rmt); path->r_rate = mud_read48(packet->data.stat.rate); + path->r_ratemax = mud_read48(packet->data.stat.ratemax); if (path->mtu.ok < path->r_rms) path->mtu.ok = path->r_rms; break; @@ -1353,9 +1356,29 @@ mud_recv(struct mud *mud, void *data, size_t size) if (MUD_PACKET(send_time)) { mud_packet_recv(mud, path, now, send_time, packet, packet_size); } else if (mud_timeout(now, path->stat_time, MUD_STAT_TIMEOUT)) { - path->recv.rate = MUD_ONE_SEC * path->recv.bytes / MUD_TIME_MASK(now - path->stat_time); - mud_packet_send(mud, path, now, send_time, mud_stat); + const uint64_t rate = MUD_ONE_SEC * path->recv.bytes / MUD_TIME_MASK(now - path->stat_time); + const uint64_t lat = MUD_TIME_MASK(now - send_time + mud->time_tolerance); + + if (path->recv.ratemax < rate) + path->recv.ratemax = rate; + + if (path->latmin > lat || !path->latmin) + path->latmin = lat; + + if (path->latmax < lat) + path->latmax = lat; + + if (path->recv.ratemax > rate) { + const uint64_t range = path->latmax - path->latmin; + if (range && lat > path->latmin + (range >> 1)) + path->recv.ratemax = ((lat - path->latmin) * rate + + (path->latmax - lat) * path->recv.ratemax) / range; + } + + path->recv.rate = rate; path->recv.bytes = 0; + + mud_packet_send(mud, path, now, send_time, mud_stat); path->stat_time = now; } diff --git a/mud.h b/mud.h index 673ca28..1b55045 100644 --- a/mud.h +++ b/mud.h @@ -29,8 +29,11 @@ struct mud_path { uint64_t recv_max_time; uint64_t rtt; uint64_t rttvar; + uint64_t latmin; + uint64_t latmax; uint64_t rst; uint64_t r_rate; + uint64_t r_ratemax; uint64_t r_rst; uint64_t r_rms; uint64_t r_rmt; @@ -44,6 +47,7 @@ struct mud_path { struct { uint64_t total; uint64_t rate; + uint64_t ratemax; uint64_t bytes; uint64_t time; } send, recv;