From ed25ff8d010926f3a4638c77bff294bd4698ee05 Mon Sep 17 00:00:00 2001 From: Francesco Carli <62562180+fcarli3@users.noreply.github.com> Date: Sun, 11 Oct 2020 21:54:06 +0200 Subject: [PATCH] Fixes minor issues introduced by #460 (#461) --- include/n2n.h | 1 + include/n2n_define.h | 7 ++-- include/n2n_wire.h | 6 ++-- src/edge_utils.c | 83 ++++---------------------------------------- src/n2n.c | 70 +++++++++++++++++++++++++++++++++++-- src/sn.c | 11 ++---- src/sn_utils.c | 6 ++-- src/wire.c | 24 ++++--------- 8 files changed, 95 insertions(+), 113 deletions(-) diff --git a/include/n2n.h b/include/n2n.h index ddf3008..3889588 100644 --- a/include/n2n.h +++ b/include/n2n.h @@ -500,6 +500,7 @@ int quick_edge_init(char *device_name, char *community_name, int comm_init(struct sn_community *comm, char *cmn); int sn_init(n2n_sn_t *sss); void sn_term(n2n_sn_t *sss); +int supernode2sock(n2n_sock_t * sn, const n2n_sn_name_t addrIn); struct peer_info* add_sn_to_federation_by_mac_or_sock(n2n_sn_t *sss, n2n_sock_t *sock, n2n_mac_t *mac); int run_sn_loop(n2n_sn_t *sss, int *keep_running); int assign_one_ip_subnet(n2n_sn_t *sss, struct sn_community *comm); diff --git a/include/n2n_define.h b/include/n2n_define.h index 19a4ed2..4228c2e 100644 --- a/include/n2n_define.h +++ b/include/n2n_define.h @@ -59,7 +59,7 @@ /* parameters for replay protection */ #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 */ #define TIME_STAMP_ALLOW_JITTER 1 /* constant for allowing or... */ #define TIME_STAMP_NO_JITTER 0 /* not allowing jitter to be considered */ @@ -82,8 +82,8 @@ enum federation{IS_NO_FEDERATION = 0,IS_FEDERATION = 1}; #define COMMUNITY_UNPURGEABLE 0 #define COMMUNITY_PURGEABLE 1 -#define SN_UNPURGEABLE 0 /* FIX fcarli3 */ -#define SN_PURGEABLE 1 /* FIX fcarli3 */ +/* (un)purgeable supernode indicator */ +enum sn_purge{SN_UNPURGEABLE = 0, SN_PURGEABLE = 1}; /* Header encryption indicators */ #define HEADER_ENCRYPTION_UNKNOWN 0 @@ -139,4 +139,3 @@ enum federation{IS_NO_FEDERATION = 0,IS_FEDERATION = 1}; #ifndef min #define min(a, b) ((a > b) ? b : a) #endif - diff --git a/include/n2n_wire.h b/include/n2n_wire.h index dbe32cd..83f85ef 100644 --- a/include/n2n_wire.h +++ b/include/n2n_wire.h @@ -304,13 +304,15 @@ int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * pkt, int encode_REGISTER_SUPER_ACK( uint8_t * base, size_t * idx, const n2n_common_t * cmn, - const n2n_REGISTER_SUPER_ACK_t * reg ); + const n2n_REGISTER_SUPER_ACK_t * reg, + uint8_t * tmpbuf); int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg, const n2n_common_t * cmn, /* info on how to interpret it */ const uint8_t * base, size_t * rem, - size_t * idx ); + size_t * idx, + uint8_t * tmpbuf); int fill_sockaddr( struct sockaddr * addr, size_t addrlen, diff --git a/src/edge_utils.c b/src/edge_utils.c index 24a3869..30d0c21 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -37,7 +37,6 @@ static void check_peer_registration_needed(n2n_edge_t *eee, static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, uint8_t tos); static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes); static void edge_cleanup_routes(n2n_edge_t *eee); -static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn); static void check_known_peer_sock_change(n2n_edge_t *eee, uint8_t from_supernode, @@ -211,7 +210,7 @@ n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) { traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee->conf.sn_ip_array[i])); /* Set the active supernode */ - supernode2addr(&(eee->supernode), eee->conf.sn_ip_array[eee->sn_idx]); + supernode2sock(&(eee->supernode), eee->conf.sn_ip_array[eee->sn_idx]); /* Set active transop */ switch(transop_id) { @@ -319,72 +318,6 @@ static int is_valid_peer_sock(const n2n_sock_t *sock) { /* ***************************************************** */ -/** Resolve the supernode IP address. - * - * REVISIT: This is a really bad idea. The edge will block completely while the - * hostname resolution is performed. This could take 15 seconds. - */ -static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn) { - n2n_sn_name_t addr; - const char *supernode_host; - int rv = 0; - - memcpy(addr, addrIn, N2N_EDGE_SN_HOST_SIZE); - - supernode_host = strtok(addr, ":"); - - if(supernode_host) { - in_addr_t sn_addr; - char *supernode_port = strtok(NULL, ":"); - const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; - struct addrinfo * ainfo = NULL; - int nameerr; - - if(supernode_port) - sn->port = atoi(supernode_port); - else - traceEvent(TRACE_WARNING, "Bad supernode parameter (-l ) %s %s:%s", - addr, supernode_host, supernode_port); - - nameerr = getaddrinfo(supernode_host, NULL, &aihints, &ainfo); - - if(0 == nameerr) - { - struct sockaddr_in * saddr; - - /* ainfo s the head of a linked list if non-NULL. */ - if(ainfo && (PF_INET == ainfo->ai_family)) - { - /* It is definitely and IPv4 address -> sockaddr_in */ - saddr = (struct sockaddr_in *)ainfo->ai_addr; - - memcpy(sn->addr.v4, &(saddr->sin_addr.s_addr), IPV4_SIZE); - sn->family=AF_INET; - } - else - { - /* Should only return IPv4 addresses due to aihints. */ - traceEvent(TRACE_WARNING, "Failed to resolve supernode IPv4 address for %s", supernode_host); - rv = -1; - } - - freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ - ainfo = NULL; - } else { - traceEvent(TRACE_WARNING, "Failed to resolve supernode host %s", supernode_host); - rv = -2; - } - - } else { - traceEvent(TRACE_WARNING, "Wrong supernode parameter (-l )"); - rv = -3; - } - - return(rv); -} - -/* ************************************** */ - static const int definitely_from_supernode = 1; /*** @@ -961,7 +894,7 @@ void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) { --(eee->sup_attempts); for(sn_idx=0; sn_idxconf.sn_num; sn_idx++) { - if(supernode2addr(&(eee->supernode), eee->conf.sn_ip_array[sn_idx]) == 0) { + if(supernode2sock(&(eee->supernode), eee->conf.sn_ip_array[sn_idx]) == 0) { traceEvent(TRACE_INFO, "Registering with supernode [id: %u/%u][%s][attempts left %u]", sn_idx+1, eee->conf.sn_num, supernode_ip(eee), (unsigned int)eee->sup_attempts); @@ -1901,6 +1834,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { in_addr_t net; char * ip_str = NULL; n2n_REGISTER_SUPER_ACK_t ra; + uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); @@ -1915,7 +1849,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { if(eee->sn_wait) { - decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx); + decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx, tmpbuf); if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp, TIME_STAMP_NO_JITTER)) { @@ -1940,13 +1874,10 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { if(0 == memcmp(ra.cookie, eee->last_cookie, N2N_COOKIE_SIZE)) { -#if 0 - if(ra.num_sn > 0) /* FIX fcarli3 */ + if(ra.num_sn > 0) { - traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK backup supernode at %s", - sock_to_cstr(sockbuf1, &(ra.sn_bak))); + traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK payload contains sockets and MACs of supernodes in the federation."); } -#endif eee->last_sup = now; eee->sn_wait=0; eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */ @@ -2548,7 +2479,7 @@ static int edge_init_routes_linux(n2n_edge_t *eee, n2n_route_t *routes, uint16_t return(-1); } - if (supernode2addr(&sn, eee->conf.sn_ip_array[0]) < 0) + if (supernode2sock(&sn, eee->conf.sn_ip_array[0]) < 0) return(-1); if (sn.family != AF_INET) { diff --git a/src/n2n.c b/src/n2n.c index 6dafb0a..5a1d067 100644 --- a/src/n2n.c +++ b/src/n2n.c @@ -221,6 +221,72 @@ char * macaddr_str(macstr_t buf, /* *********************************************** */ +/** Resolve the supernode IP address. + * + * REVISIT: This is a really bad idea. The edge will block completely while the + * hostname resolution is performed. This could take 15 seconds. + */ +int supernode2sock(n2n_sock_t * sn, const n2n_sn_name_t addrIn) { + n2n_sn_name_t addr; + const char *supernode_host; + int rv = 0; + + memcpy(addr, addrIn, N2N_EDGE_SN_HOST_SIZE); + + supernode_host = strtok(addr, ":"); + + if(supernode_host) { + in_addr_t sn_addr; + char *supernode_port = strtok(NULL, ":"); + const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; + struct addrinfo * ainfo = NULL; + int nameerr; + + if(supernode_port) + sn->port = atoi(supernode_port); + else + traceEvent(TRACE_WARNING, "Bad supernode parameter (-l ) %s %s:%s", + addr, supernode_host, supernode_port); + + nameerr = getaddrinfo(supernode_host, NULL, &aihints, &ainfo); + + if(0 == nameerr) + { + struct sockaddr_in * saddr; + + /* ainfo s the head of a linked list if non-NULL. */ + if(ainfo && (PF_INET == ainfo->ai_family)) + { + /* It is definitely and IPv4 address -> sockaddr_in */ + saddr = (struct sockaddr_in *)ainfo->ai_addr; + + memcpy(sn->addr.v4, &(saddr->sin_addr.s_addr), IPV4_SIZE); + sn->family=AF_INET; + } + else + { + /* Should only return IPv4 addresses due to aihints. */ + traceEvent(TRACE_WARNING, "Failed to resolve supernode IPv4 address for %s", supernode_host); + rv = -1; + } + + freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ + ainfo = NULL; + } else { + traceEvent(TRACE_WARNING, "Failed to resolve supernode host %s", supernode_host); + rv = -2; + } + + } else { + traceEvent(TRACE_WARNING, "Wrong supernode parameter (-l )"); + rv = -3; + } + + return(rv); +} + +/* ************************************** */ + uint8_t is_multi_broadcast(const uint8_t * dest_mac) { int is_broadcast =(memcmp(broadcast_addr, dest_mac, 6) == 0); @@ -278,7 +344,7 @@ void print_n2n_version() { GIT_RELEASE, PACKAGE_OSNAME, PACKAGE_BUILDDATE); } -/* *********************************************** */ +/* *********************************************** */ size_t purge_expired_registrations(struct peer_info ** peer_list, time_t* p_last_purge, int timeout) { time_t now = time(NULL); @@ -373,7 +439,7 @@ extern char * sock_to_cstr(n2n_sock_str_t out, } else { const uint8_t * a = sock->addr.v4; - snprintf(out, N2N_SOCKBUF_SIZE, "%hu.%hu.%hu.%hu:%hu", + snprintf(out, N2N_SOCKBUF_SIZE, "%hu.%hu.%hu.%hu:%hu", (unsigned short)(a[0] & 0xff), (unsigned short)(a[1] & 0xff), (unsigned short)(a[2] & 0xff), diff --git a/src/sn.c b/src/sn.c index becd9d2..d98b576 100644 --- a/src/sn.c +++ b/src/sn.c @@ -234,7 +234,7 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { n2n_sock_t *socket; struct peer_info *anchor_sn; size_t length; - int rv; + int rv = -1; length = strlen(_optarg); if(length >= N2N_EDGE_SN_HOST_SIZE) { @@ -251,13 +251,8 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { anchor_sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE); if(anchor_sn->ip_addr){ strncpy(anchor_sn->ip_addr,_optarg,N2N_EDGE_SN_HOST_SIZE-1); + rv = supernode2sock(socket,_optarg); -#if 1 - rv = -1; -#else - rv = supernode2sock(socket,_optarg); /* FIX fcarli3 */ -#endif - if(rv != 0){ traceEvent(TRACE_WARNING, "Invalid socket"); break; @@ -270,7 +265,7 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { } } } - + break; } diff --git a/src/sn_utils.c b/src/sn_utils.c index f645f77..94a3044 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -1185,8 +1185,7 @@ static int process_udp(n2n_sn_t * sss, update_edge(sss, ®, comm, &(ack.sock), now); } - encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack); - encode_buf(ackbuf,&encx,tmpbuf,(num*ENTRY_SIZE)); + encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack, tmpbuf); if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx, @@ -1219,6 +1218,7 @@ static int process_udp(n2n_sn_t * sss, n2n_sock_t *tmp_sock; n2n_mac_t *tmp_mac; int i; + uint8_t dec_tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; sender.family = AF_INET; sender.port = ntohs(sender_sock->sin_port); @@ -1237,7 +1237,7 @@ static int process_udp(n2n_sn_t * sss, return -1; } - decode_REGISTER_SUPER_ACK(&ack,&cmn,udp_buf,&rem,&idx); + decode_REGISTER_SUPER_ACK(&ack,&cmn,udp_buf,&rem,&idx,dec_tmpbuf); orig_sender = &(ack.sock); if (comm) { diff --git a/src/wire.c b/src/wire.c index 4ca6526..4c18bc4 100644 --- a/src/wire.c +++ b/src/wire.c @@ -395,7 +395,8 @@ int decode_REGISTER_ACK(n2n_REGISTER_ACK_t *reg, int encode_REGISTER_SUPER_ACK(uint8_t *base, size_t *idx, const n2n_common_t *common, - const n2n_REGISTER_SUPER_ACK_t *reg) { + const n2n_REGISTER_SUPER_ACK_t *reg, + uint8_t *tmpbuf) { int retval = 0; retval += encode_common(base, idx, common); retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE); @@ -405,15 +406,8 @@ int encode_REGISTER_SUPER_ACK(uint8_t *base, retval += encode_uint16(base, idx, reg->lifetime); retval += encode_sock(base, idx, &(reg->sock)); retval += encode_uint8(base, idx, reg->num_sn); + retval += encode_buf(base, idx, tmpbuf, (reg->num_sn*ENTRY_SIZE)); -#if 0 /* FIX fcarli3 */ - if (reg->num_sn > 0) { - /* We only support 0 or 1 at this stage */ - retval += encode_sock(base, idx, &(reg->sn_bak)); - retval += encode_mac(base, idx, reg->mac_addr); - } -#endif - return retval; } @@ -422,7 +416,8 @@ int decode_REGISTER_SUPER_ACK(n2n_REGISTER_SUPER_ACK_t *reg, const n2n_common_t *cmn, /* info on how to interpret it */ const uint8_t *base, size_t *rem, - size_t *idx) { + size_t *idx, + uint8_t *tmpbuf) { size_t retval = 0; memset(reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); @@ -437,15 +432,8 @@ int decode_REGISTER_SUPER_ACK(n2n_REGISTER_SUPER_ACK_t *reg, /* Following the edge socket are an array of backup supernodes. */ retval += decode_uint8(&(reg->num_sn), base, rem, idx); + retval += decode_buf(tmpbuf, (reg->num_sn*ENTRY_SIZE), base, rem, idx); -#if 0 /* FIX fcarli3 */ - if (reg->num_sn > 0) { - /* We only support 0 or 1 at this stage */ - retval += decode_sock(&(reg->sn_bak), base, rem, idx); - retval += decode_mac(reg->mac_addr, base, rem, idx); - } -#endif - return retval; }