Merge branch 'dev' into rp

This commit is contained in:
Luca Deri 2020-07-27 06:57:36 +02:00 committed by GitHub
commit e635926d2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 39 deletions

View File

@ -363,6 +363,7 @@ typedef struct n2n_sn
sn_stats_t stats;
int daemon; /* If non-zero then daemonise. */
uint16_t lport; /* Local UDP port to bind to. */
uint16_t mport; /* Management UDP port to bind to. */
int sock; /* Main socket for UDP traffic with edges. */
int mgmt_sock; /* management socket. */
int lock_communities; /* If true, only loaded communities can be used. */

View File

@ -35,6 +35,9 @@
#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */
#define TRANSOP_TICK_INTERVAL (10) /* sec */
#define PURGE_REGISTRATION_FREQUENCY 30
#define REGISTRATION_TIMEOUT 60
#define ETH_FRAMESIZE 14
#define IP4_SRCOFFSET 12
#define IP4_DSTOFFSET 16

View File

@ -2504,6 +2504,7 @@ static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_r
#ifdef WIN32
return edge_init_routes_win(eee, routes, num_routes);
#endif
return 0;
}
/* ************************************** */

View File

@ -22,13 +22,13 @@
#include <assert.h>
#define PURGE_REGISTRATION_FREQUENCY 30
#define REGISTRATION_TIMEOUT 60
#define TIME_STAMP_FRAME 0x0000001000000000LL /* clocks of different computers are allowed +/- 16 seconds to be off */
#define TIME_STAMP_JITTER 0x0000000027100000LL /* we allow a packet to arrive 160 ms (== 0x27100 us) before another
* set to 0x0000000000000000LL if increasing (or equal) time stamps allowed only */
static const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */
static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */

View File

