Estimate RTT, bandwidth and packet loss between nodes.
Without adding any extra traffic, we can measure round trip times, estimate the bandwidth and packet loss between nodes. The RTT and bandwidth can be measured by timing the MTU probe packets. The RTT is the difference between the time a burst of MTU probes was sent and when the first reply is received. The bandwidth can be estimated by multiplying the size of the probe packets by the time between succesive received probe replies of the same burst. The packet loss can be estimated for incoming traffic by comparing how many packets have actually been received to the increase in the sequence numbers. The estimates are not perfect. Especially bandwidth is difficult to measure, the only accurate way is to continuously send as much data as possible, but that is obviously not desirable. The packet loss rate is also almost always a few percent when sending a lot of data over the VPN via TCP, since TCP *needs* packet loss to work properly.
This commit is contained in:
parent
eef25266cb
commit
61275547cd
2 changed files with 41 additions and 0 deletions
|
|
@ -150,6 +150,21 @@ static void send_mtu_probe_handler(void *data) {
|
|||
send_udppacket(n, &packet);
|
||||
}
|
||||
|
||||
n->probe_counter = 0;
|
||||
gettimeofday(&n->probe_time, NULL);
|
||||
|
||||
/* Calculate the packet loss of incoming traffic by comparing the rate of
|
||||
packets received to the rate with which the sequence number has increased.
|
||||
*/
|
||||
|
||||
if(n->received > n->prev_received)
|
||||
n->packetloss = 1.0 - (n->received - n->prev_received) / (float)(n->received_seqno - n->prev_received_seqno);
|
||||
else
|
||||
n->packetloss = n->received_seqno <= n->prev_received_seqno;
|
||||
|
||||
n->prev_received_seqno = n->received_seqno;
|
||||
n->prev_received = n->received;
|
||||
|
||||
end:
|
||||
timeout_set(&n->mtutimeout, &(struct timeval){timeout, rand() % 100000});
|
||||
}
|
||||
|
|
@ -196,6 +211,25 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
|
|||
len = n->maxmtu;
|
||||
if(n->minmtu < len)
|
||||
n->minmtu = len;
|
||||
|
||||
/* Calculate RTT and bandwidth.
|
||||
The RTT is the time between the MTU probe burst was sent and the first
|
||||
reply is received. The bandwidth is measured using the time between the
|
||||
arrival of the first and third probe reply.
|
||||
*/
|
||||
|
||||
struct timeval now, diff;
|
||||
gettimeofday(&now, NULL);
|
||||
timersub(&now, &n->probe_time, &diff);
|
||||
n->probe_counter++;
|
||||
|
||||
if(n->probe_counter == 1) {
|
||||
n->rtt = diff.tv_sec + diff.tv_usec * 1e-6;
|
||||
n->probe_time = now;
|
||||
} else if(n->probe_counter == 3) {
|
||||
n->bandwidth = 2.0 * len / (diff.tv_sec + diff.tv_usec * 1e-6);
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "%s (%s) RTT %.2f ms, burst bandwidth %.3f Mbit/s, rx packet loss %.2f %%", n->name, n->hostname, n->rtt * 1e3, n->bandwidth * 8e-6, n->packetloss * 1e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue