Releasing 1.1pre5.
[tinc] / src / net_packet.c
index 3c3397c..c034f85 100644 (file)
@@ -1,7 +1,7 @@
 /*
     net_packet.c -- Handles in- and outgoing VPN packets
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2013 Guus Sliepen <guus@tinc-vpn.org>
                   2010      Timothy Redaelli <timothy@redaelli.eu>
                   2010      Brandon Black <blblack@gmail.com>
 
@@ -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);
+               }
        }
 }
 
@@ -365,6 +399,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
        if(inpkt->seqno > n->received_seqno)
                n->received_seqno = inpkt->seqno;
 
+       n->received++;
+
        if(n->received_seqno > MAX_SEQNO)
                regenerate_key();