mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
Merge branch 'dev' into rp
This commit is contained in:
commit
e635926d2c
|
@ -363,6 +363,7 @@ typedef struct n2n_sn
|
||||||
sn_stats_t stats;
|
sn_stats_t stats;
|
||||||
int daemon; /* If non-zero then daemonise. */
|
int daemon; /* If non-zero then daemonise. */
|
||||||
uint16_t lport; /* Local UDP port to bind to. */
|
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 sock; /* Main socket for UDP traffic with edges. */
|
||||||
int mgmt_sock; /* management socket. */
|
int mgmt_sock; /* management socket. */
|
||||||
int lock_communities; /* If true, only loaded communities can be used. */
|
int lock_communities; /* If true, only loaded communities can be used. */
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */
|
#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */
|
||||||
#define TRANSOP_TICK_INTERVAL (10) /* sec */
|
#define TRANSOP_TICK_INTERVAL (10) /* sec */
|
||||||
|
|
||||||
|
#define PURGE_REGISTRATION_FREQUENCY 30
|
||||||
|
#define REGISTRATION_TIMEOUT 60
|
||||||
|
|
||||||
#define ETH_FRAMESIZE 14
|
#define ETH_FRAMESIZE 14
|
||||||
#define IP4_SRCOFFSET 12
|
#define IP4_SRCOFFSET 12
|
||||||
#define IP4_DSTOFFSET 16
|
#define IP4_DSTOFFSET 16
|
||||||
|
|
|
@ -2504,6 +2504,7 @@ static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_r
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
return edge_init_routes_win(eee, routes, num_routes);
|
return edge_init_routes_win(eee, routes, num_routes);
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
|
@ -22,13 +22,13 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
#define PURGE_REGISTRATION_FREQUENCY 30
|
#define PURGE_REGISTRATION_FREQUENCY 30
|
||||||
#define REGISTRATION_TIMEOUT 60
|
#define REGISTRATION_TIMEOUT 60
|
||||||
|
|
||||||
#define TIME_STAMP_FRAME 0x0000001000000000LL /* clocks of different computers are allowed +/- 16 seconds to be off */
|
#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
|
#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 */
|
* 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 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 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 */
|
static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */
|
||||||
|
|
17
src/sn.c
17
src/sn.c
|
@ -104,19 +104,21 @@ static void help() {
|
||||||
"or\n"
|
"or\n"
|
||||||
);
|
);
|
||||||
printf("supernode ");
|
printf("supernode ");
|
||||||
printf("-l <lport> ");
|
printf("-l <local port> ");
|
||||||
printf("-c <path> ");
|
printf("-c <path> ");
|
||||||
#if defined(N2N_HAVE_DAEMON)
|
#if defined(N2N_HAVE_DAEMON)
|
||||||
printf("[-f] ");
|
printf("[-f] ");
|
||||||
#endif
|
#endif
|
||||||
|
printf("[-t <mgmt port>] ");
|
||||||
printf("[-v] ");
|
printf("[-v] ");
|
||||||
printf("\n\n");
|
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");
|
printf("-c <path>\tFile containing the allowed communities.\n");
|
||||||
#if defined(N2N_HAVE_DAEMON)
|
#if defined(N2N_HAVE_DAEMON)
|
||||||
printf("-f \tRun in foreground.\n");
|
printf("-f \tRun in foreground.\n");
|
||||||
#endif /* #if defined(N2N_HAVE_DAEMON) */
|
#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("-v \tIncrease verbosity. Can be used multiple times.\n");
|
||||||
printf("-h \tThis help message.\n");
|
printf("-h \tThis help message.\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -135,6 +137,10 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
||||||
sss->lport = atoi(_optarg);
|
sss->lport = atoi(_optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 't': /* mgmt-port */
|
||||||
|
sss->mport = atoi(_optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'c': /* community file */
|
case 'c': /* community file */
|
||||||
load_allowed_sn_community(sss, _optarg);
|
load_allowed_sn_community(sss, _optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -165,6 +171,7 @@ static const struct option long_options[] = {
|
||||||
{ "communities", required_argument, NULL, 'c' },
|
{ "communities", required_argument, NULL, 'c' },
|
||||||
{ "foreground", no_argument, NULL, 'f' },
|
{ "foreground", no_argument, NULL, 'f' },
|
||||||
{ "local-port", required_argument, NULL, 'l' },
|
{ "local-port", required_argument, NULL, 'l' },
|
||||||
|
{ "mgmt-port", required_argument, NULL, 't' },
|
||||||
{ "help" , no_argument, NULL, 'h' },
|
{ "help" , no_argument, NULL, 'h' },
|
||||||
{ "verbose", no_argument, NULL, 'v' },
|
{ "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) {
|
static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) {
|
||||||
u_char c;
|
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)) != '?') {
|
long_options, NULL)) != '?') {
|
||||||
if(c == 255) break;
|
if(c == 255) break;
|
||||||
setOption(c, optarg, sss);
|
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);
|
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) {
|
if(-1 == sss_node.mgmt_sock) {
|
||||||
traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno));
|
traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno));
|
||||||
exit(-2);
|
exit(-2);
|
||||||
} else
|
} 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");
|
traceEvent(TRACE_NORMAL, "supernode started");
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ static ssize_t sendto_sock(n2n_sn_t *sss,
|
||||||
const uint8_t *pktbuf,
|
const uint8_t *pktbuf,
|
||||||
size_t pktsize);
|
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,
|
static int try_broadcast(n2n_sn_t * sss,
|
||||||
const struct sn_community *comm,
|
const struct sn_community *comm,
|
||||||
const n2n_common_t * cmn,
|
const n2n_common_t * cmn,
|
||||||
|
@ -29,6 +34,10 @@ static int update_edge(n2n_sn_t *sss,
|
||||||
const n2n_sock_t *sender_sock,
|
const n2n_sock_t *sender_sock,
|
||||||
time_t now);
|
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,
|
static int process_mgmt(n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr_in *sender_sock,
|
||||||
const uint8_t *mgmt_buf,
|
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->daemon = 1; /* By defult run as a daemon. */
|
||||||
sss->lport = N2N_SN_LPORT_DEFAULT;
|
sss->lport = N2N_SN_LPORT_DEFAULT;
|
||||||
|
sss->mport = N2N_SN_MGMT_PORT;
|
||||||
sss->sock = -1;
|
sss->sock = -1;
|
||||||
sss->mgmt_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) );
|
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,
|
static int process_mgmt(n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr_in *sender_sock,
|
||||||
|
@ -323,10 +362,11 @@ static int process_mgmt(n2n_sn_t *sss,
|
||||||
char resbuf[N2N_SN_PKTBUF_SIZE];
|
char resbuf[N2N_SN_PKTBUF_SIZE];
|
||||||
size_t ressize = 0;
|
size_t ressize = 0;
|
||||||
uint32_t num_edges = 0;
|
uint32_t num_edges = 0;
|
||||||
ssize_t r;
|
uint32_t num = 0;
|
||||||
struct sn_community *community, *tmp;
|
struct sn_community *community, *tmp;
|
||||||
struct peer_info * peer, *tmpPeer;
|
struct peer_info * peer, *tmpPeer;
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
|
n2n_sock_str_t sockbuf;
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "process_mgmt");
|
traceEvent(TRACE_DEBUG, "process_mgmt");
|
||||||
|
|
||||||
|
@ -374,29 +414,45 @@ static int process_mgmt(n2n_sn_t *sss,
|
||||||
(long unsigned int)(now - sss->stats.last_reg_super));
|
(long unsigned int)(now - sss->stats.last_reg_super));
|
||||||
|
|
||||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
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) {
|
HASH_ITER(hh, sss->communities, community, tmp) {
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
" [%s]",
|
"community: %s\n", community->community);
|
||||||
community->community);
|
sendto_mgmt(sss, sender_sock, resbuf, ressize);
|
||||||
|
ressize = 0;
|
||||||
|
|
||||||
|
num = 0;
|
||||||
HASH_ITER(hh, community->edges, peer, tmpPeer) {
|
HASH_ITER(hh, community->edges, peer, tmpPeer) {
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
" {%s}",
|
"\t[id: %u][MAC: %s][edge: %s][last seen: %lu sec ago]\n",
|
||||||
macaddr_str(mac_buf, peer->mac_addr));
|
++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,
|
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||||
"\n");
|
"\n");
|
||||||
|
sendto_mgmt(sss, sender_sock, resbuf, ressize);
|
||||||
|
|
||||||
r = sendto(sss->mgmt_sock, resbuf, ressize, 0 /*flags*/,
|
return 0;
|
||||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
if (r <= 0)
|
|
||||||
{
|
|
||||||
++(sss->stats.errors);
|
|
||||||
traceEvent(TRACE_ERROR, "process_mgmt : sendto failed. %s", strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,7 +886,6 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
|
||||||
{
|
{
|
||||||
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE];
|
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE];
|
||||||
time_t last_purge_edges = 0;
|
time_t last_purge_edges = 0;
|
||||||
struct sn_community *comm, *tmp;
|
|
||||||
|
|
||||||
sss->start_time = time(NULL);
|
sss->start_time = time(NULL);
|
||||||
|
|
||||||
|
@ -915,20 +970,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
|
||||||
traceEvent(TRACE_DEBUG, "timeout");
|
traceEvent(TRACE_DEBUG, "timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
HASH_ITER(hh, sss->communities, comm, tmp)
|
purge_expired_communities(sss, &last_purge_edges, now);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user