@ -104,19 +104,21 @@ static void help() {
"or\n"
);
printf("supernode ");
printf("-l <lport> ");
printf("-l <local port> ");
printf("-c <path> ");
#if defined(N2N_HAVE_DAEMON)
printf("[-f] ");
#endif
printf("[-t <mgmt port>] ");
printf("[-v] ");
printf("\n\n");
printf("-l <lport>\tSet UDP main listen port to <lport>\n");
printf("-l <port>\tSet UDP main listen port to <port>\n");
printf("-c <path>\tFile containing the allowed communities.\n");
#if defined(N2N_HAVE_DAEMON)
printf("-f \tRun in foreground.\n");
#endif /* #if defined(N2N_HAVE_DAEMON) */
printf("-t <port>\tManagement UDP Port (for multiple supernodes on a machine).\n");
printf("-v \tIncrease verbosity. Can be used multiple times.\n");
printf("-h \tThis help message.\n");
printf("\n");
@ -135,6 +137,10 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
sss->lport = atoi(_optarg);
break;
case 't': /* mgmt-port */
sss->mport = atoi(_optarg);
break;
case 'c': /* community file */
load_allowed_sn_community(sss, _optarg);
break;
@ -165,9 +171,10 @@ static const struct option long_options[] = {
{ "communities", required_argument, NULL, 'c' },
{ "foreground", no_argument, NULL, 'f' },
{ "local-port", required_argument, NULL, 'l' },
{ "mgmt-port", required_argument, NULL, 't' },
{ "help" , no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
{ NULL, 0, NULL, 0 }
};
/* *************************************************** */
@ -176,7 +183,7 @@ static const struct option long_options[] = {
static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) {
u_char c;
while((c = getopt_long(argc, argv, "fl:c:vh",
while((c = getopt_long(argc, argv, "fl:t:c:vh",
long_options, NULL)) != '?') {
if(c == 255) break;
setOption(c, optarg, sss);
@ -380,12 +387,12 @@ int main(int argc, char * const argv[]) {
traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (main)", sss_node.lport);
}
sss_node.mgmt_sock = open_socket(N2N_SN_MGMT_PORT, 0 /* bind LOOPBACK */);
sss_node.mgmt_sock = open_socket(sss_node.mport, 0 /* bind LOOPBACK */);
if(-1 == sss_node.mgmt_sock) {
traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno));
exit(-2);
} else
traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (management)", N2N_SN_MGMT_PORT);
traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (management)", sss_node.mport);
traceEvent(TRACE_NORMAL, "supernode started");

View File

@ -14,6 +14,11 @@ static ssize_t sendto_sock(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 int try_broadcast(n2n_sn_t * sss,
const struct sn_community *comm,
const n2n_common_t * cmn,
@ -29,6 +34,10 @@ static int update_edge(n2n_sn_t *sss,
const n2n_sock_t *sender_sock,
time_t now);
static int purge_expired_communities(n2n_sn_t *sss,
time_t* p_last_purge,
time_t now);
static int process_mgmt(n2n_sn_t *sss,
const struct sockaddr_in *sender_sock,
const uint8_t *mgmt_buf,
@ -185,6 +194,7 @@ int sn_init(n2n_sn_t *sss)
sss->daemon = 1; /* By defult run as a daemon. */
sss->lport = N2N_SN_LPORT_DEFAULT;
sss->mport = N2N_SN_MGMT_PORT;
sss->sock = -1;
sss->mgmt_sock = -1;
@ -313,6 +323,35 @@ static int find_edge_time_stamp_and_verify (struct peer_info * edges,
return ( time_stamp_verify_and_update (stamp, previous_stamp) );
}
static int purge_expired_communities(n2n_sn_t *sss,
time_t* p_last_purge,
time_t now)
{
struct sn_community *comm, *tmp;
size_t num_reg = 0;
if ((now - (*p_last_purge)) < PURGE_REGISTRATION_FREQUENCY) return 0;
traceEvent(TRACE_DEBUG, "Purging old communities and edges");
HASH_ITER(hh, sss->communities, comm, tmp) {
num_reg += purge_peer_list(&comm->edges, now - REGISTRATION_TIMEOUT);
if ((comm->edges == NULL) && (!sss->lock_communities)) {
traceEvent(TRACE_INFO, "Purging idle community %s", comm->community);
if (NULL != comm->header_encryption_ctx)
/* this should not happen as no 'locked' and thus only communities w/o encrypted header here */
free(comm->header_encryption_ctx);
HASH_DEL(sss->communities, comm);
free(comm);
}
}
(*p_last_purge) = now;
traceEvent(TRACE_DEBUG, "Remove %ld edges", num_reg);
return 0;
}
static int process_mgmt(n2n_sn_t *sss,
const struct sockaddr_in *sender_sock,
@ -323,10 +362,11 @@ static int process_mgmt(n2n_sn_t *sss,
char resbuf[N2N_SN_PKTBUF_SIZE];
size_t ressize = 0;
uint32_t num_edges = 0;
ssize_t r;
uint32_t num = 0;
struct sn_community *community, *tmp;
struct peer_info * peer, *tmpPeer;
macstr_t mac_buf;
n2n_sock_str_t sockbuf;
traceEvent(TRACE_DEBUG, "process_mgmt");
@ -374,32 +414,48 @@ static int process_mgmt(n2n_sn_t *sss,
(long unsigned int)(now - sss->stats.last_reg_super));
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
"cur_cmnts");
"cur_cmnts %u\n", HASH_COUNT(sss->communities));
HASH_ITER(hh, sss->communities, community, tmp) {
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
" [%s]",
community->community);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"community: %s\n", community->community);
sendto_mgmt(sss, sender_sock, resbuf, ressize);
ressize = 0;
num = 0;
HASH_ITER(hh, community->edges, peer, tmpPeer) {
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
" {%s}",
macaddr_str(mac_buf, peer->mac_addr));
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"\t[id: %u][MAC: %s][edge: %s][last seen: %lu sec ago]\n",
++num, macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), now-peer->last_seen);
sendto_mgmt(sss, sender_sock, resbuf, ressize);
ressize = 0;
}
}
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
"\n");
r = sendto(sss->mgmt_sock, resbuf, ressize, 0 /*flags*/,
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
if (r <= 0)
{
++(sss->stats.errors);
traceEvent(TRACE_ERROR, "process_mgmt : sendto failed. %s", strerror(errno));
}
sendto_mgmt(sss, sender_sock, 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, 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.
*
*/
@ -830,7 +886,6 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
{
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE];
time_t last_purge_edges = 0;
struct sn_community *comm, *tmp;
sss->start_time = time(NULL);
@ -915,20 +970,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
traceEvent(TRACE_DEBUG, "timeout");
}
HASH_ITER(hh, sss->communities, comm, tmp)
{
purge_expired_registrations(&comm->edges, &last_purge_edges);
if ((comm->edges == NULL) && (!sss->lock_communities))
{
traceEvent(TRACE_INFO, "Purging idle community %s", comm->community);
if (NULL != comm->header_encryption_ctx)
/* this should not happen as no 'locked' and thus only communities w/o encrypted header here */
free (comm->header_encryption_ctx);
HASH_DEL(sss->communities, comm);
free(comm);
}
}
purge_expired_communities(sss, &last_purge_edges, now);
} /* while */