From 78409df1c8e3a8408814d729015c78b40a20cbfb Mon Sep 17 00:00:00 2001 From: Logan007 Date: Tue, 18 Aug 2020 22:35:27 +0545 Subject: [PATCH 1/3] let auto ip feature handle several sub-networks --- community.list | 28 +++++++++++ include/n2n.h | 5 +- include/n2n_define.h | 3 +- include/pearson.h | 2 + src/pearson.c | 4 +- src/sn.c | 114 +++++++++++++++++++++++++++++++------------ src/sn_utils.c | 95 ++++++++++++++++++++++++++++++++---- 7 files changed, 208 insertions(+), 43 deletions(-) diff --git a/community.list b/community.list index 3674e3b..d8f3889 100644 --- a/community.list +++ b/community.list @@ -35,3 +35,31 @@ ntop[0-1][0-9] # '\d' Digits, [0-9] # '\D' Non-digits # +# fixed-name communities can optionally be followed by a network using the +# network/bitlen syntax such as the following line +# +home 192.168.1.0/24 +# +# the supernode draws ip addresses to assign to the edges (if they omit the `-a` +# parameter) from this network. note that the network is delimited by [SPACE] so +# community names cannot contain a [SPACE] either. +# +# if no network is provided here, the supernode assigns some other network to each +# community. networks are taken from the default range 10.128.0.0 - 10.255.255.0/24 +# as long as no other network rane is provided through the supernode's command line +# option `-d`. those sub-networks are distinct so several edges with different +# communities can be used at the same computer (being served ip addresses from the +# same supernode). also, the networks described in this file are avoided. +# +# however, all networks assigned in this file are not checked for colliding ranges +# so different communities can use same or overlapping sub-networks. that does not +# impose a problem if the communities do not share edge nodes. +# +# there seems to be no sense in pre-assigning sub-networks to communities whose +# names are defined by regular expressions. those will be assigned a sub-network +# from the default range or the `-d` range. +# +# if `-a` is used with the edge, the edge uses the ip address specified with the +# `-a xxx.xxx.xxx.xxx` option. also, the enhanced syntax `-r -a dhcp:0.0.0.0` is +# still available to serve more professional needs by a dhcp server. +# diff --git a/include/n2n.h b/include/n2n.h index 337616c..84e5abe 100644 --- a/include/n2n.h +++ b/include/n2n.h @@ -370,6 +370,7 @@ struct sn_community he_context_t *header_iv_ctx; /* Header IV ecnryption cipher context, REMOVE as soon as seperate fields for checksum and replay protection available */ struct peer_info *edges; /* Link list of registered edges. */ int64_t number_enc_packets; /* Number of encrypted packets handled so far, required for sorting from time to time */ + n2n_ip_subnet_t dhcp_net; /* Address range of dhcp service. */ UT_hash_handle hh; /* makes this structure hashable */ }; @@ -390,7 +391,8 @@ typedef struct n2n_sn uint16_t mport; /* Management UDP port to bind to. */ int sock; /* Main socket for UDP traffic with edges. */ int mgmt_sock; /* management socket. */ - n2n_ip_subnet_t dhcp_addr; /* Address range of dhcp service. */ + n2n_ip_subnet_t min_dhcp_net; /* Address range of dhcp service. */ + n2n_ip_subnet_t max_dhcp_net; /* Address range of dhcp service. */ #ifndef WIN32 uid_t userid; gid_t groupid; @@ -502,6 +504,7 @@ int quick_edge_init(char *device_name, char *community_name, int sn_init(n2n_sn_t *sss); void sn_term(n2n_sn_t *sss); int run_sn_loop(n2n_sn_t *sss, int *keep_running); +int assign_one_ip_subnet(n2n_sn_t *sss, struct sn_community *comm); const char* compression_str(uint8_t cmpr); const char* transop_str(enum n2n_transform tr); diff --git a/include/n2n_define.h b/include/n2n_define.h index ca8e997..df2a413 100644 --- a/include/n2n_define.h +++ b/include/n2n_define.h @@ -102,7 +102,8 @@ #define TUNTAP_IP_MODE_DHCP 2 /* Default network segment of the dhcp service provided by sn. */ -#define N2N_SN_DHCP_NET_ADDR_DEFAULT "172.17.12.0" +#define N2N_SN_MIN_DHCP_NET_DEFAULT "10.128.0.0" +#define N2N_SN_MAX_DHCP_NET_DEFAULT "10.255.255.0" #define N2N_SN_DHCP_NET_BIT_DEFAULT 24 /* ************************************** */ diff --git a/include/pearson.h b/include/pearson.h index 24e51fe..a5ebb45 100644 --- a/include/pearson.h +++ b/include/pearson.h @@ -20,6 +20,8 @@ void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len); void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len); +uint32_t pearson_hash_32 (const uint8_t *in, size_t len); + uint16_t pearson_hash_16 (const uint8_t *in, size_t len); void pearson_hash_init(); diff --git a/src/pearson.c b/src/pearson.c index a515b52..0844ddf 100644 --- a/src/pearson.c +++ b/src/pearson.c @@ -270,7 +270,7 @@ void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len) { *o = lower_hash; } -/* --- for later use --- + // 32-bit hash: the return value has to be interpreted as uint32_t and // follows machine-specific endianess in memory uint32_t pearson_hash_32 (const uint8_t *in, size_t len) { @@ -300,7 +300,7 @@ uint32_t pearson_hash_32 (const uint8_t *in, size_t len) { } // output return hash; -} --- pearson_hash_32 for later use --- */ +} // 16-bit hash: the return value has to be interpreted as uint16_t and diff --git a/src/sn.c b/src/sn.c index 59c8eb7..cbf613c 100644 --- a/src/sn.c +++ b/src/sn.c @@ -27,12 +27,17 @@ static n2n_sn_t sss_node; * */ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) { - char buffer[4096], *line; + char buffer[4096], *line, *cmn_str, net_str[20]; + dec_ip_str_t ip_str = {'\0'}; + uint8_t bitlen; + in_addr_t net; + uint32_t mask; FILE *fd = fopen(path, "r"); struct sn_community *s, *tmp; uint32_t num_communities = 0; struct sn_community_regular_expression *re, *tmp_re; uint32_t num_regex = 0; + int has_net; if(fd == NULL) { traceEvent(TRACE_WARNING, "File %s not found", path); @@ -66,15 +71,20 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) { break; } + // cut off any IP sub-network upfront + cmn_str = (char*)calloc(len+1, sizeof(char)); + has_net = ( sscanf (line, "%s %s", cmn_str, net_str) == 2 ); + // if it contains typical characters... - if(NULL != strpbrk(line, ".^$*+?[]\\")) { + if(NULL != strpbrk(cmn_str, ".^$*+?[]\\")) { // ...it is treated as regular expression re = (struct sn_community_regular_expression*)calloc(1,sizeof(struct sn_community_regular_expression)); if (re) { - re->rule = re_compile(line); + re->rule = re_compile(cmn_str); HASH_ADD_PTR(sss->rules, rule, re); num_regex++; - traceEvent(TRACE_INFO, "Added regular expression for allowed communities '%s'", line); + traceEvent(TRACE_INFO, "Added regular expression for allowed communities '%s'", cmn_str); + free(cmn_str); continue; } } @@ -82,7 +92,7 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) { s = (struct sn_community*)calloc(1,sizeof(struct sn_community)); if(s != NULL) { - strncpy((char*)s->community, line, N2N_COMMUNITY_SIZE-1); + strncpy((char*)s->community, cmn_str, N2N_COMMUNITY_SIZE-1); s->community[N2N_COMMUNITY_SIZE-1] = '\0'; /* loaded from file, this community is unpurgeable */ s->purgeable = COMMUNITY_UNPURGEABLE; @@ -95,7 +105,42 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) { num_communities++; traceEvent(TRACE_INFO, "Added allowed community '%s' [total: %u]", (char*)s->community, num_communities); + + // check for sub-network address + if(has_net) { + if(sscanf(net_str, "%15[^/]/%hhu", ip_str, &bitlen) != 2) { + traceEvent(TRACE_WARNING, "Bad net/bit format '%s' for community '%c', ignoring. See comments inside community.list file.", + net_str, cmn_str); + has_net = 0; + } + net = inet_addr(ip_str); + mask = bitlen2mask(bitlen); + if((net == (in_addr_t)(-1)) || (net == INADDR_NONE) || (net == INADDR_ANY) + || ((ntohl(net) & ~mask) != 0) ) { + traceEvent(TRACE_WARNING, "Bad network '%s/%u' in '%s' for community '%s', ignoring.", + ip_str, bitlen, net_str, cmn_str); + has_net = 0; + } + if ((bitlen > 30) || (bitlen == 0)) { + traceEvent(TRACE_WARNING, "Bad prefix '%hhu' in '%s' for community '%s', ignoring.", + bitlen, net_str, cmn_str); + has_net = 0; + } + } + if(has_net) { + s->dhcp_net.net_addr = ntohl(net); + s->dhcp_net.net_bitlen = bitlen; + traceEvent(TRACE_INFO, "Assigned sub-network %s/%u to community '%s'.", + inet_ntoa(*(struct in_addr *) &net), + s->dhcp_net.net_bitlen, + s->community); + } else { + assign_one_ip_subnet(sss, s); + } } + + free(cmn_str); + } fclose(fd); @@ -138,23 +183,23 @@ static void help() { printf("[-u -g ] "); #endif /* ifndef WIN32 */ printf("[-t ] "); - printf("[-d ] "); + printf("[-d ] "); printf("[-v] "); printf("\n\n"); - printf("-l | Set UDP main listen port to \n"); - printf("-c | File containing the allowed communities.\n"); + printf("-l | Set UDP main listen port to \n"); + printf("-c | File containing the allowed communities.\n"); #if defined(N2N_HAVE_DAEMON) - printf("-f | Run in foreground.\n"); + printf("-f | Run in foreground.\n"); #endif /* #if defined(N2N_HAVE_DAEMON) */ #ifndef WIN32 - printf("-u | User ID (numeric) to use when privileges are dropped.\n"); - printf("-g | Group ID (numeric) to use when privileges are dropped.\n"); + printf("-u | User ID (numeric) to use when privileges are dropped.\n"); + printf("-g | Group ID (numeric) to use when privileges are dropped.\n"); #endif /* ifndef WIN32 */ - printf("-t | Management UDP Port (for multiple supernodes on a machine).\n"); - printf("-d | Subnet that provides dhcp service for edge. eg. -d 172.17.12.0/24\n"); - printf("-v | Increase verbosity. Can be used multiple times.\n"); - printf("-h | This help message.\n"); + printf("-t | Management UDP Port (for multiple supernodes on a machine).\n"); + printf("-d | Subnet range for community ip address service for edges. eg. -d 10.128.255.0-10.255.255.0/24\n"); + printf("-v | Increase verbosity. Can be used multiple times.\n"); + printf("-h | This help message.\n"); printf("\n"); exit(1); @@ -175,34 +220,43 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { break; case 'd': { - dec_ip_str_t ip_str = {'\0'}; - in_addr_t net; + dec_ip_str_t ip_min_str = {'\0'}; + dec_ip_str_t ip_max_str = {'\0'}; + in_addr_t net_min, net_max; uint8_t bitlen; + uint32_t mask; - if (sscanf(_optarg, "%15[^/]/%hhu", ip_str, &bitlen) != 2) { - traceEvent(TRACE_WARNING, "Bad net/bit format '%s'. See -h.", _optarg); + if (sscanf(_optarg, "%15[^\\-]-%15[^/]/%hhu", ip_min_str, ip_max_str, &bitlen) != 3) { + traceEvent(TRACE_WARNING, "Bad net-net/bit format '%s'. See -h.", _optarg); break; } - net = inet_addr(ip_str); - if ((net == (in_addr_t)(-1)) || (net == INADDR_NONE) || (net == INADDR_ANY)) { - traceEvent(TRACE_WARNING, "Bad network '%s' in '%s', Use default: '%s/%d'", - ip_str, _optarg, - N2N_SN_DHCP_NET_ADDR_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT); + net_min = inet_addr(ip_min_str); + net_max = inet_addr(ip_max_str); + mask = bitlen2mask(bitlen); + if ((net_min == (in_addr_t)(-1)) || (net_min == INADDR_NONE) || (net_min == INADDR_ANY) + || (net_max == (in_addr_t)(-1)) || (net_max == INADDR_NONE) || (net_max == INADDR_ANY) + || (ntohl(net_min) > ntohl(net_max)) + || ((ntohl(net_min) & ~mask) != 0) || ((ntohl(net_max) & ~mask) != 0) ) { + traceEvent(TRACE_WARNING, "Bad network range '%s...%s/%u' in '%s', defaulting to '%s...%s/%d'", + ip_min_str, ip_max_str, bitlen, _optarg, + N2N_SN_MIN_DHCP_NET_DEFAULT, N2N_SN_MAX_DHCP_NET_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT); break; } - if (bitlen > 32) { - traceEvent(TRACE_WARNING, "Bad prefix '%hhu' in '%s', Use default: '%s/%d'", + if ((bitlen > 30) || (bitlen == 0)) { + traceEvent(TRACE_WARNING, "Bad prefix '%hhu' in '%s', defaulting to '%s...%s/%d'", bitlen, _optarg, - N2N_SN_DHCP_NET_ADDR_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT); + N2N_SN_MIN_DHCP_NET_DEFAULT, N2N_SN_MAX_DHCP_NET_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT); break; } - traceEvent(TRACE_NORMAL, "The subnet of DHCP service is: '%s/%hhu'.", ip_str, bitlen); + traceEvent(TRACE_NORMAL, "The network range for community ip address service is '%s...%s/%hhu'.", ip_min_str, ip_max_str, bitlen); - sss->dhcp_addr.net_addr = ntohl(net); - sss->dhcp_addr.net_bitlen = bitlen; + sss->min_dhcp_net.net_addr = ntohl(net_min); + sss->min_dhcp_net.net_bitlen = bitlen; + sss->max_dhcp_net.net_addr = ntohl(net_max); + sss->max_dhcp_net.net_bitlen = bitlen; break; } diff --git a/src/sn_utils.c b/src/sn_utils.c index 08be497..1f6c7dd 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -218,9 +218,12 @@ int sn_init(n2n_sn_t *sss) { sss->mport = N2N_SN_MGMT_PORT; sss->sock = -1; sss->mgmt_sock = -1; - sss->dhcp_addr.net_addr = inet_addr(N2N_SN_DHCP_NET_ADDR_DEFAULT); - sss->dhcp_addr.net_addr = ntohl(sss->dhcp_addr.net_addr); - sss->dhcp_addr.net_bitlen = N2N_SN_DHCP_NET_BIT_DEFAULT; + sss->min_dhcp_net.net_addr = inet_addr(N2N_SN_MIN_DHCP_NET_DEFAULT); + sss->min_dhcp_net.net_addr = ntohl(sss->min_dhcp_net.net_addr); + sss->min_dhcp_net.net_bitlen = N2N_SN_DHCP_NET_BIT_DEFAULT; + sss->max_dhcp_net.net_addr = inet_addr(N2N_SN_MAX_DHCP_NET_DEFAULT); + sss->max_dhcp_net.net_addr = ntohl(sss->max_dhcp_net.net_addr); + sss->max_dhcp_net.net_bitlen = N2N_SN_DHCP_NET_BIT_DEFAULT; return 0; /* OK */ } @@ -335,15 +338,14 @@ static signed int peer_tap_ip_sort(struct peer_info *a, struct peer_info *b) { /** The IP address assigned to the edge by the DHCP function of sn. */ -static int assign_one_ip_addr(n2n_sn_t *sss, - struct sn_community *comm, +static int assign_one_ip_addr(struct sn_community *comm, n2n_ip_subnet_t *ipaddr) { struct peer_info *peer, *tmpPeer; uint32_t net_id, mask, max_host, host_id = 1; dec_ip_bit_str_t ip_bit_str = {'\0'}; - mask = bitlen2mask(sss->dhcp_addr.net_bitlen); - net_id = sss->dhcp_addr.net_addr & mask; + mask = bitlen2mask(comm->dhcp_net.net_bitlen); + net_id = comm->dhcp_net.net_addr & mask; max_host = ~mask; HASH_SORT(comm->edges, peer_tap_ip_sort); @@ -364,13 +366,87 @@ static int assign_one_ip_addr(n2n_sn_t *sss, } } ipaddr->net_addr = net_id | host_id; - ipaddr->net_bitlen = sss->dhcp_addr.net_bitlen; + ipaddr->net_bitlen = comm->dhcp_net.net_bitlen; traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr)); return 0; } +/** checks if a certain sub-network is still available, i.e. does not cut any other community's sub-network */ +int subnet_available(n2n_sn_t *sss, + struct sn_community *comm, + uint32_t net_id, + uint32_t mask) { + + struct sn_community *cmn, *tmpCmn; + int success = 1; + + HASH_ITER(hh, sss->communities, cmn, tmpCmn) { + if (cmn == comm) continue; + if( (net_id <= (cmn->dhcp_net.net_addr + ~bitlen2mask(cmn->dhcp_net.net_bitlen))) + &&(net_id + ~mask >= cmn->dhcp_net.net_addr) ) { + success = 0; + break; + } + } + + return success; +} + + +/** The IP address assigned to the edge by the DHCP function of sn. */ +int assign_one_ip_subnet(n2n_sn_t *sss, + struct sn_community *comm) { + + uint32_t net_id, net_id_i, mask, net_increment; + uint32_t no_subnets; + uint8_t success; + in_addr_t net; + + mask = bitlen2mask(sss->min_dhcp_net.net_bitlen); + // number of possible sub-networks + no_subnets = (sss->max_dhcp_net.net_addr - sss->min_dhcp_net.net_addr); + no_subnets >>= (32 - sss->min_dhcp_net.net_bitlen); + no_subnets += 1; + + // proposal for sub-network to choose + net_id = pearson_hash_32(comm->community, N2N_COMMUNITY_SIZE) % no_subnets; + net_id = sss->min_dhcp_net.net_addr + (net_id << (32 - sss->min_dhcp_net.net_bitlen)); + + // check for availability starting from net_id, then downwards, ... + net_increment = (~mask+1); + for(net_id_i=net_id; net_id_i >= sss->min_dhcp_net.net_addr; net_id_i -= net_increment) { + success = subnet_available(sss, comm, net_id_i, mask); + if(success) break; + } + // ... then upwards + if(!success) { + for(net_id_i=net_id + net_increment; net_id_i <= sss->max_dhcp_net.net_addr; net_id_i += net_increment) { + success = subnet_available(sss, comm, net_id_i, mask); + if(success) break; + } + } + + if(success) { + comm->dhcp_net.net_addr = net_id_i; + comm->dhcp_net.net_bitlen = sss->min_dhcp_net.net_bitlen; + net = htonl(comm->dhcp_net.net_addr); + traceEvent(TRACE_INFO, "Assigned sub-network %s/%u to community '%s'.", + inet_ntoa(*(struct in_addr *) &net), + comm->dhcp_net.net_bitlen, + comm->community); + return 0; + } else { + comm->dhcp_net.net_addr = 0; + comm->dhcp_net.net_bitlen = 0; + traceEvent(TRACE_WARNING, "No assignable sub-network left for community '%s'.", + comm->community); + return -1; + } +} + + /*** * * For a given packet, find the apporopriate internal last valid time stamp for lookup @@ -905,6 +981,7 @@ static int process_udp(n2n_sn_t * sss, HASH_ADD_STR(sss->communities, community, comm); traceEvent(TRACE_INFO, "New community: %s", comm->community); + assign_one_ip_subnet(sss, comm); } } @@ -918,7 +995,7 @@ static int process_udp(n2n_sn_t * sss, memcpy(ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t)); if ((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) || ((reg.dev_addr.net_addr & 0xFFFF0000) == 0xA9FE0000 /* 169.254.0.0 */)) { - assign_one_ip_addr(sss, comm, &ipaddr); + assign_one_ip_addr(comm, &ipaddr); ack.dev_addr.net_addr = ipaddr.net_addr; ack.dev_addr.net_bitlen = ipaddr.net_bitlen; } From f57bb94fa57378985c1b040aa4ada3f2ba49a0dc Mon Sep 17 00:00:00 2001 From: Logan007 Date: Tue, 18 Aug 2020 23:27:03 +0545 Subject: [PATCH 2/3] let auto ip feature handle several sub-networks --- community.list | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/community.list b/community.list index d8f3889..181e015 100644 --- a/community.list +++ b/community.list @@ -38,28 +38,28 @@ ntop[0-1][0-9] # fixed-name communities can optionally be followed by a network using the # network/bitlen syntax such as the following line # -home 192.168.1.0/24 +home 192.168.168.0/24 # # the supernode draws ip addresses to assign to the edges (if they omit the `-a` # parameter) from this network. note that the network is delimited by [SPACE] so -# community names cannot contain a [SPACE] either. +# community names cannot contain [SPACE] either. # # if no network is provided here, the supernode assigns some other network to each # community. networks are taken from the default range 10.128.0.0 - 10.255.255.0/24 -# as long as no other network rane is provided through the supernode's command line +# as long as no other network range is provided through the supernode's command line # option `-d`. those sub-networks are distinct so several edges with different # communities can be used at the same computer (being served ip addresses from the -# same supernode). also, the networks described in this file are avoided. +# same supernode). also, the sub-networks described in this file are avoided. # -# however, all networks assigned in this file are not checked for colliding ranges -# so different communities can use same or overlapping sub-networks. that does not -# impose a problem if the communities do not share edge nodes. +# however, all networks assigned in this file are not mutually checked for colliding +# ranges so different communities can use same or overlapping sub-networks. that does +# not impose a problem if the communities do not share edge nodes. # # there seems to be no sense in pre-assigning sub-networks to communities whose -# names are defined by regular expressions. those will be assigned a sub-network -# from the default range or the `-d` range. +# names are defined by regular expressions. those will be assigned distinct +# sub-networks from the default range or the `-d` range. # # if `-a` is used with the edge, the edge uses the ip address specified with the # `-a xxx.xxx.xxx.xxx` option. also, the enhanced syntax `-r -a dhcp:0.0.0.0` is -# still available to serve more professional needs by a dhcp server. +# still available to have more professional needs served by a full dhcp server. # From a35675da4d5615d657bbbae0db03f1f21046b057 Mon Sep 17 00:00:00 2001 From: Logan007 Date: Wed, 19 Aug 2020 14:46:58 +0545 Subject: [PATCH 3/3] internally renamed dhcp --> auto ip --- include/n2n.h | 6 +++--- include/n2n_define.h | 8 +++---- src/sn.c | 29 ++++++++++++------------- src/sn_utils.c | 50 ++++++++++++++++++++++---------------------- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/include/n2n.h b/include/n2n.h index 84e5abe..9fc2cdf 100644 --- a/include/n2n.h +++ b/include/n2n.h @@ -370,7 +370,7 @@ struct sn_community he_context_t *header_iv_ctx; /* Header IV ecnryption cipher context, REMOVE as soon as seperate fields for checksum and replay protection available */ struct peer_info *edges; /* Link list of registered edges. */ int64_t number_enc_packets; /* Number of encrypted packets handled so far, required for sorting from time to time */ - n2n_ip_subnet_t dhcp_net; /* Address range of dhcp service. */ + n2n_ip_subnet_t auto_ip_net; /* Address range of auto ip address service. */ UT_hash_handle hh; /* makes this structure hashable */ }; @@ -391,8 +391,8 @@ typedef struct n2n_sn uint16_t mport; /* Management UDP port to bind to. */ int sock; /* Main socket for UDP traffic with edges. */ int mgmt_sock; /* management socket. */ - n2n_ip_subnet_t min_dhcp_net; /* Address range of dhcp service. */ - n2n_ip_subnet_t max_dhcp_net; /* Address range of dhcp service. */ + n2n_ip_subnet_t min_auto_ip_net; /* Address range of auto_ip service. */ + n2n_ip_subnet_t max_auto_ip_net; /* Address range of auto_ip service. */ #ifndef WIN32 uid_t userid; gid_t groupid; diff --git a/include/n2n_define.h b/include/n2n_define.h index df2a413..b9933bd 100644 --- a/include/n2n_define.h +++ b/include/n2n_define.h @@ -101,10 +101,10 @@ #define TUNTAP_IP_MODE_STATIC 1 #define TUNTAP_IP_MODE_DHCP 2 -/* Default network segment of the dhcp service provided by sn. */ -#define N2N_SN_MIN_DHCP_NET_DEFAULT "10.128.0.0" -#define N2N_SN_MAX_DHCP_NET_DEFAULT "10.255.255.0" -#define N2N_SN_DHCP_NET_BIT_DEFAULT 24 +/* Default network segment of the auto ip address service provided by sn. */ +#define N2N_SN_MIN_AUTO_IP_NET_DEFAULT "10.128.0.0" +#define N2N_SN_MAX_AUTO_IP_NET_DEFAULT "10.255.255.0" +#define N2N_SN_AUTO_IP_NET_BIT_DEFAULT 24 /* ************************************** */ diff --git a/src/sn.c b/src/sn.c index cbf613c..2470e8f 100644 --- a/src/sn.c +++ b/src/sn.c @@ -128,11 +128,11 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) { } } if(has_net) { - s->dhcp_net.net_addr = ntohl(net); - s->dhcp_net.net_bitlen = bitlen; + s->auto_ip_net.net_addr = ntohl(net); + s->auto_ip_net.net_bitlen = bitlen; traceEvent(TRACE_INFO, "Assigned sub-network %s/%u to community '%s'.", inet_ntoa(*(struct in_addr *) &net), - s->dhcp_net.net_bitlen, + s->auto_ip_net.net_bitlen, s->community); } else { assign_one_ip_subnet(sss, s); @@ -183,7 +183,7 @@ static void help() { printf("[-u -g ] "); #endif /* ifndef WIN32 */ printf("[-t ] "); - printf("[-d ] "); + printf("[-a ] "); printf("[-v] "); printf("\n\n"); @@ -197,7 +197,8 @@ static void help() { printf("-g | Group ID (numeric) to use when privileges are dropped.\n"); #endif /* ifndef WIN32 */ printf("-t | Management UDP Port (for multiple supernodes on a machine).\n"); - printf("-d | Subnet range for community ip address service for edges. eg. -d 10.128.255.0-10.255.255.0/24\n"); + printf("-a | Subnet range for auto ip address service, e.g.\n"); + printf(" | -a 192.168.0.0-192.168.255.0/24, defaults to 10.128.255.0-10.255.255.0/24\n"); printf("-v | Increase verbosity. Can be used multiple times.\n"); printf("-h | This help message.\n"); printf("\n"); @@ -219,7 +220,7 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { sss->mport = atoi(_optarg); break; - case 'd': { + case 'a': { dec_ip_str_t ip_min_str = {'\0'}; dec_ip_str_t ip_max_str = {'\0'}; in_addr_t net_min, net_max; @@ -240,23 +241,23 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { || ((ntohl(net_min) & ~mask) != 0) || ((ntohl(net_max) & ~mask) != 0) ) { traceEvent(TRACE_WARNING, "Bad network range '%s...%s/%u' in '%s', defaulting to '%s...%s/%d'", ip_min_str, ip_max_str, bitlen, _optarg, - N2N_SN_MIN_DHCP_NET_DEFAULT, N2N_SN_MAX_DHCP_NET_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT); + N2N_SN_MIN_AUTO_IP_NET_DEFAULT, N2N_SN_MAX_AUTO_IP_NET_DEFAULT, N2N_SN_AUTO_IP_NET_BIT_DEFAULT); break; } if ((bitlen > 30) || (bitlen == 0)) { traceEvent(TRACE_WARNING, "Bad prefix '%hhu' in '%s', defaulting to '%s...%s/%d'", bitlen, _optarg, - N2N_SN_MIN_DHCP_NET_DEFAULT, N2N_SN_MAX_DHCP_NET_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT); + N2N_SN_MIN_AUTO_IP_NET_DEFAULT, N2N_SN_MAX_AUTO_IP_NET_DEFAULT, N2N_SN_AUTO_IP_NET_BIT_DEFAULT); break; } traceEvent(TRACE_NORMAL, "The network range for community ip address service is '%s...%s/%hhu'.", ip_min_str, ip_max_str, bitlen); - sss->min_dhcp_net.net_addr = ntohl(net_min); - sss->min_dhcp_net.net_bitlen = bitlen; - sss->max_dhcp_net.net_addr = ntohl(net_max); - sss->max_dhcp_net.net_bitlen = bitlen; + sss->min_auto_ip_net.net_addr = ntohl(net_min); + sss->min_auto_ip_net.net_bitlen = bitlen; + sss->max_auto_ip_net.net_addr = ntohl(net_max); + sss->max_auto_ip_net.net_bitlen = bitlen; break; } @@ -303,7 +304,7 @@ static const struct option long_options[] = { {"foreground", no_argument, NULL, 'f'}, {"local-port", required_argument, NULL, 'l'}, {"mgmt-port", required_argument, NULL, 't'}, - {"dhcp", required_argument, NULL, 'd'}, + {"autoip", required_argument, NULL, 'a'}, {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} @@ -315,7 +316,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:u:g:t:d:c:vh", + while((c = getopt_long(argc, argv, "fl:u:g:t:a:c:vh", long_options, NULL)) != '?') { if(c == 255) break; setOption(c, optarg, sss); diff --git a/src/sn_utils.c b/src/sn_utils.c index 1f6c7dd..ebc90f7 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -218,12 +218,12 @@ int sn_init(n2n_sn_t *sss) { sss->mport = N2N_SN_MGMT_PORT; sss->sock = -1; sss->mgmt_sock = -1; - sss->min_dhcp_net.net_addr = inet_addr(N2N_SN_MIN_DHCP_NET_DEFAULT); - sss->min_dhcp_net.net_addr = ntohl(sss->min_dhcp_net.net_addr); - sss->min_dhcp_net.net_bitlen = N2N_SN_DHCP_NET_BIT_DEFAULT; - sss->max_dhcp_net.net_addr = inet_addr(N2N_SN_MAX_DHCP_NET_DEFAULT); - sss->max_dhcp_net.net_addr = ntohl(sss->max_dhcp_net.net_addr); - sss->max_dhcp_net.net_bitlen = N2N_SN_DHCP_NET_BIT_DEFAULT; + sss->min_auto_ip_net.net_addr = inet_addr(N2N_SN_MIN_AUTO_IP_NET_DEFAULT); + sss->min_auto_ip_net.net_addr = ntohl(sss->min_auto_ip_net.net_addr); + sss->min_auto_ip_net.net_bitlen = N2N_SN_AUTO_IP_NET_BIT_DEFAULT; + sss->max_auto_ip_net.net_addr = inet_addr(N2N_SN_MAX_AUTO_IP_NET_DEFAULT); + sss->max_auto_ip_net.net_addr = ntohl(sss->max_auto_ip_net.net_addr); + sss->max_auto_ip_net.net_bitlen = N2N_SN_AUTO_IP_NET_BIT_DEFAULT; return 0; /* OK */ } @@ -337,15 +337,15 @@ static signed int peer_tap_ip_sort(struct peer_info *a, struct peer_info *b) { } -/** The IP address assigned to the edge by the DHCP function of sn. */ +/** The IP address assigned to the edge by the auto ip address function of sn. */ static int assign_one_ip_addr(struct sn_community *comm, n2n_ip_subnet_t *ipaddr) { struct peer_info *peer, *tmpPeer; uint32_t net_id, mask, max_host, host_id = 1; dec_ip_bit_str_t ip_bit_str = {'\0'}; - mask = bitlen2mask(comm->dhcp_net.net_bitlen); - net_id = comm->dhcp_net.net_addr & mask; + mask = bitlen2mask(comm->auto_ip_net.net_bitlen); + net_id = comm->auto_ip_net.net_addr & mask; max_host = ~mask; HASH_SORT(comm->edges, peer_tap_ip_sort); @@ -366,7 +366,7 @@ static int assign_one_ip_addr(struct sn_community *comm, } } ipaddr->net_addr = net_id | host_id; - ipaddr->net_bitlen = comm->dhcp_net.net_bitlen; + ipaddr->net_bitlen = comm->auto_ip_net.net_bitlen; traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr)); return 0; @@ -384,8 +384,8 @@ int subnet_available(n2n_sn_t *sss, HASH_ITER(hh, sss->communities, cmn, tmpCmn) { if (cmn == comm) continue; - if( (net_id <= (cmn->dhcp_net.net_addr + ~bitlen2mask(cmn->dhcp_net.net_bitlen))) - &&(net_id + ~mask >= cmn->dhcp_net.net_addr) ) { + if( (net_id <= (cmn->auto_ip_net.net_addr + ~bitlen2mask(cmn->auto_ip_net.net_bitlen))) + &&(net_id + ~mask >= cmn->auto_ip_net.net_addr) ) { success = 0; break; } @@ -395,7 +395,7 @@ int subnet_available(n2n_sn_t *sss, } -/** The IP address assigned to the edge by the DHCP function of sn. */ +/** The IP address range (subnet) assigned to the community by the auto ip address function of sn. */ int assign_one_ip_subnet(n2n_sn_t *sss, struct sn_community *comm) { @@ -404,42 +404,42 @@ int assign_one_ip_subnet(n2n_sn_t *sss, uint8_t success; in_addr_t net; - mask = bitlen2mask(sss->min_dhcp_net.net_bitlen); + mask = bitlen2mask(sss->min_auto_ip_net.net_bitlen); // number of possible sub-networks - no_subnets = (sss->max_dhcp_net.net_addr - sss->min_dhcp_net.net_addr); - no_subnets >>= (32 - sss->min_dhcp_net.net_bitlen); + no_subnets = (sss->max_auto_ip_net.net_addr - sss->min_auto_ip_net.net_addr); + no_subnets >>= (32 - sss->min_auto_ip_net.net_bitlen); no_subnets += 1; // proposal for sub-network to choose net_id = pearson_hash_32(comm->community, N2N_COMMUNITY_SIZE) % no_subnets; - net_id = sss->min_dhcp_net.net_addr + (net_id << (32 - sss->min_dhcp_net.net_bitlen)); + net_id = sss->min_auto_ip_net.net_addr + (net_id << (32 - sss->min_auto_ip_net.net_bitlen)); // check for availability starting from net_id, then downwards, ... net_increment = (~mask+1); - for(net_id_i=net_id; net_id_i >= sss->min_dhcp_net.net_addr; net_id_i -= net_increment) { + for(net_id_i=net_id; net_id_i >= sss->min_auto_ip_net.net_addr; net_id_i -= net_increment) { success = subnet_available(sss, comm, net_id_i, mask); if(success) break; } // ... then upwards if(!success) { - for(net_id_i=net_id + net_increment; net_id_i <= sss->max_dhcp_net.net_addr; net_id_i += net_increment) { + for(net_id_i=net_id + net_increment; net_id_i <= sss->max_auto_ip_net.net_addr; net_id_i += net_increment) { success = subnet_available(sss, comm, net_id_i, mask); if(success) break; } } if(success) { - comm->dhcp_net.net_addr = net_id_i; - comm->dhcp_net.net_bitlen = sss->min_dhcp_net.net_bitlen; - net = htonl(comm->dhcp_net.net_addr); + comm->auto_ip_net.net_addr = net_id_i; + comm->auto_ip_net.net_bitlen = sss->min_auto_ip_net.net_bitlen; + net = htonl(comm->auto_ip_net.net_addr); traceEvent(TRACE_INFO, "Assigned sub-network %s/%u to community '%s'.", inet_ntoa(*(struct in_addr *) &net), - comm->dhcp_net.net_bitlen, + comm->auto_ip_net.net_bitlen, comm->community); return 0; } else { - comm->dhcp_net.net_addr = 0; - comm->dhcp_net.net_bitlen = 0; + comm->auto_ip_net.net_addr = 0; + comm->auto_ip_net.net_bitlen = 0; traceEvent(TRACE_WARNING, "No assignable sub-network left for community '%s'.", comm->community); return -1;