Keep last known address and time since reachability changed.
authorGuus Sliepen <guus@tinc-vpn.org>
Wed, 26 Sep 2012 20:20:43 +0000 (22:20 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Wed, 26 Sep 2012 20:20:43 +0000 (22:20 +0200)
This allows tincctl info to show since when a node is online or offline.

src/graph.c
src/info.c
src/net_packet.c
src/net_setup.c
src/node.c
src/node.h

index 9da552e..98eb469 100644 (file)
@@ -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",
index 18b8e24..ee60a3f 100644 (file)
@@ -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");
index d45f0d0..abfb55c 100644 (file)
@@ -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)) {
index 30ab0fa..3991bd2 100644 (file)
@@ -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);
 
index debc915..8c81d48 100644 (file)
@@ -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);
index f5817fc..dad926c 100644 (file)
@@ -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 */