Browse Source

fixed endianess issue in federated sn socket forwarding (#1030)

pull/1031/head
Logan oos Even 2 years ago
committed by GitHub
parent
commit
053ab381b3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      include/n2n_typedefs.h
  2. 13
      include/n2n_wire.h
  3. 16
      src/edge_utils.c
  4. 17
      src/sn_utils.c
  5. 44
      src/wire.c

4
include/n2n_typedefs.h

@ -406,7 +406,9 @@ typedef struct n2n_REGISTER_SUPER_NAK {
/* REGISTER_SUPER_ACK may contain extra payload (their number given by num_sn) /* REGISTER_SUPER_ACK may contain extra payload (their number given by num_sn)
* of following type describing a(nother) supernode */ * of following type describing a(nother) supernode */
typedef struct n2n_REGISTER_SUPER_ACK_payload { typedef struct n2n_REGISTER_SUPER_ACK_payload {
n2n_sock_t sock; /**< socket 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_mac_t mac; /**< MAC of supernode */
} n2n_REGISTER_SUPER_ACK_payload_t; } n2n_REGISTER_SUPER_ACK_payload_t;

13
include/n2n_wire.h

@ -118,6 +118,19 @@ int decode_sock (n2n_sock_t * sock,
size_t * rem, size_t * rem,
size_t * idx); 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, int encode_REGISTER (uint8_t * base,
size_t * idx, size_t * idx,
const n2n_common_t * common, const n2n_common_t * common,

16
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]; uint8_t tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
char ip_tmp[N2N_EDGE_SN_HOST_SIZE]; char ip_tmp[N2N_EDGE_SN_HOST_SIZE];
n2n_REGISTER_SUPER_ACK_payload_t *payload; n2n_REGISTER_SUPER_ACK_payload_t *payload;
n2n_sock_t payload_sock;
int i; int i;
int skip_add; 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 // from here on, 'sn' gets used differently
for(i = 0; i < ra.num_sn; i++) { for(i = 0; i < ra.num_sn; i++) {
skip_add = SN_ADD; 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) { if(skip_add == SN_ADD_ADDED) {
sn->ip_addr = calloc(1, N2N_EDGE_SN_HOST_SIZE); sn->ip_addr = calloc(1, N2N_EDGE_SN_HOST_SIZE);
if(sn->ip_addr != NULL) { if(sn->ip_addr != NULL) {
inet_ntop(payload->sock.family, inet_ntop(payload_sock.family,
(payload->sock.family == AF_INET) ? (void*)&(payload->sock.addr.v4) : (void*)&(payload->sock.addr.v6), (payload_sock.family == AF_INET) ? (void*)&(payload_sock.addr.v4) : (void*)&(payload_sock.addr.v6),
sn->ip_addr, N2N_EDGE_SN_HOST_SIZE - 1); 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)); memcpy(sn->ip_addr, ip_tmp, sizeof(ip_tmp));
} }
sn_selection_criterion_default(&(sn->selection_criterion)); sn_selection_criterion_default(&(sn->selection_criterion));

17
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 * We need to allow for a little extra time because supernodes sometimes exceed
* their SN_ACTIVE time before they get re-registred to. */ * 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 */ 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)); memcpy(payload->mac, peer->mac_addr, sizeof(n2n_mac_t));
// shift to next payload entry // shift to next payload entry
payload++; payload++;
@ -2182,6 +2187,7 @@ static int process_udp (n2n_sn_t * sss,
int i; int i;
uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE]; uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
n2n_REGISTER_SUPER_ACK_payload_t *payload; n2n_REGISTER_SUPER_ACK_payload_t *payload;
n2n_sock_t payload_sock;
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); 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; payload = (n2n_REGISTER_SUPER_ACK_payload_t *)dec_tmpbuf;
for(i = 0; i < ack.num_sn; i++) { for(i = 0; i < ack.num_sn; i++) {
skip_add = SN_ADD; 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 // other supernodes communicate via standard udp socket
tmp->socket_fd = sss->sock; tmp->socket_fd = sss->sock;

44
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, int encode_REGISTER (uint8_t *base,
size_t *idx, size_t *idx,
const n2n_common_t *common, const n2n_common_t *common,

Loading…
Cancel
Save