From 0f0585d71b28428792e53258bc570dddc17b0b27 Mon Sep 17 00:00:00 2001 From: volth Date: Tue, 12 Jun 2018 21:17:30 +0000 Subject: [PATCH] keep track of round trip times of UDP pings --- src/info.c | 7 +++++-- src/net_packet.c | 18 ++++++++++++++---- src/node.c | 5 +++-- src/node.h | 1 + src/tincctl.c | 10 +++++++--- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/info.c b/src/info.c index 09e65805..652c4aeb 100644 --- a/src/info.c +++ b/src/info.c @@ -70,15 +70,16 @@ static int info_node(int fd, const char *item) { } status_union; node_status_t status; long int last_state_change; + long int udp_ping_rtt; while(recvline(fd, line, sizeof(line))) { - int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt); if(n == 2) { break; } - if(n != 19) { + if(n != 20) { fprintf(stderr, "Unable to parse node dump from tincd.\n"); return 1; } @@ -143,6 +144,8 @@ static int info_node(int fd, const char *item) { if(status.udp_confirmed) { printf(" udp_confirmed"); + if(udp_ping_rtt != -1) + printf(" (rtt %ld.%03ld)", udp_ping_rtt/1000, udp_ping_rtt%1000); } printf("\n"); diff --git a/src/net_packet.c b/src/net_packet.c index 8ade0576..6ce6431d 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -102,6 +102,7 @@ static void udp_probe_timeout_handler(void *data) { logger(DEBUG_TRAFFIC, LOG_INFO, "Too much time has elapsed since last UDP ping response from %s (%s), stopping UDP communication", n->name, n->hostname); n->status.udp_confirmed = false; + n->udp_ping_rtt = -1; n->maxrecentlen = 0; n->mtuprobes = 0; n->minmtu = 0; @@ -151,7 +152,15 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { len = ntohs(len16); } - logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); + if (n->udp_ping_sent.tv_sec != 0) { // a probe in flight + gettimeofday(&now, NULL); + struct timeval rtt; + timersub(&now, &n->udp_ping_sent, &rtt); + n->udp_ping_rtt = rtt.tv_sec*1000000L + rtt.tv_usec; + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s) rtt=%ld.%03ld", DATA(packet)[0], len, n->name, n->hostname, n->udp_ping_rtt/1000, n->udp_ping_rtt%1000); + } else { + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); + } /* It's a valid reply: now we know bidirectional communication is possible using the address and socket that the reply @@ -167,8 +176,8 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { reset_address_cache(n->address_cache, &n->address); } - // Reset the UDP ping timer. - n->udp_ping_sent = now; + // Reset the UDP ping timer. (no probe in flight) + n->udp_ping_sent.tv_sec = 0; if(udp_discovery) { timeout_del(&n->udp_ping_timeout); @@ -1119,8 +1128,9 @@ static void try_udp(node_t *n) { int interval = n->status.udp_confirmed ? udp_discovery_keepalive_interval : udp_discovery_interval; if(ping_tx_elapsed.tv_sec >= interval) { + gettimeofday(&now, NULL); + n->udp_ping_sent = now; // a probe in flight send_udp_probe_packet(n, MIN_PROBE_SIZE); - n->udp_ping_sent = now; if(localdiscovery && !n->status.udp_confirmed && n->prevedge) { n->status.send_locally = true; diff --git a/src/node.c b/src/node.c index bea23c7b..c3f2ab55 100644 --- a/src/node.c +++ b/src/node.c @@ -80,6 +80,7 @@ node_t *new_node(void) { n->edge_tree = new_edge_tree(); n->mtu = MTU; n->maxmtu = MTU; + n->udp_ping_rtt = -1; return n; } @@ -211,7 +212,7 @@ bool dump_nodes(connection_t *c) { } id[sizeof(id) - 1] = 0; - send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld", CONTROL, REQ_DUMP_NODES, + send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld %ld", CONTROL, REQ_DUMP_NODES, n->name, id, n->hostname ? : "unknown port unknown", #ifdef DISABLE_LEGACY 0, 0, 0, @@ -220,7 +221,7 @@ bool dump_nodes(connection_t *c) { #endif n->outcompression, n->options, bitfield_to_int(&n->status, sizeof(n->status)), n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ? : "-" : "-", n->distance, - n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); + n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change, (long)n->udp_ping_rtt); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); diff --git a/src/node.h b/src/node.h index 496880f4..0cdac3fa 100644 --- a/src/node.h +++ b/src/node.h @@ -92,6 +92,7 @@ typedef struct node_t { struct timeval udp_reply_sent; /* Last time a (gratuitous) UDP probe reply was sent */ struct timeval udp_ping_sent; /* Last time a UDP probe was sent */ + long int udp_ping_rtt; /* Round trip time of UDP ping (in microseconds) */ timeout_t udp_ping_timeout; /* Ping timeout event */ struct timeval mtu_ping_sent; /* Last time a MTU probe was sent */ diff --git a/src/tincctl.c b/src/tincctl.c index cf19d481..76ff3740 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1298,12 +1298,13 @@ static int cmd_dump(int argc, char *argv[]) { unsigned int options, status_int; node_status_t status; long int last_state_change; + long int udp_ping_rtt; switch(req) { case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt); - if(n != 17) { + if(n != 18) { fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); return 1; } @@ -1331,8 +1332,11 @@ static int cmd_dump(int argc, char *argv[]) { continue; } - printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n", + printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)", node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); + if (udp_ping_rtt != -1) + printf(" rtt %ld.%03ld", udp_ping_rtt/1000, udp_ping_rtt%1000); + printf("\n"); } } break; -- 2.20.1