From 9ade39b7d5564fb6f5a41946c9a23cfa7851a19f Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 26 Sep 2012 22:20:43 +0200 Subject: [PATCH] Keep last known address and time since reachability changed. This allows tincctl info to show since when a node is online or offline. --- src/graph.c | 4 +++- src/info.c | 22 +++++++++++++++++----- src/net_packet.c | 2 +- src/net_setup.c | 1 + src/node.c | 12 +++--------- src/node.h | 1 + 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/graph.c b/src/graph.c index 9da552e7..98eb469b 100644 --- a/src/graph.c +++ b/src/graph.c @@ -188,7 +188,8 @@ static void sssp_bfs(void) { e->to->options = e->options; e->to->distance = n->distance + 1; - if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) + if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) +) update_node_udp(e->to, &e->address); list_insert_tail(todo_list, e->to); @@ -217,6 +218,7 @@ static void check_reachability(void) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; + n->last_state_change = time(NULL); if(n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", diff --git a/src/info.c b/src/info.c index 18b8e24a..ee60a3fe 100644 --- a/src/info.c +++ b/src/info.c @@ -59,18 +59,19 @@ static int info_node(int fd, const char *item) { short int pmtu, minmtu, maxmtu; unsigned int options; node_status_t status; + long int last_state_change; while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)", &code, &req, node, host, port, &cipher, &digest, &maclength, &compression, &options, (unsigned *)&status, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu); + int n = sscanf(line, "%d %d %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd) %ld", &code, &req, node, host, port, &cipher, &digest, &maclength, &compression, &options, (unsigned *)&status, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); if(n == 2) break; - if(n != 17) { + if(n != 18) { *port = 0; - n = sscanf(line, "%d %d %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)", &code, &req, node, host, &cipher, &digest, &maclength, &compression, &options, (unsigned *)&status, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu); + n = sscanf(line, "%d %d %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd) %ld", &code, &req, node, host, &cipher, &digest, &maclength, &compression, &options, (unsigned *)&status, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); - if(n != 16) { + if(n != 17) { fprintf(stderr, "Unable to parse node dump from tincd.\n"); return 1; } @@ -95,6 +96,16 @@ static int info_node(int fd, const char *item) { printf("Node: %s\n", item); if(*port) printf("Address: %s port %s\n", host, port); + + char timestr[32] = "never"; + if(last_state_change) + strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&last_state_change)); + + if(status.reachable) + printf("Online since: %s\n", timestr); + else + printf("Last seen: %s\n", timestr); + printf("Status: "); if(status.validkey) printf(" validkey"); @@ -107,6 +118,7 @@ static int info_node(int fd, const char *item) { if(status.sptps) printf(" sptps"); printf("\n"); + printf("Options: "); if(options & OPTION_INDIRECT) printf(" indirect"); @@ -119,7 +131,7 @@ static int info_node(int fd, const char *item) { printf("\n"); printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options)); printf("Reachability: "); - if(!*port) + if(!strcmp(host, "MYSELF")) printf("can reach itself\n"); else if(!status.reachable) printf("unreachable\n"); diff --git a/src/net_packet.c b/src/net_packet.c index d45f0d03..abfb55c4 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -797,7 +797,7 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { for(node = edge_weight_tree->head; node; node = node->next) { e = node->data; - if(e->to == myself) + if(!e->to->status.reachable || e->to == myself) continue; if(sockaddrcmp_noport(from, &e->address)) { diff --git a/src/net_setup.c b/src/net_setup.c index 30ab0fa9..3991bd2b 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -709,6 +709,7 @@ static bool setup_myself(void) { myself->nexthop = myself; myself->via = myself; myself->status.reachable = true; + myself->last_state_change = time(NULL); myself->status.sptps = experimental; node_add(myself); diff --git a/src/node.c b/src/node.c index debc9155..8c81d481 100644 --- a/src/node.c +++ b/src/node.c @@ -135,20 +135,14 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { return; } - if(n->hostname) - free(n->hostname); - hash_insert(node_udp_cache, &n->address, NULL); if(sa) { n->address = *sa; hash_insert(node_udp_cache, sa, n); + free(n->hostname); n->hostname = sockaddr2hostname(&n->address); logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); - } else { - memset(&n->address, 0, sizeof n->address); - n->hostname = NULL; - logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s cleared", n->name); } } @@ -158,11 +152,11 @@ bool dump_nodes(connection_t *c) { for(node = node_tree->head; node; node = node->next) { n = node->data; - send_request(c, "%d %d %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)", CONTROL, REQ_DUMP_NODES, + send_request(c, "%d %d %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd) %ld", CONTROL, REQ_DUMP_NODES, n->name, n->hostname, cipher_get_nid(&n->outcipher), digest_get_nid(&n->outdigest), (int)digest_length(&n->outdigest), 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); + n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); diff --git a/src/node.h b/src/node.h index f5817fcd..dad926cc 100644 --- a/src/node.h +++ b/src/node.h @@ -47,6 +47,7 @@ typedef struct node_t { char *hostname; /* the hostname of its real ip */ node_status_t status; + time_t last_state_change; time_t last_req_key; ecdsa_t ecdsa; /* His public ECDSA key */ -- 2.20.1