From 053ab381b33ac5b3c9eca50612af1df94328a8c4 Mon Sep 17 00:00:00 2001 From: Logan oos Even <46396513+Logan007@users.noreply.github.com> Date: Tue, 28 Jun 2022 16:53:12 +0200 Subject: [PATCH] fixed endianess issue in federated sn socket forwarding (#1030) --- include/n2n_typedefs.h | 6 ++++-- include/n2n_wire.h | 13 +++++++++++++ src/edge_utils.c | 16 +++++++++++---- src/sn_utils.c | 17 ++++++++++++++-- src/wire.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 8 deletions(-) diff --git a/include/n2n_typedefs.h b/include/n2n_typedefs.h index 36bb67e..24562c9 100644 --- a/include/n2n_typedefs.h +++ b/include/n2n_typedefs.h @@ -406,8 +406,10 @@ typedef struct n2n_REGISTER_SUPER_NAK { /* REGISTER_SUPER_ACK may contain extra payload (their number given by num_sn) * of following type describing a(nother) supernode */ typedef struct n2n_REGISTER_SUPER_ACK_payload { - n2n_sock_t sock; /**< socket of supernode */ - n2n_mac_t mac; /**< MAC of supernode */ + // REVISIT: interim for bugfix (https://github.com/ntop/n2n/issues/1029) + // remove with 4.0 + uint8_t sock[sizeof(uint16_t) + sizeof(uint16_t) + IPV6_SIZE]; /**< socket of supernode */ + n2n_mac_t mac; /**< MAC of supernode */ } n2n_REGISTER_SUPER_ACK_payload_t; diff --git a/include/n2n_wire.h b/include/n2n_wire.h index 1edf5be..3e23132 100644 --- a/include/n2n_wire.h +++ b/include/n2n_wire.h @@ -118,6 +118,19 @@ int decode_sock (n2n_sock_t * sock, size_t * rem, size_t * idx); +// bugfix for https://github.com/ntop/n2n/issues/1029 +// REVISIT: best to be removed with 4.0 +int encode_sock_payload (uint8_t * base, + size_t * idx, + const n2n_sock_t * sock); + +// bugfix for https://github.com/ntop/n2n/issues/1029 +// REVISIT: best to be removed with 4.0 +int decode_sock_payload (n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx); + int encode_REGISTER (uint8_t * base, size_t * idx, const n2n_common_t * common, diff --git a/src/edge_utils.c b/src/edge_utils.c index 06d71e7..ba42b7a 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -2414,6 +2414,7 @@ void process_udp (n2n_edge_t *eee, const struct sockaddr *sender_sock, const SOC uint8_t tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE]; char ip_tmp[N2N_EDGE_SN_HOST_SIZE]; n2n_REGISTER_SUPER_ACK_payload_t *payload; + n2n_sock_t payload_sock; int i; int skip_add; @@ -2474,15 +2475,22 @@ void process_udp (n2n_edge_t *eee, const struct sockaddr *sender_sock, const SOC // from here on, 'sn' gets used differently for(i = 0; i < ra.num_sn; i++) { skip_add = SN_ADD; - sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &(payload->sock), payload->mac, &skip_add); + + // bugfix for https://github.com/ntop/n2n/issues/1029 + // REVISIT: best to be removed with 4.0 + idx = 0; + rem = sizeof(payload->sock); + decode_sock_payload(&payload_sock, payload->sock, &rem, &idx); + + sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &payload_sock, payload->mac, &skip_add); if(skip_add == SN_ADD_ADDED) { sn->ip_addr = calloc(1, N2N_EDGE_SN_HOST_SIZE); if(sn->ip_addr != NULL) { - inet_ntop(payload->sock.family, - (payload->sock.family == AF_INET) ? (void*)&(payload->sock.addr.v4) : (void*)&(payload->sock.addr.v6), + inet_ntop(payload_sock.family, + (payload_sock.family == AF_INET) ? (void*)&(payload_sock.addr.v4) : (void*)&(payload_sock.addr.v6), sn->ip_addr, N2N_EDGE_SN_HOST_SIZE - 1); - sprintf(ip_tmp, "%s:%u", (char*)sn->ip_addr, (uint16_t)(payload->sock.port)); + sprintf(ip_tmp, "%s:%u", (char*)sn->ip_addr, (uint16_t)(payload_sock.port)); memcpy(sn->ip_addr, ip_tmp, sizeof(ip_tmp)); } sn_selection_criterion_default(&(sn->selection_criterion)); diff --git a/src/sn_utils.c b/src/sn_utils.c index f35e499..16b9d64 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -1990,7 +1990,12 @@ static int process_udp (n2n_sn_t * sss, * We need to allow for a little extra time because supernodes sometimes exceed * their SN_ACTIVE time before they get re-registred to. */ if(((++num)*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE) > REG_SUPER_ACK_PAYLOAD_SPACE) break; /* no more space available in REGISTER_SUPER_ACK payload */ - memcpy(&(payload->sock), &(peer->sock), sizeof(n2n_sock_t)); + + // bugfix for https://github.com/ntop/n2n/issues/1029 + // REVISIT: best to be removed with 4.0 (replace with encode_sock) + idx = 0; + encode_sock_payload(payload->sock, &idx, &(peer->sock)); + memcpy(payload->mac, peer->mac_addr, sizeof(n2n_mac_t)); // shift to next payload entry payload++; @@ -2182,6 +2187,7 @@ static int process_udp (n2n_sn_t * sss, int i; uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE]; n2n_REGISTER_SUPER_ACK_payload_t *payload; + n2n_sock_t payload_sock; memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); @@ -2224,7 +2230,14 @@ static int process_udp (n2n_sn_t * sss, payload = (n2n_REGISTER_SUPER_ACK_payload_t *)dec_tmpbuf; for(i = 0; i < ack.num_sn; i++) { skip_add = SN_ADD; - tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(payload->sock), payload->mac, &skip_add); + + // bugfix for https://github.com/ntop/n2n/issues/1029 + // REVISIT: best to be removed with 4.0 + idx = 0; + rem = sizeof(payload->sock); + decode_sock_payload(&payload_sock, payload->sock, &rem, &idx); + + tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(payload_sock), payload->mac, &skip_add); // other supernodes communicate via standard udp socket tmp->socket_fd = sss->sock; diff --git a/src/wire.c b/src/wire.c index 7f0dd58..f85ee34 100644 --- a/src/wire.c +++ b/src/wire.c @@ -305,6 +305,50 @@ int decode_sock (n2n_sock_t * sock, } +// bugfix for https://github.com/ntop/n2n/issues/1029 +// REVISIT: best to be removed with 4.0 +int encode_sock_payload (uint8_t * base, + size_t * idx, + const n2n_sock_t * sock) { + + int retval = 0; + + retval += encode_uint8(base, idx, sock->family); + retval += encode_uint8(base, idx, 0); // blank + retval += encode_uint8(base, idx, sock->port & 0x00FF); + retval += encode_uint8(base, idx, sock->port >> 8); + // copy full address field length + retval += encode_buf(base, idx, sock->addr.v6, IPV6_SIZE); + + return retval; +} + + +// bugfix for https://github.com/ntop/n2n/issues/1029 +// REVISIT: best to be removed with 4.0 +int decode_sock_payload (n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + int retval = 0; + uint8_t port_low = 0; + uint8_t port_high = 0; + + retval += decode_uint8(&(sock->family), base, rem, idx); + ++(*idx); // skip blank + --(*rem); + ++retval; + retval += decode_uint8(&port_low, base, rem, idx); + retval += decode_uint8(&port_high, base, rem, idx); + sock->port = ((uint16_t)port_high << 8) + port_low; + // copy full address field length + retval += decode_buf(sock->addr.v6, IPV6_SIZE, base, rem, idx); + + return retval; +} + + int encode_REGISTER (uint8_t *base, size_t *idx, const n2n_common_t *common,