diff --git a/src/net_packet.c b/src/net_packet.c index c0be8c4d..1e455434 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -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); + } } } diff --git a/src/node.h b/src/node.h index 662ad683..51938cd6 100644 --- a/src/node.h +++ b/src/node.h @@ -78,6 +78,8 @@ typedef struct node_t { uint32_t sent_seqno; /* Sequence number last sent to this node */ uint32_t received_seqno; /* Sequence number last received from this node */ uint32_t received; /* Total valid packets received from this node */ + uint32_t prev_received_seqno; + uint32_t prev_received; uint32_t farfuture; /* Packets in a row that have arrived from the far future */ unsigned char* late; /* Bitfield marking late packets */ @@ -86,6 +88,11 @@ typedef struct node_t { length_t maxmtu; /* Probed maximum MTU */ int mtuprobes; /* Number of probes */ timeout_t mtutimeout; /* Probe event */ + struct timeval probe_time; /* Time the last probe was sent or received */ + int probe_counter; /* Number of probes received since last burst was sent */ + float rtt; /* Last measured round trip time */ + float bandwidth; /* Last measured bandwidth */ + float packetloss; /* Last measured packet loss rate */ uint64_t in_packets; uint64_t in_bytes;