From afd5acc4225111324e23f0927ab04282e5b80865 Mon Sep 17 00:00:00 2001 From: Hamish Coleman Date: Sat, 19 Oct 2024 15:53:39 +1100 Subject: [PATCH] Check that the peer object is not too old to use This is an attempt to fix the auth/reconnect issue. --- src/edge_utils.c | 6 ++---- src/peer_info.c | 24 ++++++++++++++++++++++++ src/peer_info.h | 1 + src/sn_utils.c | 8 +++++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/edge_utils.c b/src/edge_utils.c index 1aa6b7d..9be89b3 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -2726,12 +2726,10 @@ void process_udp (struct n3n_runtime_data *eee, const struct sockaddr *sender_so if((memcmp(nak.srcMac, eee->device.mac_addr, sizeof(n2n_mac_t))) == 0) { macstr_t buf_src; - macstr_t buf_dev; traceEvent( TRACE_ERROR, - "auth error: %s != %s", - macaddr_str(buf_src, nak.srcMac), - macaddr_str(buf_dev, eee->device.mac_addr) + "auth error: mac %s", + macaddr_str(buf_src, nak.srcMac) ); if(eee->conf.shared_secret) { traceEvent(TRACE_ERROR, "authentication error, username or password not recognized by supernode"); diff --git a/src/peer_info.c b/src/peer_info.c index 43cc9f6..d5ca9e7 100644 --- a/src/peer_info.c +++ b/src/peer_info.c @@ -98,6 +98,28 @@ void peer_info_free (struct peer_info *p) { free(p); } +/* + * If the peer is still valid, returns it. + * If the peer has timed out, frees it and returns NULL + * Used after a HASH_FIND_PEER to validate the found peer + */ +struct peer_info* peer_info_validate (struct peer_info **list, struct peer_info *p) { + if(!p) { + return NULL; + } + if(!p->purgeable) { + return p; + } + time_t now = time(NULL); + if(p->last_seen >= now - REGISTRATION_TIMEOUT) { + return p; + } + HASH_DEL(*list, p); + mgmt_event_post(N3N_EVENT_PEER,N3N_EVENT_PEER_PURGE,p); + peer_info_free(p); + return NULL; +} + inline char *peer_info_get_hostname (struct peer_info *p) { return p->hostname; } @@ -120,6 +142,8 @@ size_t purge_peer_list (struct peer_info **peer_list, } HASH_ITER(hh, *peer_list, scan, tmp) { + // TODO: untangle the tcp_connections usage and use + // peer_info_validate() as the core of this loop if(scan->purgeable && scan->last_seen < purge_before) { if((scan->socket_fd >=0) && (scan->socket_fd != socket_not_to_close)) { if(tcp_connections) { diff --git a/src/peer_info.h b/src/peer_info.h index f8ab87a..7d5290b 100644 --- a/src/peer_info.h +++ b/src/peer_info.h @@ -48,6 +48,7 @@ typedef struct peer_info peer_info_t; void peer_info_init (struct peer_info *, const n2n_mac_t mac); struct peer_info* peer_info_malloc (const n2n_mac_t mac); void peer_info_free (struct peer_info *); +struct peer_info* peer_info_validate (struct peer_info **, struct peer_info *); char *peer_info_get_hostname (struct peer_info *); diff --git a/src/sn_utils.c b/src/sn_utils.c index 1edd775..99915df 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -1195,7 +1195,11 @@ static int update_edge (struct n3n_runtime_data *sss, // if unknown, make sure it is also not known by IP address if(NULL == scan) { HASH_ITER(hh,comm->edges,iter,tmp) { - // TODO: needs ipv6 support + // TODO: + // - needs ipv6 support + // - I suspect that this can leak TCP connections + // - convert to using a peer_info_*() call for manipulating the + // peer info lists if(iter->dev_addr.net_addr == reg->dev_addr.net_addr) { scan = iter; HASH_DEL(comm->edges, scan); @@ -1206,6 +1210,8 @@ static int update_edge (struct n3n_runtime_data *sss, } } + scan = peer_info_validate(&comm->edges, scan); + if(NULL == scan) { /* Not known */ if(handle_remote_auth(sss, &(reg->auth), answer_auth, comm) == 0) {