"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/edge_utils.c" between
n2n-3.0.tar.gz and n2n-3.1.1.tar.gz

About: n2n is a layer-two peer-to-peer virtual private network (VPN) which allows bypassing intermediate firewalls.
Pre-release.

edge_utils.c  (n2n-3.0):edge_utils.c  (n2n-3.1.1)
/** /**
* (C) 2007-21 - ntop.org and contributors * (C) 2007-22 - ntop.org and contributors
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not see see <http://www.gnu.org/licenses/> * along with this program; if not see see <http://www.gnu.org/licenses/>
* *
*/ */
#include "n2n.h" #include "n2n.h"
#include "network_traffic_filter.h" #include "network_traffic_filter.h"
#include "edge_utils_win32.h" #include "edge_utils_win32.h"
/* heap allocation for compression as per lzo example doc */
#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lz
o_align_t) - 1)) / sizeof(lzo_align_t) ]
static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
/* ************************************** */ /* ************************************** */
int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn _list); int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn _list);
int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, t ime_t now); int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, t ime_t now);
int resolve_cancel_thread (n2n_resolve_parameter_t *param); int resolve_cancel_thread (n2n_resolve_parameter_t *param);
#ifdef HAVE_PORT_FORWARDING
int port_map_create_thread (n2n_port_map_parameter_t **param, uint16_t mgmt_port
);
int port_map_cancel_thread (n2n_port_map_parameter_t *param);
#endif
static const char * supernode_ip (const n2n_edge_t * eee); static const char * supernode_ip (const n2n_edge_t * eee);
static void send_register (n2n_edge_t *eee, const n2n_sock_t *remote_peer, const n2n_mac_t peer_mac, n2n_cookie_t cookie); static void send_register (n2n_edge_t *eee, const n2n_sock_t *remote_peer, const n2n_mac_t peer_mac, n2n_cookie_t cookie);
static void check_peer_registration_needed (n2n_edge_t *eee, static void check_peer_registration_needed (n2n_edge_t *eee,
uint8_t from_supernode, uint8_t from_supernode,
uint8_t via_multicast, uint8_t via_multicast,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_cookie_t cookie, const n2n_cookie_t cookie,
const n2n_ip_subnet_t *dev_addr, const n2n_ip_subnet_t *dev_addr,
const n2n_desc_t *dev_desc, const n2n_desc_t *dev_desc,
skipping to change at line 327 skipping to change at line 328
memcpy(&eee->conf.preferred_sock, &local_sock, sizeof(n2n_sock_t )); memcpy(&eee->conf.preferred_sock, &local_sock, sizeof(n2n_sock_t ));
traceEvent(TRACE_INFO, "determined local socket [%s]", traceEvent(TRACE_INFO, "determined local socket [%s]",
sock_to_cstr(sockbuf, &local_sock)); sock_to_cstr(sockbuf, &local_sock));
} }
} }
if(eee->cb.sock_opened) if(eee->cb.sock_opened)
eee->cb.sock_opened(eee); eee->cb.sock_opened(eee);
} }
#ifdef HAVE_PORT_FORWARDING
if(eee->conf.port_forwarding)
// REVISIT: replace with mgmt port notification to listener for mgmt por
t
// subscription support
n2n_chg_port_mapping(eee, eee->conf.preferred_sock.port);
#endif // HAVE_PORT_FORWARDING
return 0; return 0;
} }
// always closes the socket // always closes the socket
void supernode_disconnect (n2n_edge_t *eee) { void supernode_disconnect (n2n_edge_t *eee) {
if(eee->sock >= 0) { if(eee->sock >= 0) {
closesocket(eee->sock); closesocket(eee->sock);
eee->sock = -1; eee->sock = -1;
} }
skipping to change at line 375 skipping to change at line 382
eee->start_time = time(NULL); eee->start_time = time(NULL);
eee->known_peers = NULL; eee->known_peers = NULL;
eee->pending_peers = NULL; eee->pending_peers = NULL;
reset_sup_attempts(eee); reset_sup_attempts(eee);
sn_selection_criterion_common_data_default(eee); sn_selection_criterion_common_data_default(eee);
pearson_hash_init(); pearson_hash_init();
if(eee->conf.compression == N2N_COMPRESSION_ID_LZO) // always initialize compression transforms so we can at least decompress
if(lzo_init() != LZO_E_OK) { rc = n2n_transop_lzo_init(&eee->conf, &eee->transop_lzo);
traceEvent(TRACE_ERROR, "LZO compression error"); if(rc) goto edge_init_error; /* error message is printed in lzo_init */
goto edge_init_error; #ifdef HAVE_ZSTD
} rc = n2n_transop_zstd_init(&eee->conf, &eee->transop_zstd);
#ifdef N2N_HAVE_ZSTD if(rc) goto edge_init_error; /* error message is printed in zstd_init */
// zstd does not require initialization. if it were required, this would be
a good place
#endif #endif
traceEvent(TRACE_NORMAL, "number of supernodes in the list: %d\n", HASH_COUN T(eee->conf.supernodes)); traceEvent(TRACE_NORMAL, "number of supernodes in the list: %d\n", HASH_COUN T(eee->conf.supernodes));
HASH_ITER(hh, eee->conf.supernodes, scan, tmp) { HASH_ITER(hh, eee->conf.supernodes, scan, tmp) {
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (scan->ip_addr)); traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (scan->ip_addr));
i++; i++;
} }
/* Set active transop */ /* Set active transop */
switch(transop_id) { switch(transop_id) {
skipping to change at line 477 skipping to change at line 483
eee->udp_multicast_sock = -1; eee->udp_multicast_sock = -1;
#endif #endif
if(edge_init_sockets(eee) < 0) { if(edge_init_sockets(eee) < 0) {
traceEvent(TRACE_ERROR, "socket setup failed"); traceEvent(TRACE_ERROR, "socket setup failed");
goto edge_init_error; goto edge_init_error;
} }
if(resolve_create_thread(&(eee->resolve_parameter), eee->conf.supernodes) == 0) { if(resolve_create_thread(&(eee->resolve_parameter), eee->conf.supernodes) == 0) {
traceEvent(TRACE_NORMAL, "successfully created resolver thread"); traceEvent(TRACE_NORMAL, "successfully created resolver thread");
} }
#ifdef HAVE_PORT_FORWARDING
if(eee->conf.port_forwarding)
if(port_map_create_thread(&eee->port_map_parameter, eee->conf.mgmt_port)
== 0) {
traceEvent(TRACE_NORMAL, "successfully created port mapping thread")
;
}
#endif // HAVE_MINIUPNP || HAVE_NATPMP
eee->network_traffic_filter = create_network_traffic_filter(); eee->network_traffic_filter = create_network_traffic_filter();
network_traffic_filter_add_rule(eee->network_traffic_filter, eee->conf.netwo rk_traffic_filter_rules); network_traffic_filter_add_rule(eee->network_traffic_filter, eee->conf.netwo rk_traffic_filter_rules);
//edge_init_success: //edge_init_success:
*rv = 0; *rv = 0;
return(eee); return(eee);
edge_init_error: edge_init_error:
if(eee) if(eee)
free(eee); free(eee);
skipping to change at line 786 skipping to change at line 797
if(scan) if(scan)
scan->last_cookie = N2N_NO_REG_COOKIE; scan->last_cookie = N2N_NO_REG_COOKIE;
} }
if(scan) { if(scan) {
HASH_DEL(eee->pending_peers, scan); HASH_DEL(eee->pending_peers, scan);
scan_tmp = find_peer_by_sock(peer, eee->known_peers); scan_tmp = find_peer_by_sock(peer, eee->known_peers);
if(scan_tmp != NULL) { if(scan_tmp != NULL) {
HASH_DEL(eee->known_peers, scan_tmp); HASH_DEL(eee->known_peers, scan_tmp);
mgmt_event_post(N2N_EVENT_PEER,N2N_EVENT_PEER_DEL_P2P,scan);
free(scan); free(scan);
scan = scan_tmp; scan = scan_tmp;
memcpy(scan->mac_addr, mac, sizeof(n2n_mac_t)); memcpy(scan->mac_addr, mac, sizeof(n2n_mac_t));
// in case of MAC change, reset cookie to allow immediate re-registr ation // in case of MAC change, reset cookie to allow immediate re-registr ation
scan->last_cookie = N2N_NO_REG_COOKIE; scan->last_cookie = N2N_NO_REG_COOKIE;
} else { } else {
// update sock but ... // update sock but ...
// ... ignore ACKs's (and their socks) from lower ranked inbound way s for a while // ... ignore ACKs's (and their socks) from lower ranked inbound way s for a while
if(((now - scan->last_seen) > REGISTRATION_TIMEOUT / 4) if(((now - scan->last_seen) > REGISTRATION_TIMEOUT / 4)
||(cookie > scan->last_cookie)) { ||(cookie > scan->last_cookie)) {
scan->sock = *peer; scan->sock = *peer;
scan->last_cookie = cookie; scan->last_cookie = cookie;
} }
} }
HASH_ADD_PEER(eee->known_peers, scan); HASH_ADD_PEER(eee->known_peers, scan);
scan->last_p2p = now; scan->last_p2p = now;
mgmt_event_post(N2N_EVENT_PEER,N2N_EVENT_PEER_ADD_P2P,scan);
traceEvent(TRACE_DEBUG, "p2p connection established: %s [%s]", traceEvent(TRACE_DEBUG, "p2p connection established: %s [%s]",
macaddr_str(mac_buf, mac), macaddr_str(mac_buf, mac),
sock_to_cstr(sockbuf, peer)); sock_to_cstr(sockbuf, peer));
traceEvent(TRACE_DEBUG, "new peer %s [%s]", traceEvent(TRACE_DEBUG, "new peer %s [%s]",
macaddr_str(mac_buf, scan->mac_addr), macaddr_str(mac_buf, scan->mac_addr),
sock_to_cstr(sockbuf, &(scan->sock))); sock_to_cstr(sockbuf, &(scan->sock)));
traceEvent(TRACE_DEBUG, "pending peers list size=%u", traceEvent(TRACE_DEBUG, "pending peers list size=%u",
skipping to change at line 963 skipping to change at line 976
if(!sock_equal(&(scan->sock), peer)) { if(!sock_equal(&(scan->sock), peer)) {
if(!from_supernode) { if(!from_supernode) {
/* This is a P2P packet */ /* This is a P2P packet */
traceEvent(TRACE_NORMAL, "peer %s changed [%s] -> [%s]", traceEvent(TRACE_NORMAL, "peer %s changed [%s] -> [%s]",
macaddr_str(mac_buf, scan->mac_addr), macaddr_str(mac_buf, scan->mac_addr),
sock_to_cstr(sockbuf1, &(scan->sock)), sock_to_cstr(sockbuf1, &(scan->sock)),
sock_to_cstr(sockbuf2, peer)); sock_to_cstr(sockbuf2, peer));
/* The peer has changed public socket. It can no longer be assumed t o be reachable. */ /* The peer has changed public socket. It can no longer be assumed t o be reachable. */
HASH_DEL(eee->known_peers, scan); HASH_DEL(eee->known_peers, scan);
mgmt_event_post(N2N_EVENT_PEER,N2N_EVENT_PEER_DEL_P2P,scan);
free(scan); free(scan);
register_with_new_peer(eee, from_supernode, via_multicast, mac, dev_ addr, dev_desc, peer); register_with_new_peer(eee, from_supernode, via_multicast, mac, dev_ addr, dev_desc, peer);
} else { } else {
/* Don't worry about what the supernode reports, it could be seeing a different socket. */ /* Don't worry about what the supernode reports, it could be seeing a different socket. */
} }
} else } else
scan->last_seen = when; scan->last_seen = when;
} }
skipping to change at line 1519 skipping to change at line 1533
} }
check_join_multicast_group(eee); check_join_multicast_group(eee);
if(0 == eee->sup_attempts) { if(0 == eee->sup_attempts) {
/* Give up on that supernode and try the next one. */ /* Give up on that supernode and try the next one. */
sn_selection_criterion_bad(&(eee->curr_sn->selection_criterion)); sn_selection_criterion_bad(&(eee->curr_sn->selection_criterion));
sn_selection_sort(&(eee->conf.supernodes)); sn_selection_sort(&(eee->conf.supernodes));
eee->curr_sn = eee->conf.supernodes; eee->curr_sn = eee->conf.supernodes;
traceEvent(TRACE_WARNING, "supernode not responding, now trying [%s]", s upernode_ip(eee)); traceEvent(TRACE_WARNING, "supernode not responding, now trying [%s]", s upernode_ip(eee));
supernode_connect(eee);
reset_sup_attempts(eee); reset_sup_attempts(eee);
// trigger out-of-schedule DNS resolution // trigger out-of-schedule DNS resolution
eee->resolution_request = 1; eee->resolution_request = 1;
// in some multi-NATed scenarios communication gets stuck on losing conn ection to supernode // in some multi-NATed scenarios communication gets stuck on losing conn ection to supernode
// closing and re-opening the socket allows for re-establishing communic ation // closing and re-opening the socket allows for re-establishing communic ation
// this can only be done, if working on some unprivileged port and/or ha ving sufficent // this can only be done, if working on some unprivileged port and/or ha ving sufficent
// privileges. as we are not able to check for sufficent privileges here , we only do it // privileges. as we are not able to check for sufficent privileges here , we only do it
// if port is sufficently high or unset. uncovered: privileged port and sufficent privileges // if port is sufficently high or unset. uncovered: privileged port and sufficent privileges
if((eee->conf.local_port == 0) || (eee->conf.local_port > 1024)) { if((eee->conf.local_port == 0) || (eee->conf.local_port > 1024)) {
skipping to change at line 1547 skipping to change at line 1560
if(!cnt) { if(!cnt) {
// ... and then count the connection retries // ... and then count the connection retries
(eee->close_socket_counter)++; (eee->close_socket_counter)++;
if(eee->close_socket_counter >= N2N_CLOSE_SOCKET_COUNTER_MAX) { if(eee->close_socket_counter >= N2N_CLOSE_SOCKET_COUNTER_MAX) {
eee->close_socket_counter = 0; eee->close_socket_counter = 0;
supernode_disconnect(eee); supernode_disconnect(eee);
traceEvent(TRACE_DEBUG, "disconnected supernode"); traceEvent(TRACE_DEBUG, "disconnected supernode");
} }
} }
supernode_connect(eee);
traceEvent(TRACE_DEBUG, "reconnected to supernode"); traceEvent(TRACE_DEBUG, "reconnected to supernode");
} }
supernode_connect(eee);
} else { } else {
--(eee->sup_attempts); --(eee->sup_attempts);
} }
#ifndef HAVE_PTHREAD #ifndef HAVE_PTHREAD
if(supernode2sock(&(eee->curr_sn->sock), eee->curr_sn->ip_addr) == 0) { if(supernode2sock(&(eee->curr_sn->sock), eee->curr_sn->ip_addr) == 0) {
#endif #endif
traceEvent(TRACE_INFO, "registering with supernode [%s][number of supern odes %d][attempts left %u]", traceEvent(TRACE_INFO, "registering with supernode [%s][number of supern odes %d][attempts left %u]",
supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigne d int)eee->sup_attempts); supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigne d int)eee->sup_attempts);
skipping to change at line 1627 skipping to change at line 1640
++(eee->stats.rx_sup); ++(eee->stats.rx_sup);
eee->last_sup = now; eee->last_sup = now;
} else { } else {
++(eee->stats.rx_p2p); ++(eee->stats.rx_p2p);
eee->last_p2p=now; eee->last_p2p=now;
} }
/* Handle transform. */ /* Handle transform. */
{ {
uint8_t decodebuf[N2N_PKT_BUF_SIZE]; uint8_t decode_buf[N2N_PKT_BUF_SIZE];
uint8_t deflate_buf[N2N_PKT_BUF_SIZE];
size_t eth_size; size_t eth_size;
n2n_transform_t rx_transop_id; n2n_transform_t rx_transop_id;
uint8_t rx_compression_id; uint8_t rx_compression_id;
rx_transop_id = (n2n_transform_t)pkt->transform; rx_transop_id = (n2n_transform_t)pkt->transform;
rx_compression_id = pkt->compression; rx_compression_id = pkt->compression;
if(rx_transop_id == eee->conf.transop_id) { if(rx_transop_id == eee->conf.transop_id) {
uint8_t is_multicast; uint8_t is_multicast;
eth_payload = decodebuf; // decrypt
eh = (ether_hdr_t*)eth_payload; eth_payload = decode_buf;
eth_size = eee->transop.rev(&eee->transop, eth_size = eee->transop.rev(&eee->transop,
eth_payload, N2N_PKT_BUF_SIZE, eth_payload, N2N_PKT_BUF_SIZE,
payload, psize, pkt->srcMac); payload, psize, pkt->srcMac);
++(eee->transop.rx_cnt); /* stats */ ++(eee->transop.rx_cnt); /* stats */
/* decompress if necessary */ /* decompress if necessary */
uint8_t * deflation_buffer = 0; size_t deflate_len;
lzo_uint deflated_len;
switch(rx_compression_id) { switch(rx_compression_id) {
case N2N_COMPRESSION_ID_NONE: case N2N_COMPRESSION_ID_NONE:
break; // continue afterwards break; // continue afterwards
case N2N_COMPRESSION_ID_LZO: case N2N_COMPRESSION_ID_LZO:
deflation_buffer = malloc(N2N_PKT_BUF_SIZE); deflate_len = eee->transop_lzo.rev(&eee->transop_lzo,
lzo1x_decompress(eth_payload, eth_size, deflation_buffer, &d deflate_buf, N2N_PKT_BUF_
eflated_len, NULL); SIZE,
decode_buf, eth_size, pkt
->srcMac);
break; break;
#ifdef N2N_HAVE_ZSTD
#ifdef HAVE_ZSTD
case N2N_COMPRESSION_ID_ZSTD: case N2N_COMPRESSION_ID_ZSTD:
deflated_len = N2N_PKT_BUF_SIZE; deflate_len = eee->transop_zstd.rev(&eee->transop_zstd,
deflation_buffer = malloc(deflated_len); deflate_buf, N2N_PKT_BUF
deflated_len = ZSTD_decompress(deflation_buffer, deflated_le _SIZE,
n, eth_payload, eth_size); decode_buf, eth_size, pk
if(ZSTD_isError(deflated_len)) { t->srcMac);
traceEvent(TRACE_WARNING, "payload decompression failed
with zstd error '%s'.",
ZSTD_getErrorName(deflated_len));
free(deflation_buffer);
return(-1); // cannot help it
}
break; break;
#endif #endif
default: default:
traceEvent(TRACE_WARNING, "payload decompression failed: rec eived packet indicating unsupported %s compression.", traceEvent(TRACE_WARNING, "payload decompression failed: rec eived packet indicating unsupported %s compression.",
compression_str(rx_compression_id)); compression_str(rx_compression_id));
return(-1); // cannot handle it return(-1); // cannot handle it
} }
if(rx_compression_id != N2N_COMPRESSION_ID_NONE) { if(rx_compression_id != N2N_COMPRESSION_ID_NONE) {
traceEvent(TRACE_DEBUG, "payload decompression %s: deflated %u b ytes to %u bytes", traceEvent(TRACE_DEBUG, "payload decompression %s: deflated %u b ytes to %u bytes",
compression_str(rx_compression_id), eth_size, (int)de compression_str(rx_compression_id), eth_
flated_len); size, (int)deflate_len);
memcpy(eth_payload,deflation_buffer, deflated_len ); eth_payload = deflate_buf;
eth_size = deflated_len; eth_size = deflate_len;
free(deflation_buffer);
} }
eh = (ether_hdr_t*)eth_payload;
is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMul ticast(eth_payload, eth_size)); is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMul ticast(eth_payload, eth_size));
if(eee->conf.drop_multicast && is_multicast) { if(eee->conf.drop_multicast && is_multicast) {
traceEvent(TRACE_INFO, "dropping RX multicast"); traceEvent(TRACE_INFO, "dropping RX multicast");
return(-1); return(-1);
} else if((!eee->conf.allow_routing) && (!is_multicast)) { } else if((!eee->conf.allow_routing) && (!is_multicast)) {
/* Check if it is a routed packet */ /* Check if it is a routed packet */
if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + I P4_MIN_SIZE)) { if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + I P4_MIN_SIZE)) {
uint32_t *dst = (uint32_t*)&eth_payload[ETH_FRAMESIZE + IP4_ DSTOFFSET]; uint32_t *dst = (uint32_t*)&eth_payload[ETH_FRAMESIZE + IP4_ DSTOFFSET];
uint8_t *dst_mac = (uint8_t*)eth_payload; uint8_t *dst_mac = (uint8_t*)eth_payload;
/* Note: all elements of the_ip are in network order */ /* Note: all elements of the_ip are in network order */
if(!memcmp(dst_mac, broadcast_mac, N2N_MAC_SIZE)) if(!memcmp(dst_mac, broadcast_mac, N2N_MAC_SIZE))
traceEvent(TRACE_DEBUG, "RX broadcast packet destined to [%s]", traceEvent(TRACE_DEBUG, "RX broadcast packet destined to [%s]",
intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); intoa(ntohl(*dst), ip_buf, sizeof(ip_buf)));
else if((*dst != eee->device.ip_addr)) { else if((*dst != eee->device.ip_addr)) {
/* This is a packet that needs to be routed */ /* This is a packet that needs to be routed */
traceEvent(TRACE_INFO, "discarding routed packet destine d to [%s]", traceEvent(TRACE_INFO, "discarding routed packet destine d to [%s]",
skipping to change at line 1785 skipping to change at line 1796
} }
} }
fclose(fd); fclose(fd);
return buf; return buf;
} }
#endif #endif
#endif #endif
/** Read a datagram from the management UDP socket and take appropriate
* action. */
static void readFromMgmtSocket (n2n_edge_t *eee) {
char udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */
ssize_t recvlen;
/* ssize_t sendlen; */
struct sockaddr_in sender_sock;
socklen_t i;
size_t msg_len;
time_t now;
struct peer_info *peer, *tmpPeer;
macstr_t mac_buf;
char time_buf[10]; /* 9 digits + 1 terminating zero */
char uptime_buf[11]; /* 10 digits + 1 terminating zero */
/* dec_ip_bit_str_t ip_bit_str = {'\0'}; */
/* dec_ip_str_t ip_str = {'\0'}; */
in_addr_t net;
n2n_sock_str_t sockbuf;
uint32_t num_pending_peers = 0;
uint32_t num_known_peers = 0;
uint32_t num = 0;
selection_criterion_str_t sel_buf;
now = time(NULL);
i = sizeof(sender_sock);
recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/
,
(struct sockaddr *) &sender_sock, (socklen_t *) &i);
if(recvlen < 0) {
traceEvent(TRACE_WARNING, "mgmt recvfrom failed: %d - %s", errno, strerr
or(errno));
return; /* failed to receive data from UDP */
}
/* avoid parsing any uninitialized junk from the stack */
udp_buf[recvlen] = 0;
if((0 == memcmp(udp_buf, "help", 4)) || (0 == memcmp(udp_buf, "?", 1))) {
msg_len = 0;
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - ms
g_len),
"Help for edge management console:\n"
"\tstop | Gracefully exit edge\n"
"\thelp | This help message\n"
"\t+verb | Increase verbosity of logging\n"
"\t-verb | Decrease verbosity of logging\n"
"\tr ... | start query with JSON reply\n"
"\tw ... | start update with JSON reply\n"
"\t<enter> | Display statistics\n\n");
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
return;
}
if(0 == memcmp(udp_buf, "stop", 4)) {
traceEvent(TRACE_NORMAL, "stop command received");
*eee->keep_running = 0;
return;
}
if(0 == memcmp(udp_buf, "+verb", 5)) {
msg_len = 0;
setTraceLevel(getTraceLevel() + 1);
traceEvent(TRACE_NORMAL, "+verb traceLevel=%u", (unsigned int) getTraceL
evel());
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - ms
g_len),
"> +OK traceLevel=%u\n", (unsigned int) getTraceLeve
l());
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
return;
}
if(0 == memcmp(udp_buf, "-verb", 5)) {
msg_len = 0;
if(getTraceLevel() > 0) {
setTraceLevel(getTraceLevel() - 1);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE
- msg_len),
"> -OK traceLevel=%u\n", getTraceLevel());
} else {
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE
- msg_len),
"> -NOK traceLevel=%u\n", getTraceLevel());
}
traceEvent(TRACE_NORMAL, "-verb traceLevel=%u", (unsigned int) getTraceL
evel());
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
return;
}
if((udp_buf[0] == 'r' || udp_buf[0] == 'w') && (udp_buf[1] == ' ')) {
/* this is a JSON request */
handleMgmtJson(eee, udp_buf, sender_sock);
return;
}
traceEvent(TRACE_DEBUG, "mgmt status requested");
msg_len = 0;
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"COMMUNITY '%s'\n\n",
(eee->conf.header_encryption == HEADER_ENCRYPTION_NONE)
? (char*)eee->conf.community_name : "-- header encrypted --");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
" ### | TAP | MAC | EDGE
| HINT | LAST SEEN | UPTIME\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"=======================================================
======================================================\n");
// dump nodes with forwarding through supernodes
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"SUPERNODE FORWARD\n");
num = 0;
HASH_ITER(hh, eee->pending_peers, peer, tmpPeer) {
++num_pending_peers;
net = htonl(peer->dev_addr.net_addr);
snprintf(time_buf, sizeof(time_buf), "%9u", (unsigned int)(now - peer->l
ast_seen));
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - ms
g_len),
"%4u | %-15s | %-17s | %-21s | %-15s | %9s |\n",
++num,
(peer->dev_addr.net_addr == 0) ? "" : inet_ntoa(*(st
ruct in_addr *) &net),
(is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac
_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc,
(peer->last_seen) ? time_buf : "");
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
msg_len = 0;
}
// dump peer-to-peer nodes
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"-------------------------------------------------------
------------------------------------------------------\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"PEER TO PEER\n");
num = 0;
HASH_ITER(hh, eee->known_peers, peer, tmpPeer) {
++num_known_peers;
net = htonl(peer->dev_addr.net_addr);
snprintf(time_buf, sizeof(time_buf), "%9u", (unsigned int)(now - peer->l
ast_seen));
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - ms
g_len),
"%4u | %-15s | %-17s | %-21s | %-15s | %9s |\n",
++num,
(peer->dev_addr.net_addr == 0) ? "" : inet_ntoa(*(st
ruct in_addr *) &net),
(is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac
_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc,
(peer->last_seen) ? time_buf : "");
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
msg_len = 0;
}
// dump supernodes
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"-------------------------------------------------------
------------------------------------------------------\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"SUPERNODES\n");
HASH_ITER(hh, eee->conf.supernodes, peer, tmpPeer) {
net = htonl(peer->dev_addr.net_addr);
snprintf(time_buf, sizeof(time_buf), "%9u", (unsigned int)(now - peer->l
ast_seen));
snprintf(uptime_buf, sizeof(uptime_buf), "%10u", (unsigned int)(peer->up
time));
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - ms
g_len),
"%-19s %1s%1s | %-17s | %-21s | %-15s | %9s | %10s\n
",
peer->version,
(peer->purgeable == SN_UNPURGEABLE) ? "l" : "",
(peer == eee->curr_sn) ? (eee->sn_wait ? "." : "*" )
: "",
is_null_mac(peer->mac_addr) ? "" : macaddr_str(mac_b
uf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)),
sn_selection_criterion_str(eee, sel_buf, peer),
(peer->last_seen) ? time_buf : "",
(peer->uptime) ? uptime_buf : "");
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
msg_len = 0;
}
// further stats
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"=======================================================
======================================================\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"uptime %lu | ",
time(NULL) - eee->start_time);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"pend_peers %u | ",
num_pending_peers);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"known_peers %u | ",
num_known_peers);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"transop %u,%u\n",
(unsigned int) eee->transop.tx_cnt,
(unsigned int) eee->transop.rx_cnt);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"super %u,%u | ",
(unsigned int) eee->stats.tx_sup,
(unsigned int) eee->stats.rx_sup);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"p2p %u,%u\n",
(unsigned int) eee->stats.tx_p2p,
(unsigned int) eee->stats.rx_p2p);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"last_super %ld sec ago | ",
(now - eee->last_sup));
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"last_p2p %ld sec ago\n",
(now - eee->last_p2p));
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_le
n),
"\nType \"help\" to see more commands.\n\n");
/* sendlen = */ sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct socka
ddr_in));
}
/* ************************************** */ /* ************************************** */
static int check_query_peer_info (n2n_edge_t *eee, time_t now, n2n_mac_t mac) { static int check_query_peer_info (n2n_edge_t *eee, time_t now, n2n_mac_t mac) {
struct peer_info *scan; struct peer_info *scan;
HASH_FIND_PEER(eee->pending_peers, mac, scan); HASH_FIND_PEER(eee->pending_peers, mac, scan);
if(!scan) { if(!scan) {
scan = calloc(1, sizeof(struct peer_info)); scan = calloc(1, sizeof(struct peer_info));
skipping to change at line 2074 skipping to change at line 1855
macaddr_str(mac_buf, mac_address)); macaddr_str(mac_buf, mac_address));
HASH_FIND_PEER(eee->known_peers, mac_address, scan); HASH_FIND_PEER(eee->known_peers, mac_address, scan);
if(scan && (scan->last_seen > 0)) { if(scan && (scan->last_seen > 0)) {
if((now - scan->last_p2p) >= (scan->timeout / 2)) { if((now - scan->last_p2p) >= (scan->timeout / 2)) {
/* Too much time passed since we saw the peer, need to register agai n /* Too much time passed since we saw the peer, need to register agai n
* since the peer address may have changed. */ * since the peer address may have changed. */
traceEvent(TRACE_DEBUG, "refreshing idle known peer"); traceEvent(TRACE_DEBUG, "refreshing idle known peer");
HASH_DEL(eee->known_peers, scan); HASH_DEL(eee->known_peers, scan);
mgmt_event_post(N2N_EVENT_PEER,N2N_EVENT_PEER_DEL_P2P,scan);
free(scan); free(scan);
/* NOTE: registration will be performed upon the receival of the nex t response packet */ /* NOTE: registration will be performed upon the receival of the nex t response packet */
} else { } else {
/* Valid known peer found */ /* Valid known peer found */
memcpy(destination, &scan->sock, sizeof(n2n_sock_t)); memcpy(destination, &scan->sock, sizeof(n2n_sock_t));
retval = 1; retval = 1;
} }
} }
if(retval == 0) { if(retval == 0) {
skipping to change at line 2154 skipping to change at line 1936
/* ************************************** */ /* ************************************** */
/** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */ /** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */
void edge_send_packet2net (n2n_edge_t * eee, void edge_send_packet2net (n2n_edge_t * eee,
uint8_t *tap_pkt, size_t len) { uint8_t *tap_pkt, size_t len) {
ipstr_t ip_buf; ipstr_t ip_buf;
n2n_mac_t destMac; n2n_mac_t destMac;
n2n_common_t cmn; n2n_common_t cmn;
n2n_PACKET_t pkt; n2n_PACKET_t pkt;
uint8_t *enc_src = tap_pkt;
size_t enc_len = len;
uint8_t compression_buf[N2N_PKT_BUF_SIZE];
uint8_t pktbuf[N2N_PKT_BUF_SIZE]; uint8_t pktbuf[N2N_PKT_BUF_SIZE];
size_t idx = 0; size_t idx = 0;
n2n_transform_t tx_transop_idx = eee->transop.transform_id; n2n_transform_t tx_transop_idx = eee->transop.transform_id;
ether_hdr_t eh; ether_hdr_t eh;
/* tap_pkt is not aligned so we have to copy to aligned memory */ /* tap_pkt is not aligned so we have to copy to aligned memory */
memcpy(&eh, tap_pkt, sizeof(ether_hdr_t)); memcpy(&eh, tap_pkt, sizeof(ether_hdr_t));
/* Discard IP packets that are not originated by this hosts */ /* Discard IP packets that are not originated by this hosts */
if(!(eee->conf.allow_routing)) { if(!(eee->conf.allow_routing)) {
skipping to change at line 2203 skipping to change at line 1988
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
memcpy(pkt.srcMac, eee->device.mac_addr, N2N_MAC_SIZE); memcpy(pkt.srcMac, eee->device.mac_addr, N2N_MAC_SIZE);
memcpy(pkt.dstMac, destMac, N2N_MAC_SIZE); memcpy(pkt.dstMac, destMac, N2N_MAC_SIZE);
pkt.transform = tx_transop_idx; pkt.transform = tx_transop_idx;
// compression needs to be tried before encode_PACKET is called for compress ion indication gets encoded there // compression needs to be tried before encode_PACKET is called for compress ion indication gets encoded there
pkt.compression = N2N_COMPRESSION_ID_NONE; pkt.compression = N2N_COMPRESSION_ID_NONE;
if(eee->conf.compression) { if(eee->conf.compression) {
uint8_t * compression_buffer = NULL;
int32_t compression_len; int32_t compression_len;
switch(eee->conf.compression) { switch(eee->conf.compression) {
case N2N_COMPRESSION_ID_LZO: case N2N_COMPRESSION_ID_LZO:
compression_buffer = malloc(len + len / 16 + 64 + 3); compression_len = eee->transop_lzo.fwd(&eee->transop_lzo,
if(lzo1x_1_compress(tap_pkt, len, compression_buffer, (lzo_uint* compression_buf, sizeof(c
)&compression_len, wrkmem) == LZO_E_OK) { ompression_buf),
if(compression_len < len) { tap_pkt, len,
pkt.compression = N2N_COMPRESSION_ID_LZO; pkt.dstMac);
}
if((compression_len > 0) && (compression_len < len)) {
pkt.compression = N2N_COMPRESSION_ID_LZO;
} }
break; break;
#ifdef N2N_HAVE_ZSTD
#ifdef HAVE_ZSTD
case N2N_COMPRESSION_ID_ZSTD: case N2N_COMPRESSION_ID_ZSTD:
compression_len = N2N_PKT_BUF_SIZE + 128; compression_len = eee->transop_zstd.fwd(&eee->transop_zstd,
compression_buffer = malloc(compression_len); // leaves enough compression_buf, sizeof(
room, for exact size call compression_len = ZSTD_compressBound (len); (slower) compression_buf),
compression_len = (int32_t)ZSTD_compress(compression_buffer, com tap_pkt, len,
pression_len, tap_pkt, len, ZSTD_COMPRESSION_LEVEL); pkt.dstMac);
if(!ZSTD_isError(compression_len)) {
if(compression_len < len) { if((compression_len > 0) && (compression_len < len)) {
pkt.compression = N2N_COMPRESSION_ID_ZSTD; pkt.compression = N2N_COMPRESSION_ID_ZSTD;
}
} else {
traceEvent(TRACE_ERROR, "payload compression failed with zst
d error '%s'.",
ZSTD_getErrorName(compression_len));
free(compression_buffer);
// continue with unset without pkt.compression --> will send
uncompressed
} }
break; break;
#endif #endif
default: default:
break; break;
} }
if(pkt.compression != N2N_COMPRESSION_ID_NONE) { if(pkt.compression != N2N_COMPRESSION_ID_NONE) {
traceEvent(TRACE_DEBUG, "payload compression [%s]: compressed %u byt es to %u bytes\n", traceEvent(TRACE_DEBUG, "payload compression [%s]: compressed %u byt es to %u bytes\n",
compression_str(pkt.compression), len, compression_len); compression_str(pkt.compression), len, compression_len);
enc_src = compression_buf;
memcpy(tap_pkt, compression_buffer, compression_len); enc_len = compression_len;
len = compression_len;
}
if(compression_buffer) {
free(compression_buffer);
} }
} }
idx = 0; idx = 0;
encode_PACKET(pktbuf, &idx, &cmn, &pkt); encode_PACKET(pktbuf, &idx, &cmn, &pkt);
uint16_t headerIdx = idx; uint16_t headerIdx = idx;
idx += eee->transop.fwd(&eee->transop, idx += eee->transop.fwd(&eee->transop,
pktbuf + idx, N2N_PKT_BUF_SIZE - idx, pktbuf + idx, N2N_PKT_BUF_SIZE - idx,
tap_pkt, len, pkt.dstMac); enc_src, enc_len, pkt.dstMac);
traceEvent(TRACE_DEBUG, "encode PACKET of %u bytes, %u bytes data, %u bytes overhead, transform %u", traceEvent(TRACE_DEBUG, "encode PACKET of %u bytes, %u bytes data, %u bytes overhead, transform %u",
(u_int)idx, (u_int)len, (u_int)(idx - len), tx_transop_idx); (u_int)idx, (u_int)len, (u_int)(idx - len), tx_transop_idx);
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
// in case of user-password auth, also encrypt the iv of payload assumin g ChaCha20 and SPECK having the same iv size // in case of user-password auth, also encrypt the iv of payload assumin g ChaCha20 and SPECK having the same iv size
packet_header_encrypt(pktbuf, headerIdx + (NULL != eee->conf.shared_secr et) * min(idx - headerIdx, N2N_SPECK_IVEC_SIZE), idx, packet_header_encrypt(pktbuf, headerIdx + (NULL != eee->conf.shared_secr et) * min(idx - headerIdx, N2N_SPECK_IVEC_SIZE), idx,
eee->conf.header_encryption_ctx_dynamic, eee->conf .header_iv_ctx_dynamic, eee->conf.header_encryption_ctx_dynamic, eee->conf .header_iv_ctx_dynamic,
time_stamp()); time_stamp());
skipping to change at line 2480 skipping to change at line 2258
return; return;
} }
} }
if(!eee->last_sup) { if(!eee->last_sup) {
// drop packets received before first registration with supe rnode // drop packets received before first registration with supe rnode
traceEvent(TRACE_DEBUG, "dropped PACKET recevied before firs t registration with supernode"); traceEvent(TRACE_DEBUG, "dropped PACKET recevied before firs t registration with supernode");
return; return;
} }
if(is_valid_peer_sock(&pkt.sock))
orig_sender = &(pkt.sock);
if(!from_supernode) { if(!from_supernode) {
/* This is a P2P packet from the peer. We purge a pending /* This is a P2P packet from the peer. We purge a pending
* registration towards the possibly nat-ted peer address as we now have * registration towards the possibly nat-ted peer address as we now have
* a valid channel. We still use check_peer_registration_nee ded in * a valid channel. We still use check_peer_registration_nee ded in
* handle_PACKET to double check this. * handle_PACKET to double check this.
*/ */
traceEvent(TRACE_DEBUG, "[p2p] from %s", traceEvent(TRACE_DEBUG, "[p2p] from %s",
macaddr_str(mac_buf1, pkt.srcMac)); macaddr_str(mac_buf1, pkt.srcMac));
find_and_remove_peer(&eee->pending_peers, pkt.srcMac); find_and_remove_peer(&eee->pending_peers, pkt.srcMac);
} else { } else {
/* [PsP] : edge Peer->Supernode->edge Peer */ /* [PsP] : edge Peer->Supernode->edge Peer */
if(is_valid_peer_sock(&pkt.sock))
orig_sender = &(pkt.sock);
traceEvent(TRACE_DEBUG, "[pSp] from %s via [%s]", traceEvent(TRACE_DEBUG, "[pSp] from %s via [%s]",
macaddr_str(mac_buf1, pkt.srcMac), macaddr_str(mac_buf1, pkt.srcMac),
sock_to_cstr(sockbuf1, &sender)); sock_to_cstr(sockbuf1, &sender));
} }
/* Update the sender in peer table entry */ /* Update the sender in peer table entry */
check_peer_registration_needed(eee, from_supernode, via_multicas t, check_peer_registration_needed(eee, from_supernode, via_multicas t,
pkt.srcMac, pkt.srcMac,
// REVISIT: also consider PORT_RE G_COOKIEs when implemented // REVISIT: also consider PORT_RE G_COOKIEs when implemented
from_supernode ? N2N_FORWARDED_RE G_COOKIE : N2N_REGULAR_REG_COOKIE, from_supernode ? N2N_FORWARDED_RE G_COOKIE : N2N_REGULAR_REG_COOKIE,
skipping to change at line 2805 skipping to change at line 2584
scan = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes) , &sender, pi.srcMac, &skip_add); scan = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes) , &sender, pi.srcMac, &skip_add);
if(scan != NULL) { if(scan != NULL) {
eee->sn_pong = 1; eee->sn_pong = 1;
scan->last_seen = now; scan->last_seen = now;
scan->uptime = pi.uptime; scan->uptime = pi.uptime;
memcpy(scan->version, pi.version, sizeof(n2n_version_t)) ; memcpy(scan->version, pi.version, sizeof(n2n_version_t)) ;
/* The data type depends on the actual selection strateg y that has been chosen. */ /* The data type depends on the actual selection strateg y that has been chosen. */
SN_SELECTION_CRITERION_DATA_TYPE sn_sel_tmp = pi.load; SN_SELECTION_CRITERION_DATA_TYPE sn_sel_tmp = pi.load;
sn_selection_criterion_calculate(eee, scan, &sn_sel_tmp) ; sn_selection_criterion_calculate(eee, scan, &sn_sel_tmp) ;
traceEvent(TRACE_INFO, "Rx PONG from supernode %s", traceEvent(TRACE_INFO, "Rx PONG from supernode %s versio
macaddr_str(mac_buf1, pi.srcMac)); n '%s'",
macaddr_str(mac_buf1, pi.srcMac),
pi.version);
break; break;
} }
} else { } else {
// regular PEER_INFO // regular PEER_INFO
HASH_FIND_PEER(eee->pending_peers, pi.mac, scan); HASH_FIND_PEER(eee->pending_peers, pi.mac, scan);
if(!scan) if(!scan)
// just in case the remote edge has been upgraded by the REG/ACK mechanism in the meantime // just in case the remote edge has been upgraded by the REG/ACK mechanism in the meantime
HASH_FIND_PEER(eee->known_peers, pi.mac, scan); HASH_FIND_PEER(eee->known_peers, pi.mac, scan);
skipping to change at line 3150 skipping to change at line 2930
eee->cb.main_loop_period(eee, now); eee->cb.main_loop_period(eee, now);
} /* while */ } /* while */
send_unregister_super(eee); send_unregister_super(eee);
#ifdef WIN32 #ifdef WIN32
WaitForSingleObject(tun_read_thread, INFINITE); WaitForSingleObject(tun_read_thread, INFINITE);
#endif #endif
closesocket(eee->sock); supernode_disconnect(eee);
return(0); return 0;
} }
/* ************************************** */ /* ************************************** */
/** Deinitialise the edge and deallocate any owned memory. */ /** Deinitialise the edge and deallocate any owned memory. */
void edge_term (n2n_edge_t * eee) { void edge_term (n2n_edge_t * eee) {
resolve_cancel_thread(eee->resolve_parameter); resolve_cancel_thread(eee->resolve_parameter);
#ifdef HAVE_PORT_FORWARDING
if(eee->conf.port_forwarding)
port_map_cancel_thread(eee->port_map_parameter);
#endif // HAVE_MINIUPNP || HAVE_NATPMP
if(eee->sock >= 0) if(eee->sock >= 0)
closesocket(eee->sock); closesocket(eee->sock);
if(eee->udp_mgmt_sock >= 0) if(eee->udp_mgmt_sock >= 0)
closesocket(eee->udp_mgmt_sock); closesocket(eee->udp_mgmt_sock);
#ifndef SKIP_MULTICAST_PEERS_DISCOVERY #ifndef SKIP_MULTICAST_PEERS_DISCOVERY
if(eee->udp_multicast_sock >= 0) if(eee->udp_multicast_sock >= 0)
closesocket(eee->udp_multicast_sock); closesocket(eee->udp_multicast_sock);
#endif #endif
clear_peer_list(&eee->pending_peers); clear_peer_list(&eee->pending_peers);
clear_peer_list(&eee->known_peers); clear_peer_list(&eee->known_peers);
eee->transop.deinit(&eee->transop); eee->transop.deinit(&eee->transop);
eee->transop_lzo.deinit(&eee->transop_lzo);
#ifdef HAVE_ZSTD
eee->transop_zstd.deinit(&eee->transop_zstd);
#endif
edge_cleanup_routes(eee); edge_cleanup_routes(eee);
destroy_network_traffic_filter(eee->network_traffic_filter); destroy_network_traffic_filter(eee->network_traffic_filter);
closeTraceFile(); closeTraceFile();
free(eee); free(eee);
} }
skipping to change at line 3679 skipping to change at line 3466
generate_private_key(*(conf->shared_secret), getenv("N2N_PASSWORD")) ; generate_private_key(*(conf->shared_secret), getenv("N2N_PASSWORD")) ;
} }
tmp_string = calloc(1, strlen(N2N_MGMT_PASSWORD) + 1); tmp_string = calloc(1, strlen(N2N_MGMT_PASSWORD) + 1);
if(tmp_string) { if(tmp_string) {
strncpy((char*)tmp_string, N2N_MGMT_PASSWORD, strlen(N2N_MGMT_PASSWORD) + 1); strncpy((char*)tmp_string, N2N_MGMT_PASSWORD, strlen(N2N_MGMT_PASSWORD) + 1);
conf->mgmt_password_hash = pearson_hash_64((uint8_t*)tmp_string, strlen( N2N_MGMT_PASSWORD)); conf->mgmt_password_hash = pearson_hash_64((uint8_t*)tmp_string, strlen( N2N_MGMT_PASSWORD));
free(tmp_string); free(tmp_string);
} }
#if defined(HAVE_MINIUPNP) || defined(HAVE_NATPMP)
conf->port_forwarding = 1;
#endif // HAVE_MINIUPNP || HAVE_NATPMP
conf->sn_selection_strategy = SN_SELECTION_STRATEGY_LOAD; conf->sn_selection_strategy = SN_SELECTION_STRATEGY_LOAD;
conf->metric = 0; conf->metric = 0;
} }
/* ************************************** */ /* ************************************** */
void edge_term_conf (n2n_edge_conf_t *conf) { void edge_term_conf (n2n_edge_conf_t *conf) {
if(conf->routes) free(conf->routes); if(conf->routes) free(conf->routes);
if(conf->encrypt_key) free(conf->encrypt_key); if(conf->encrypt_key) free(conf->encrypt_key);
 End of changes. 39 change blocks. 
360 lines changed or deleted 104 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)