From 703197ca7614963ba9b831967352b6c90379af48 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Fri, 6 Dec 2019 21:47:11 +0100 Subject: [PATCH] Don't add duplicates to the list of recently seen addresses. Duplicate addresses would be appended to the list, and could push out other addresses. If the address already exists, only move it to the top if it is not already there. Also don't force an immediate write of the host config file when trying to add an address that already exists. --- src/discovery.c | 4 ++-- src/meshlink.c | 8 ++++---- src/node.c | 31 ++++++++++++++++++++++++++++++- src/node.h | 1 + 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/discovery.c b/src/discovery.c index 52b08f2c..68e1a261 100644 --- a/src/discovery.c +++ b/src/discovery.c @@ -248,11 +248,11 @@ static void discovery_resolve_callback(CattaSServiceResolver *resolver, CattaIfI } if(naddress.unknown.family != AF_UNKNOWN) { - meshlink_hint_address(mesh, node, (struct sockaddr *)&naddress); - node_t *n = (node_t *)node; connection_t *c = n->connection; + node_add_recent_address(mesh, n, &naddress); + if(c && c->outgoing && !c->status.active) { c->outgoing->timeout = 0; diff --git a/src/meshlink.c b/src/meshlink.c index b0cb8a93..69ab8f24 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -3120,11 +3120,11 @@ void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const pthread_mutex_lock(&mesh->mutex); node_t *n = (node_t *)node; - memmove(n->recent + 1, n->recent, (MAX_RECENT - 1) * sizeof(*n->recent)); - memcpy(n->recent, addr, SALEN(*addr)); - if(!node_write_config(mesh, n)) { - logger(mesh, MESHLINK_DEBUG, "Could not update %s\n", n->name); + if(node_add_recent_address(mesh, n, (sockaddr_t *)addr)) { + if(!node_write_config(mesh, n)) { + logger(mesh, MESHLINK_DEBUG, "Could not update %s\n", n->name); + } } pthread_mutex_unlock(&mesh->mutex); diff --git a/src/node.c b/src/node.c index 5f5d235c..b8caed6c 100644 --- a/src/node.c +++ b/src/node.c @@ -135,7 +135,7 @@ void update_node_udp(meshlink_handle_t *mesh, node_t *n, const sockaddr_t *sa) { hash_insert(mesh->node_udp_cache, sa, n); - meshlink_hint_address(mesh, (meshlink_node_t *)n, &sa->sa); + node_add_recent_address(mesh, n, sa); if(mesh->log_level <= MESHLINK_DEBUG) { char *hostname = sockaddr2hostname(&n->address); @@ -144,3 +144,32 @@ void update_node_udp(meshlink_handle_t *mesh, node_t *n, const sockaddr_t *sa) { } } } + +bool node_add_recent_address(meshlink_handle_t *mesh, node_t *n, const sockaddr_t *sa) { + (void)mesh; + bool found = false; + int i; + + /* Check if we already know this address */ + for(i = 0; i < MAX_RECENT && n->recent[i].sa.sa_family; i++) { + if(!sockaddrcmp(&n->recent[i], sa)) { + found = true; + break; + } + } + + if(found && i == 0) { + /* It's already the most recent address, nothing to do. */ + return false; + } + + if(i >= MAX_RECENT) { + i = MAX_RECENT - 1; + } + + memmove(n->recent + 1, n->recent, i * sizeof(*n->recent)); + memcpy(n->recent, sa, SALEN(sa->sa)); + + n->status.dirty = true; + return !found; +} diff --git a/src/node.h b/src/node.h index 19e31fac..ff8b3335 100644 --- a/src/node.h +++ b/src/node.h @@ -107,5 +107,6 @@ extern void node_del(struct meshlink_handle *mesh, node_t *n); extern node_t *lookup_node(struct meshlink_handle *mesh, const char *name) __attribute__((__warn_unused_result__)); extern node_t *lookup_node_udp(struct meshlink_handle *mesh, const sockaddr_t *sa) __attribute__((__warn_unused_result__)); extern void update_node_udp(struct meshlink_handle *mesh, node_t *n, const sockaddr_t *sa); +extern bool node_add_recent_address(struct meshlink_handle *mesh, node_t *n, const sockaddr_t *addr); #endif -- 2.39.2