From ace3dbc44f07c3edeebf5c4aa7eac09cd546f947 Mon Sep 17 00:00:00 2001 From: Hamish Coleman Date: Sat, 6 Nov 2021 19:55:31 +0000 Subject: [PATCH] Move all supernode management handling into one source file --- include/n2n.h | 1 - src/sn_management.c | 163 ++++++++++++++++++++++++++++++++++++++++- src/sn_utils.c | 171 +------------------------------------------- 3 files changed, 163 insertions(+), 172 deletions(-) diff --git a/include/n2n.h b/include/n2n.h index 79c4108..9ca353a 100644 --- a/include/n2n.h +++ b/include/n2n.h @@ -286,5 +286,4 @@ const char* compression_str (uint8_t cmpr); const char* transop_str (enum n2n_transform tr); void readFromMgmtSocket (n2n_edge_t *eee); -void handleMgmtJson_sn (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock); #endif /* _N2N_H_ */ diff --git a/src/sn_management.c b/src/sn_management.c index 0f34a39..b220c00 100644 --- a/src/sn_management.c +++ b/src/sn_management.c @@ -326,7 +326,7 @@ static int mgmt_auth (n2n_sn_t *sss, const struct sockaddr_in sender_sock, enum return 0; } -void handleMgmtJson_sn (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock) { +static void handleMgmtJson (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock) { char cmdlinebuf[80]; enum n2n_mgmt_type type; @@ -439,3 +439,164 @@ void handleMgmtJson_sn (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in s (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); return; } + +static int sendto_mgmt (n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const uint8_t *mgmt_buf, + size_t mgmt_size) { + + ssize_t r = sendto(sss->mgmt_sock, (void *)mgmt_buf, mgmt_size, 0 /*flags*/, + (struct sockaddr *)sender_sock, sizeof (struct sockaddr_in)); + + if(r <= 0) { + ++(sss->stats.errors); + traceEvent(TRACE_ERROR, "sendto_mgmt : sendto failed. %s", strerror(errno)); + return -1; + } + + return 0; +} + +int process_mgmt (n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + char *mgmt_buf, + size_t mgmt_size, + time_t now) { + + char resbuf[N2N_SN_PKTBUF_SIZE]; + size_t ressize = 0; + uint32_t num_edges = 0; + uint32_t num_comm = 0; + uint32_t num = 0; + struct sn_community *community, *tmp; + struct peer_info *peer, *tmpPeer; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + char time_buf[10]; /* 9 digits + 1 terminating zero */ + dec_ip_bit_str_t ip_bit_str = {'\0'}; + + traceEvent(TRACE_DEBUG, "process_mgmt"); + + /* avoid parsing any uninitialized junk from the stack */ + mgmt_buf[mgmt_size] = 0; + + // process input, if any + if((0 == memcmp(mgmt_buf, "help", 4)) || (0 == memcmp(mgmt_buf, "?", 1))) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "Help for supernode management console:\n" + "\thelp | This help message\n" + "\treload_communities | Reloads communities and user's public keys\n" + "\t | Display status and statistics\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + + if(0 == memcmp(mgmt_buf, "reload_communities", 18)) { + if(!sss->community_file) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "No community file provided (-c command line option)\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + traceEvent(TRACE_NORMAL, "'reload_communities' command"); + + if(load_allowed_sn_community(sss)) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "Error while re-loading community file (not found or no valid content)\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "OK.\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + + if((mgmt_buf[0] == 'r' || mgmt_buf[0] == 'w') && (mgmt_buf[1] == ' ')) { + /* this is a JSON request */ + handleMgmtJson(sss, mgmt_buf, *sender_sock); + return 0; + } + + // output current status + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + " ### | TAP | MAC | EDGE | HINT | LAST SEEN\n"); + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "========================================================================================================\n"); + HASH_ITER(hh, sss->communities, community, tmp) { + if(num_comm) + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "--------------------------------------------------------------------------------------------------------\n"); + num_comm++; + num_edges += HASH_COUNT(community->edges); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "%s '%s'\n", + (community->is_federation) ? "FEDERATION" : ((community->purgeable == COMMUNITY_UNPURGEABLE) ? "FIXED NAME COMMUNITY" : "COMMUNITY"), + (community->is_federation) ? "-/-" : community->community); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + ressize = 0; + + num = 0; + HASH_ITER(hh, community->edges, peer, tmpPeer) { + sprintf(time_buf, "%9u", (unsigned int)(now - peer->last_seen)); + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "%4u | %-19s | %-17s | %-21s %-3s | %-15s | %9s\n", + ++num, + (peer->dev_addr.net_addr == 0) ? ((peer->purgeable == SN_UNPURGEABLE) ? "-l" : "") : ip_subnet_to_str(ip_bit_str, &peer->dev_addr), + (is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + ((peer->socket_fd >= 0) && (peer->socket_fd != sss->sock)) ? "TCP" : "", + peer->dev_desc, + (peer->last_seen) ? time_buf : ""); + + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + ressize = 0; + } + } + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "========================================================================================================\n"); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "uptime %lu | ", (now - sss->start_time)); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "edges %u | ", + num_edges); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "reg_sup %u | ", + (unsigned int) sss->stats.reg_super); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "reg_nak %u | ", + (unsigned int) sss->stats.reg_super_nak); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "errors %u \n", + (unsigned int) sss->stats.errors); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "fwd %u | ", + (unsigned int) sss->stats.fwd); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "broadcast %u | ", + (unsigned int) sss->stats.broadcast); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "cur_cmnts %u\n", HASH_COUNT(sss->communities)); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "last_fwd %lu sec ago | ", + (long unsigned int) (now - sss->stats.last_fwd)); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "last reg %lu sec ago\n\n", + (long unsigned int) (now - sss->stats.last_reg_super)); + + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + + return 0; +} diff --git a/src/sn_utils.c b/src/sn_utils.c index 464eb9e..b14469d 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -30,11 +30,6 @@ static ssize_t sendto_peer (n2n_sn_t *sss, const uint8_t *pktbuf, size_t pktsize); -static int sendto_mgmt (n2n_sn_t *sss, - const struct sockaddr_in *sender_sock, - const uint8_t *mgmt_buf, - size_t mgmt_size); - static uint16_t reg_lifetime (n2n_sn_t *sss); static int update_edge (n2n_sn_t *sss, @@ -61,7 +56,7 @@ static int sort_communities (n2n_sn_t *sss, time_t* p_last_sort, time_t now); -static int process_mgmt (n2n_sn_t *sss, +int process_mgmt (n2n_sn_t *sss, const struct sockaddr_in *sender_sock, char *mgmt_buf, size_t mgmt_size, @@ -1501,170 +1496,6 @@ static int sort_communities (n2n_sn_t *sss, } -static int process_mgmt (n2n_sn_t *sss, - const struct sockaddr_in *sender_sock, - char *mgmt_buf, - size_t mgmt_size, - time_t now) { - - char resbuf[N2N_SN_PKTBUF_SIZE]; - size_t ressize = 0; - uint32_t num_edges = 0; - uint32_t num_comm = 0; - uint32_t num = 0; - struct sn_community *community, *tmp; - struct peer_info *peer, *tmpPeer; - macstr_t mac_buf; - n2n_sock_str_t sockbuf; - char time_buf[10]; /* 9 digits + 1 terminating zero */ - dec_ip_bit_str_t ip_bit_str = {'\0'}; - - traceEvent(TRACE_DEBUG, "process_mgmt"); - - /* avoid parsing any uninitialized junk from the stack */ - mgmt_buf[mgmt_size] = 0; - - // process input, if any - if((0 == memcmp(mgmt_buf, "help", 4)) || (0 == memcmp(mgmt_buf, "?", 1))) { - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "Help for supernode management console:\n" - "\thelp | This help message\n" - "\treload_communities | Reloads communities and user's public keys\n" - "\t | Display status and statistics\n"); - sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - return 0; /* no status output afterwards */ - } - - if(0 == memcmp(mgmt_buf, "reload_communities", 18)) { - if(!sss->community_file) { - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "No community file provided (-c command line option)\n"); - sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - return 0; /* no status output afterwards */ - } - traceEvent(TRACE_NORMAL, "'reload_communities' command"); - - if(load_allowed_sn_community(sss)) { - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "Error while re-loading community file (not found or no valid content)\n"); - sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - return 0; /* no status output afterwards */ - } - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "OK.\n"); - sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - return 0; /* no status output afterwards */ - } - - if((mgmt_buf[0] == 'r' || mgmt_buf[0] == 'w') && (mgmt_buf[1] == ' ')) { - /* this is a JSON request */ - handleMgmtJson_sn(sss, mgmt_buf, *sender_sock); - return 0; - } - - // output current status - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - " ### | TAP | MAC | EDGE | HINT | LAST SEEN\n"); - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "========================================================================================================\n"); - HASH_ITER(hh, sss->communities, community, tmp) { - if(num_comm) - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "--------------------------------------------------------------------------------------------------------\n"); - num_comm++; - num_edges += HASH_COUNT(community->edges); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "%s '%s'\n", - (community->is_federation) ? "FEDERATION" : - ((community->purgeable == COMMUNITY_UNPURGEABLE) ? "FIXED NAME COMMUNITY" : "COMMUNITY"), - (community->is_federation) ? "-/-" : community->community); - sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - ressize = 0; - - num = 0; - HASH_ITER(hh, community->edges, peer, tmpPeer) { - sprintf (time_buf, "%9u", (unsigned int)(now - peer->last_seen)); - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "%4u | %-19s | %-17s | %-21s %-3s | %-15s | %9s\n", - ++num, - (peer->dev_addr.net_addr == 0) ? ((peer->purgeable == SN_UNPURGEABLE) ? "-l" : "") : - ip_subnet_to_str(ip_bit_str, &peer->dev_addr), - (is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac_buf, peer->mac_addr), - sock_to_cstr(sockbuf, &(peer->sock)), - ((peer->socket_fd >= 0) && (peer->socket_fd != sss->sock)) ? "TCP" : "", - peer->dev_desc, - (peer->last_seen) ? time_buf : ""); - - sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - ressize = 0; - } - } - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "========================================================================================================\n"); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "uptime %lu | ", (now - sss->start_time)); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "edges %u | ", - num_edges); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "reg_sup %u | ", - (unsigned int) sss->stats.reg_super); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "reg_nak %u | ", - (unsigned int) sss->stats.reg_super_nak); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "errors %u \n", - (unsigned int) sss->stats.errors); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "fwd %u | ", - (unsigned int) sss->stats.fwd); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "broadcast %u | ", - (unsigned int) sss->stats.broadcast); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "cur_cmnts %u\n", HASH_COUNT(sss->communities)); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "last_fwd %lu sec ago | ", - (long unsigned int) (now - sss->stats.last_fwd)); - - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "last reg %lu sec ago\n\n", - (long unsigned int) (now - sss->stats.last_reg_super)); - - sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - - return 0; -} - - -static int sendto_mgmt (n2n_sn_t *sss, - const struct sockaddr_in *sender_sock, - const uint8_t *mgmt_buf, - size_t mgmt_size) { - - ssize_t r = sendto(sss->mgmt_sock, (void *)mgmt_buf, mgmt_size, 0 /*flags*/, - (struct sockaddr *)sender_sock, sizeof (struct sockaddr_in)); - - if(r <= 0) { - ++(sss->stats.errors); - traceEvent (TRACE_ERROR, "sendto_mgmt : sendto failed. %s", strerror (errno)); - return -1; - } - - return 0; -} - /** Examine a datagram and determine what to do with it. * */