Keep last known address and time since reachability changed.
This allows tincctl info to show since when a node is online or offline.
This commit is contained in:
parent
1e5deec973
commit
9ade39b7d5
6 changed files with 26 additions and 16 deletions
|
@ -188,7 +188,8 @@ static void sssp_bfs(void) {
|
||||||
e->to->options = e->options;
|
e->to->options = e->options;
|
||||||
e->to->distance = n->distance + 1;
|
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);
|
update_node_udp(e->to, &e->address);
|
||||||
|
|
||||||
list_insert_tail(todo_list, e->to);
|
list_insert_tail(todo_list, e->to);
|
||||||
|
@ -217,6 +218,7 @@ static void check_reachability(void) {
|
||||||
|
|
||||||
if(n->status.visited != n->status.reachable) {
|
if(n->status.visited != n->status.reachable) {
|
||||||
n->status.reachable = !n->status.reachable;
|
n->status.reachable = !n->status.reachable;
|
||||||
|
n->last_state_change = time(NULL);
|
||||||
|
|
||||||
if(n->status.reachable) {
|
if(n->status.reachable) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable",
|
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable",
|
||||||
|
|
22
src/info.c
22
src/info.c
|
@ -59,18 +59,19 @@ static int info_node(int fd, const char *item) {
|
||||||
short int pmtu, minmtu, maxmtu;
|
short int pmtu, minmtu, maxmtu;
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
node_status_t status;
|
node_status_t status;
|
||||||
|
long int last_state_change;
|
||||||
|
|
||||||
while(recvline(fd, line, sizeof line)) {
|
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)
|
if(n == 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(n != 17) {
|
if(n != 18) {
|
||||||
*port = 0;
|
*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");
|
fprintf(stderr, "Unable to parse node dump from tincd.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +96,16 @@ static int info_node(int fd, const char *item) {
|
||||||
printf("Node: %s\n", item);
|
printf("Node: %s\n", item);
|
||||||
if(*port)
|
if(*port)
|
||||||
printf("Address: %s port %s\n", host, 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: ");
|
printf("Status: ");
|
||||||
if(status.validkey)
|
if(status.validkey)
|
||||||
printf(" validkey");
|
printf(" validkey");
|
||||||
|
@ -107,6 +118,7 @@ static int info_node(int fd, const char *item) {
|
||||||
if(status.sptps)
|
if(status.sptps)
|
||||||
printf(" sptps");
|
printf(" sptps");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("Options: ");
|
printf("Options: ");
|
||||||
if(options & OPTION_INDIRECT)
|
if(options & OPTION_INDIRECT)
|
||||||
printf(" indirect");
|
printf(" indirect");
|
||||||
|
@ -119,7 +131,7 @@ static int info_node(int fd, const char *item) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options));
|
printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options));
|
||||||
printf("Reachability: ");
|
printf("Reachability: ");
|
||||||
if(!*port)
|
if(!strcmp(host, "MYSELF"))
|
||||||
printf("can reach itself\n");
|
printf("can reach itself\n");
|
||||||
else if(!status.reachable)
|
else if(!status.reachable)
|
||||||
printf("unreachable\n");
|
printf("unreachable\n");
|
||||||
|
|
|
@ -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) {
|
for(node = edge_weight_tree->head; node; node = node->next) {
|
||||||
e = node->data;
|
e = node->data;
|
||||||
|
|
||||||
if(e->to == myself)
|
if(!e->to->status.reachable || e->to == myself)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(sockaddrcmp_noport(from, &e->address)) {
|
if(sockaddrcmp_noport(from, &e->address)) {
|
||||||
|
|
|
@ -709,6 +709,7 @@ static bool setup_myself(void) {
|
||||||
myself->nexthop = myself;
|
myself->nexthop = myself;
|
||||||
myself->via = myself;
|
myself->via = myself;
|
||||||
myself->status.reachable = true;
|
myself->status.reachable = true;
|
||||||
|
myself->last_state_change = time(NULL);
|
||||||
myself->status.sptps = experimental;
|
myself->status.sptps = experimental;
|
||||||
node_add(myself);
|
node_add(myself);
|
||||||
|
|
||||||
|
|
12
src/node.c
12
src/node.c
|
@ -135,20 +135,14 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n->hostname)
|
|
||||||
free(n->hostname);
|
|
||||||
|
|
||||||
hash_insert(node_udp_cache, &n->address, NULL);
|
hash_insert(node_udp_cache, &n->address, NULL);
|
||||||
|
|
||||||
if(sa) {
|
if(sa) {
|
||||||
n->address = *sa;
|
n->address = *sa;
|
||||||
hash_insert(node_udp_cache, sa, n);
|
hash_insert(node_udp_cache, sa, n);
|
||||||
|
free(n->hostname);
|
||||||
n->hostname = sockaddr2hostname(&n->address);
|
n->hostname = sockaddr2hostname(&n->address);
|
||||||
logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname);
|
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) {
|
for(node = node_tree->head; node; node = node->next) {
|
||||||
n = node->data;
|
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),
|
n->name, n->hostname, cipher_get_nid(&n->outcipher),
|
||||||
digest_get_nid(&n->outdigest), (int)digest_length(&n->outdigest), n->outcompression,
|
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->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);
|
return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES);
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct node_t {
|
||||||
char *hostname; /* the hostname of its real ip */
|
char *hostname; /* the hostname of its real ip */
|
||||||
|
|
||||||
node_status_t status;
|
node_status_t status;
|
||||||
|
time_t last_state_change;
|
||||||
time_t last_req_key;
|
time_t last_req_key;
|
||||||
|
|
||||||
ecdsa_t ecdsa; /* His public ECDSA key */
|
ecdsa_t ecdsa; /* His public ECDSA key */
|
||||||
|
|
Loading…
Reference in a new issue