Browse Source

backported supernode selection by MAC address to 3.0 as it also fixes a rarely occuring bug found in general supernode selection

pull/899/head
Logan oos Even 3 years ago
parent
commit
0177e14026
  1. 4
      edge.8
  2. 2
      include/n2n_typedefs.h
  3. 16
      src/edge.c
  4. 37
      src/sn_selection.c

4
edge.8

@ -105,6 +105,10 @@ compress outgoing data packets, -z1 = lzo1x, disabled by default
\fB\-\-select-rtt\fR \fB\-\-select-rtt\fR
select supernode by round trip time if several to choose from (federation), select supernode by round trip time if several to choose from (federation),
defaults to load-based selection strategy if not provided. defaults to load-based selection strategy if not provided.
.TP
\fB\-\-select-mac\fR
select supernode by MAC address if several to choose from (federation),
lowest MAC address first.
.SH TAP DEVICE AND OVERLAY NETWORK CONFIGURATION .SH TAP DEVICE AND OVERLAY NETWORK CONFIGURATION
.TP .TP
\fB\-a \fR[\fImode\fR]<\fIip\fR>[\fI/n\fR] \fB\-a \fR[\fImode\fR]<\fIip\fR>[\fI/n\fR]

2
include/n2n_typedefs.h

@ -288,7 +288,7 @@ typedef char n2n_version_t[N2N_VERSION_STRING_SIZE];
#define SN_SELECTION_STRATEGY_LOAD 1 #define SN_SELECTION_STRATEGY_LOAD 1
#define SN_SELECTION_STRATEGY_RTT 2 #define SN_SELECTION_STRATEGY_RTT 2
#define SN_SELECTION_STRATEGY_MAC 3 /* REVISIT: not implemented yet */ #define SN_SELECTION_STRATEGY_MAC 3
typedef struct n2n_ip_subnet { typedef struct n2n_ip_subnet {

16
src/edge.c

@ -232,6 +232,7 @@ static void help (int level) {
"\n [-r] enable packet forwarding through n2n community" "\n [-r] enable packet forwarding through n2n community"
"\n [-E] accept multicast MAC addresses" "\n [-E] accept multicast MAC addresses"
"\n [--select-rtt] select supernode by round trip time" "\n [--select-rtt] select supernode by round trip time"
"\n [--select-mac] select supernode by MAC address"
#ifndef WIN32 #ifndef WIN32
"\n [-f] do not fork but run in foreground" "\n [-f] do not fork but run in foreground"
#endif #endif
@ -290,7 +291,8 @@ static void help (int level) {
"-z2 = zstd, " "-z2 = zstd, "
#endif #endif
"disabled by default\n"); "disabled by default\n");
printf("--select-rtt | supernode selection based on round trip time (default:\n" printf("--select-rtt | supernode selection based on round trip time\n"
"--select-mac | supernode selection based on MAC address (default:\n"
" | by load)\n"); " | by load)\n");
printf ("\n"); printf ("\n");
@ -737,7 +739,14 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e
break; break;
} }
case ']': /* password for management port */ { case ']': /* mac-address-based supernode selection strategy */ {
// overwrites the default load-based strategy
conf->sn_selection_strategy = SN_SELECTION_STRATEGY_MAC;
break;
}
case '{': /* password for management port */ {
conf->mgmt_password_hash = pearson_hash_64((uint8_t*)optargument, strlen(optargument)); conf->mgmt_password_hash = pearson_hash_64((uint8_t*)optargument, strlen(optargument));
break; break;
@ -797,7 +806,8 @@ static const struct option long_options[] =
{ "verbose", no_argument, NULL, 'v' }, { "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, '@' }, /* internal special character '@' to identify long help case */ { "help", no_argument, NULL, '@' }, /* internal special character '@' to identify long help case */
{ "select-rtt", no_argument, NULL, '[' }, /* '[' rtt selection strategy */ { "select-rtt", no_argument, NULL, '[' }, /* '[' rtt selection strategy */
{ "management-password", required_argument, NULL, ']' }, /* ']' management port password */ { "select-mac", no_argument, NULL, ']' }, /* ']' mac selection strategy */
{ "management-password", required_argument, NULL, '{' }, /* '{' management port password */
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };

37
src/sn_selection.c

@ -88,7 +88,17 @@ int sn_selection_criterion_calculate (n2n_edge_t *eee, peer_info_t *peer, SN_SEL
} }
case SN_SELECTION_STRATEGY_RTT: { case SN_SELECTION_STRATEGY_RTT: {
peer->selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE)(time_stamp() >> 22) - common_data; peer->selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE)((uint32_t)time_stamp() >> 22) - common_data;
break;
}
case SN_SELECTION_STRATEGY_MAC: {
peer->selection_criterion = 0;
memcpy(&peer->selection_criterion, /* leftbound, don't mess with pointer arithmetics */
peer->mac_addr,
N2N_MAC_SIZE);
peer->selection_criterion = be64toh(peer->selection_criterion);
peer->selection_criterion >>= (sizeof(peer->selection_criterion) - N2N_MAC_SIZE) * 8; /* rightbound */
break; break;
} }
@ -120,7 +130,12 @@ int sn_selection_criterion_common_data_default (n2n_edge_t *eee) {
} }
case SN_SELECTION_STRATEGY_RTT: { case SN_SELECTION_STRATEGY_RTT: {
eee->sn_selection_criterion_common_data = (SN_SELECTION_CRITERION_DATA_TYPE)(time_stamp() >> 22); eee->sn_selection_criterion_common_data = (SN_SELECTION_CRITERION_DATA_TYPE)((uint32_t)time_stamp() >> 22);
break;
}
case SN_SELECTION_STRATEGY_MAC: {
eee->sn_selection_criterion_common_data = 0;
break; break;
} }
@ -145,8 +160,15 @@ static SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_common_read (n2n_
/* Function that compare two selection_criterion fields and sorts them in ascending order. */ /* Function that compare two selection_criterion fields and sorts them in ascending order. */
static int sn_selection_criterion_sort (peer_info_t *a, peer_info_t *b) { static int sn_selection_criterion_sort (peer_info_t *a, peer_info_t *b) {
int ret = 0;
// comparison function for sorting supernodes in ascending order of their selection_criterion. // comparison function for sorting supernodes in ascending order of their selection_criterion.
return (a->selection_criterion - b->selection_criterion); if(a->selection_criterion > b->selection_criterion)
ret = 1;
else if(a->selection_criterion < b->selection_criterion)
ret = -2;
return ret;
} }
@ -177,7 +199,7 @@ SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_gather_data (n2n_sn_t *s
data += tmp; data += tmp;
} }
return htobe32(data); return htobe64(data);
} }
@ -195,7 +217,7 @@ extern char * sn_selection_criterion_str (n2n_edge_t *eee, selection_criterion_s
// keep off the super-big values (used for "bad" or "good" or "undetermined" supernodes, // keep off the super-big values (used for "bad" or "good" or "undetermined" supernodes,
// easier to sort to the end of the list). // easier to sort to the end of the list).
// Alternatively, typecast to (int16_t) and check for greater or equal zero // Alternatively, typecast to (int16_t) and check for greater or equal zero
if(peer->selection_criterion < (UINT32_MAX >> 2)) { if(peer->selection_criterion < (UINT64_MAX >> 2)) {
switch(eee->conf.sn_selection_strategy) { switch(eee->conf.sn_selection_strategy) {
@ -209,6 +231,11 @@ extern char * sn_selection_criterion_str (n2n_edge_t *eee, selection_criterion_s
break; break;
} }
case SN_SELECTION_STRATEGY_MAC: {
chars = snprintf(out, SN_SELECTION_CRITERION_BUF_SIZE, "%s", (int64_t)peer->selection_criterion > 0 ? "active" : "");
break;
}
default: { default: {
// this should never happen // this should never happen
traceEvent(TRACE_ERROR, "selection_criterion unknown selection strategy configuration"); traceEvent(TRACE_ERROR, "selection_criterion unknown selection strategy configuration");

Loading…
Cancel
Save