mirror of
https://github.com/ntop/n2n.git
synced 2024-09-19 16:41:11 +02:00
introduced n2n-portfwd tool (#1008)
* moved dev to version 3.1.1 * introduced n2n-portfwd tool * moved port-forwarding source to tool * adjusted tiny things, seemingly works with ./configure's --enable-miniupnp and --enable-natpmp * adjusted for Windows * wished for better typing skills * applied some finishing touch * typo
This commit is contained in:
parent
99b6b6b66d
commit
51a3a71f95
|
@ -125,9 +125,6 @@ if(N2N_OPTION_USE_PORTMAPPING)
|
||||||
add_subdirectory(${THIRD_PARTY_DIR}/libnatpmp libnatpmp)
|
add_subdirectory(${THIRD_PARTY_DIR}/libnatpmp libnatpmp)
|
||||||
link_directories(${PROJECT_BINARY_DIR}/libnatpmp)
|
link_directories(${PROJECT_BINARY_DIR}/libnatpmp)
|
||||||
|
|
||||||
# Turns on the generic code for supporting either of the above
|
|
||||||
ADD_DEFINITIONS("-DHAVE_PORT_FORWARDING")
|
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# - this is the odd one out, is it needed?
|
# - this is the odd one out, is it needed?
|
||||||
include_directories(${PROJECT_BINARY_DIR}/lib_miniupnpc)
|
include_directories(${PROJECT_BINARY_DIR}/lib_miniupnpc)
|
||||||
|
@ -264,6 +261,8 @@ add_executable(n2n-keygen tools/n2n-keygen.c)
|
||||||
target_link_libraries(n2n-keygen n2n)
|
target_link_libraries(n2n-keygen n2n)
|
||||||
add_executable(n2n-route tools/n2n-route.c)
|
add_executable(n2n-route tools/n2n-route.c)
|
||||||
target_link_libraries(n2n-route n2n)
|
target_link_libraries(n2n-route n2n)
|
||||||
|
add_executable(n2n-portfwd tools/n2n-portfwd.c)
|
||||||
|
target_link_libraries(n2n-portfwd n2n)
|
||||||
|
|
||||||
add_executable(tests-auth tools/tests-auth.c)
|
add_executable(tests-auth tools/tests-auth.c)
|
||||||
target_link_libraries(tests-auth n2n)
|
target_link_libraries(tests-auth n2n)
|
||||||
|
|
|
@ -62,7 +62,6 @@ AS_IF([test "x$enable_miniupnp" != xno],
|
||||||
[AC_CHECK_LIB([miniupnpc], [upnpDiscover],
|
[AC_CHECK_LIB([miniupnpc], [upnpDiscover],
|
||||||
[
|
[
|
||||||
AC_DEFINE([HAVE_MINIUPNP], [1], [Have miniupnp library])
|
AC_DEFINE([HAVE_MINIUPNP], [1], [Have miniupnp library])
|
||||||
AC_DEFINE([HAVE_PORT_FORWARDING],[1],[upnp libs are used])
|
|
||||||
N2N_LIBS="-lminiupnpc ${N2N_LIBS}"
|
N2N_LIBS="-lminiupnpc ${N2N_LIBS}"
|
||||||
],
|
],
|
||||||
[AC_MSG_ERROR([miniupnp library not found])]
|
[AC_MSG_ERROR([miniupnp library not found])]
|
||||||
|
@ -76,7 +75,6 @@ AS_IF([test "x$enable_natpmp" != xno],
|
||||||
[AC_CHECK_LIB([natpmp], [initnatpmp],
|
[AC_CHECK_LIB([natpmp], [initnatpmp],
|
||||||
[
|
[
|
||||||
AC_DEFINE([HAVE_NATPMP], [1], [Have natpmp library])
|
AC_DEFINE([HAVE_NATPMP], [1], [Have natpmp library])
|
||||||
AC_DEFINE([HAVE_PORT_FORWARDING],[1],[upnp libs are used])
|
|
||||||
N2N_LIBS="-lnatpmp ${N2N_LIBS}"
|
N2N_LIBS="-lnatpmp ${N2N_LIBS}"
|
||||||
],
|
],
|
||||||
[AC_MSG_ERROR([natpmp library not found])]
|
[AC_MSG_ERROR([natpmp library not found])]
|
||||||
|
|
5
edge.8
5
edge.8
|
@ -109,11 +109,6 @@ defaults to load-based selection strategy if not provided.
|
||||||
\fB\-\-select-mac\fR
|
\fB\-\-select-mac\fR
|
||||||
select supernode by MAC address if several to choose from (federation),
|
select supernode by MAC address if several to choose from (federation),
|
||||||
lowest MAC address first.
|
lowest MAC address first.
|
||||||
.TP
|
|
||||||
\fB\-\-no-port-forwarding\fR
|
|
||||||
disables the default behavior of trying to have the edge's port forwarded
|
|
||||||
through a router eventually supporting it (only if compiled with miniupnp
|
|
||||||
and/or natpmp library support).
|
|
||||||
.SH TAP DEVICE AND OVERLAY NETWORK CONFIGURATION
|
.SH TAP DEVICE AND OVERLAY NETWORK CONFIGURATION
|
||||||
.TP
|
.TP
|
||||||
\fB\-a \fR[\fImode\fR]<\fIip\fR>[\fI/n\fR]
|
\fB\-a \fR[\fImode\fR]<\fIip\fR>[\fI/n\fR]
|
||||||
|
|
|
@ -158,9 +158,7 @@
|
||||||
#include "network_traffic_filter.h"
|
#include "network_traffic_filter.h"
|
||||||
#include "auth.h"
|
#include "auth.h"
|
||||||
|
|
||||||
#if defined(HAVE_MINIUPNP) || defined(HAVE_NATPMP)
|
|
||||||
#include "n2n_port_mapping.h"
|
#include "n2n_port_mapping.h"
|
||||||
#endif // HAVE_MINIUPNP || HAVE_NATPMP
|
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,12 @@
|
||||||
#ifndef _N2N_PORT_MAPPING_H_
|
#ifndef _N2N_PORT_MAPPING_H_
|
||||||
#define _N2N_PORT_MAPPING_H_
|
#define _N2N_PORT_MAPPING_H_
|
||||||
|
|
||||||
#ifdef HAVE_PORT_FORWARDING
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef HAVE_MINIUPNP
|
#ifdef HAVE_MINIUPNP
|
||||||
#ifdef CMAKE_BUILD
|
#ifdef CMAKE_BUILD
|
||||||
// CMAKE uses static linked lib as submodule which requires different includes than
|
// CMAKE uses statically linked lib as submodule which requires different includes than
|
||||||
// the dynamically linked, intalled library in case of plain make
|
// the dynamically linked, intalled library in case of plain make
|
||||||
#include <miniupnpc.h>
|
#include <miniupnpc.h>
|
||||||
#include <upnpcommands.h>
|
#include <upnpcommands.h>
|
||||||
|
@ -44,8 +43,8 @@
|
||||||
#endif // HAVE_NATPMP
|
#endif // HAVE_NATPMP
|
||||||
|
|
||||||
|
|
||||||
void n2n_chg_port_mapping (struct n2n_edge *eee, const uint16_t port);
|
void n2n_set_port_mapping (const uint16_t port);
|
||||||
|
void n2n_del_port_mapping (const uint16_t port);
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_PORT_FORWARDING
|
|
||||||
#endif // _N2N_PORT_MAPPING_H_
|
#endif // _N2N_PORT_MAPPING_H_
|
||||||
|
|
|
@ -634,21 +634,6 @@ typedef struct n2n_resolve_parameter {
|
||||||
/* *************************************************** */
|
/* *************************************************** */
|
||||||
|
|
||||||
|
|
||||||
// structure to hold port mapping thread's parameters
|
|
||||||
typedef struct n2n_port_map_parameter {
|
|
||||||
#ifdef HAVE_PTHREAD
|
|
||||||
pthread_t id; /* thread id */
|
|
||||||
pthread_mutex_t access; /* mutex for shared access */
|
|
||||||
#endif
|
|
||||||
uint16_t mgmt_port;
|
|
||||||
uint16_t mapped_port;
|
|
||||||
uint16_t new_port; /* REVISIT: remove with management port subscriptions */
|
|
||||||
} n2n_port_map_parameter_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************************** */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct n2n_edge_conf {
|
typedef struct n2n_edge_conf {
|
||||||
struct peer_info *supernodes; /**< List of supernodes */
|
struct peer_info *supernodes; /**< List of supernodes */
|
||||||
n2n_community_t community_name; /**< The community. 16 full octets. */
|
n2n_community_t community_name; /**< The community. 16 full octets. */
|
||||||
|
@ -686,7 +671,6 @@ typedef struct n2n_edge_conf {
|
||||||
uint8_t sn_selection_strategy; /**< encodes currently chosen supernode selection strategy. */
|
uint8_t sn_selection_strategy; /**< encodes currently chosen supernode selection strategy. */
|
||||||
uint8_t number_max_sn_pings; /**< Number of maximum concurrently allowed supernode pings. */
|
uint8_t number_max_sn_pings; /**< Number of maximum concurrently allowed supernode pings. */
|
||||||
uint64_t mgmt_password_hash; /**< contains hash of managament port password. */
|
uint64_t mgmt_password_hash; /**< contains hash of managament port password. */
|
||||||
uint8_t port_forwarding; /**< indicates if port forwarding UPNP/PMP is enabled */
|
|
||||||
} n2n_edge_conf_t;
|
} n2n_edge_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -747,8 +731,6 @@ struct n2n_edge {
|
||||||
n2n_resolve_parameter_t *resolve_parameter; /**< Pointer to name resolver's parameter block */
|
n2n_resolve_parameter_t *resolve_parameter; /**< Pointer to name resolver's parameter block */
|
||||||
uint8_t resolution_request; /**< Flag an immediate DNS resolution request */
|
uint8_t resolution_request; /**< Flag an immediate DNS resolution request */
|
||||||
|
|
||||||
n2n_port_map_parameter_t *port_map_parameter; /**< Pointer to port mapping thread's parameter block */
|
|
||||||
|
|
||||||
n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */
|
n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */
|
||||||
|
|
||||||
network_traffic_filter_t *network_traffic_filter;
|
network_traffic_filter_t *network_traffic_filter;
|
||||||
|
|
15
src/edge.c
15
src/edge.c
|
@ -234,9 +234,6 @@ static void help (int level) {
|
||||||
"\n [-E] accept multicast MAC addresses"
|
"\n [-E] accept multicast MAC addresses"
|
||||||
"\n [--select-rtt] select supernode by round trip time"
|
"\n [--select-rtt] select supernode by round trip time"
|
||||||
"\n [--select-mac] select supernode by MAC address"
|
"\n [--select-mac] select supernode by MAC address"
|
||||||
#if defined(HAVE_MINIUPNP) || defined(HAVE_NATPMP)
|
|
||||||
"\n [--no-port-forwarding] disable UPnP/PMP port forwarding"
|
|
||||||
#endif // HAVE_MINIUPNP || HAVE_NATPMP
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
"\n [-f] do not fork but run in foreground"
|
"\n [-f] do not fork but run in foreground"
|
||||||
#endif
|
#endif
|
||||||
|
@ -298,11 +295,6 @@ static void help (int level) {
|
||||||
printf("--select-rtt | supernode selection based on round trip time\n"
|
printf("--select-rtt | supernode selection based on round trip time\n"
|
||||||
"--select-mac | supernode selection based on MAC address (default:\n"
|
"--select-mac | supernode selection based on MAC address (default:\n"
|
||||||
" | by load)\n");
|
" | by load)\n");
|
||||||
#if defined(HAVE_MINIUPNP) || defined(HAVE_NATPMP)
|
|
||||||
printf("--no-port-... | disable UPnP/PMP port forwarding\n"
|
|
||||||
"...forwarding | \n");
|
|
||||||
#endif // HAVE_MINIUPNP || HAVE_NATPMP
|
|
||||||
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf (" TAP DEVICE AND OVERLAY NETWORK CONFIGURATION\n");
|
printf (" TAP DEVICE AND OVERLAY NETWORK CONFIGURATION\n");
|
||||||
printf (" --------------------------------------------\n\n");
|
printf (" --------------------------------------------\n\n");
|
||||||
|
@ -728,12 +720,6 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '}': /* disable port forwarding */ {
|
|
||||||
conf->port_forwarding = 0;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'h': /* quick reference */ {
|
case 'h': /* quick reference */ {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -790,7 +776,6 @@ static const struct option long_options[] =
|
||||||
{ "select-rtt", no_argument, NULL, '[' }, /* '[' rtt selection strategy */
|
{ "select-rtt", no_argument, NULL, '[' }, /* '[' rtt selection strategy */
|
||||||
{ "select-mac", no_argument, NULL, ']' }, /* ']' mac selection strategy */
|
{ "select-mac", no_argument, NULL, ']' }, /* ']' mac selection strategy */
|
||||||
{ "management-password", required_argument, NULL, '{' }, /* '{' management port password */
|
{ "management-password", required_argument, NULL, '{' }, /* '{' management port password */
|
||||||
{ "no-port-forwarding", no_argument, NULL, '}' }, /* '}' disable port forwarding */
|
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,7 @@ static void mgmt_edge_info (mgmt_req_t *req, strbuf_t *buf) {
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
struct in_addr ip_addr, ip_addr_mask;
|
struct in_addr ip_addr, ip_addr_mask;
|
||||||
ipstr_t ip_address, ip_address_mask;
|
ipstr_t ip_address, ip_address_mask;
|
||||||
|
n2n_sock_str_t sockbuf;
|
||||||
|
|
||||||
ip_addr.s_addr = req->eee->device.ip_addr;
|
ip_addr.s_addr = req->eee->device.ip_addr;
|
||||||
inaddrtoa(ip_address, ip_addr);
|
inaddrtoa(ip_address, ip_addr);
|
||||||
|
@ -178,11 +179,13 @@ static void mgmt_edge_info (mgmt_req_t *req, strbuf_t *buf) {
|
||||||
"\"version\":\"%s\","
|
"\"version\":\"%s\","
|
||||||
"\"macaddr\":\"%s\","
|
"\"macaddr\":\"%s\","
|
||||||
"\"ip4addr\":\"%s\","
|
"\"ip4addr\":\"%s\","
|
||||||
"\"ip4netmask\":\"%s\"}\n",
|
"\"ip4netmask\":\"%s\","
|
||||||
|
"\"sockaddr\":\"%s\"}\n",
|
||||||
req->tag,
|
req->tag,
|
||||||
PACKAGE_VERSION,
|
PACKAGE_VERSION,
|
||||||
is_null_mac(req->eee->device.mac_addr) ? "" : macaddr_str(mac_buf, req->eee->device.mac_addr),
|
is_null_mac(req->eee->device.mac_addr) ? "" : macaddr_str(mac_buf, req->eee->device.mac_addr),
|
||||||
ip_address, ip_address_mask);
|
ip_address, ip_address_mask,
|
||||||
|
sock_to_cstr(sockbuf, &req->eee->conf.preferred_sock));
|
||||||
|
|
||||||
send_reply(req, buf, msg_len);
|
send_reply(req, buf, msg_len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,6 @@ int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn
|
||||||
int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_t now);
|
int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_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);
|
||||||
|
|
||||||
|
@ -329,12 +324,9 @@ int supernode_connect (n2n_edge_t *eee) {
|
||||||
eee->cb.sock_opened(eee);
|
eee->cb.sock_opened(eee);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PORT_FORWARDING
|
// REVISIT: add mgmt port notification to listener for better mgmt port
|
||||||
if(eee->conf.port_forwarding)
|
// subscription support
|
||||||
// REVISIT: replace with mgmt port notification to listener for mgmt port
|
|
||||||
// subscription support
|
|
||||||
n2n_chg_port_mapping(eee, eee->conf.preferred_sock.port);
|
|
||||||
#endif // HAVE_PORT_FORWARDING
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,12 +482,7 @@ n2n_edge_t* edge_init (const n2n_edge_conf_t *conf, int *rv) {
|
||||||
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.network_traffic_filter_rules);
|
network_traffic_filter_add_rule(eee->network_traffic_filter, eee->conf.network_traffic_filter_rules);
|
||||||
|
|
||||||
|
@ -2993,10 +2980,7 @@ int run_edge_loop (n2n_edge_t *eee) {
|
||||||
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);
|
||||||
|
|
||||||
|
@ -3117,10 +3101,6 @@ void edge_init_conf_defaults (n2n_edge_conf_t *conf) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@
|
||||||
|
|
||||||
#include "n2n.h"
|
#include "n2n.h"
|
||||||
|
|
||||||
#ifdef HAVE_PORT_FORWARDING
|
|
||||||
|
|
||||||
#ifdef HAVE_MINIUPNP
|
#ifdef HAVE_MINIUPNP
|
||||||
|
|
||||||
|
@ -463,9 +462,12 @@ static int n2n_natpmp_del_port_mapping (const uint16_t port) {
|
||||||
#endif // HAVE_NATPMP
|
#endif // HAVE_NATPMP
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
// ----------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------
|
||||||
|
// public
|
||||||
|
|
||||||
static void n2n_set_port_mapping (const uint16_t port) {
|
|
||||||
|
void n2n_set_port_mapping (const uint16_t port) {
|
||||||
|
|
||||||
#ifdef HAVE_NATPMP
|
#ifdef HAVE_NATPMP
|
||||||
// since the NAT-PMP protocol is more concise than UPnP, NAT-PMP is preferred.
|
// since the NAT-PMP protocol is more concise than UPnP, NAT-PMP is preferred.
|
||||||
|
@ -479,7 +481,7 @@ static void n2n_set_port_mapping (const uint16_t port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void n2n_del_port_mapping (const uint16_t port) {
|
void n2n_del_port_mapping (const uint16_t port) {
|
||||||
|
|
||||||
#ifdef HAVE_NATPMP
|
#ifdef HAVE_NATPMP
|
||||||
if(n2n_natpmp_del_port_mapping(port))
|
if(n2n_natpmp_del_port_mapping(port))
|
||||||
|
@ -490,151 +492,3 @@ static void n2n_del_port_mapping (const uint16_t port) {
|
||||||
#endif // HAVE_MINIUPNP
|
#endif // HAVE_MINIUPNP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
|
||||||
// ----------------------------------------------------------------------------------------------------
|
|
||||||
// public
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD /* future management port subscriptions will deprecate the following temporary code */
|
|
||||||
void n2n_chg_port_mapping (struct n2n_edge *eee, uint16_t port) {
|
|
||||||
// write a port change request to param struct, it will be handled in the thread
|
|
||||||
pthread_mutex_lock(&eee->port_map_parameter->access);
|
|
||||||
eee->port_map_parameter->new_port = port;
|
|
||||||
pthread_mutex_unlock(&eee->port_map_parameter->access);
|
|
||||||
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error "enabling port mapping requires enabling pthread"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
N2N_THREAD_RETURN_DATATYPE port_map_thread(N2N_THREAD_PARAMETER_DATATYPE p) {
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD /* future management port subscriptions will deprecate the following temporary code */
|
|
||||||
n2n_port_map_parameter_t *param = (n2n_port_map_parameter_t*)p;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
sleep(2);
|
|
||||||
pthread_mutex_lock(¶m->access);
|
|
||||||
if(param->mapped_port != param->new_port) {
|
|
||||||
if(param->mapped_port)
|
|
||||||
n2n_del_port_mapping(param->mapped_port);
|
|
||||||
if(param->new_port)
|
|
||||||
n2n_set_port_mapping(param->new_port);
|
|
||||||
param->mapped_port = param->new_port;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(¶m->access);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0 /* to be used with future management port subscriptions */
|
|
||||||
n2n_port_map_parameter_t *param = (n2n_port_map_parameter_t*)p;
|
|
||||||
SOCKET socket_fd;
|
|
||||||
fd_set socket_mask;
|
|
||||||
struct timeval wait_time;
|
|
||||||
int ret = 0;
|
|
||||||
char udp_buf[N2N_PKT_BUF_SIZE];
|
|
||||||
ssize_t msg_len;
|
|
||||||
uint32_t addr_tmp = htonl(INADDR_LOOPBACK);
|
|
||||||
n2n_sock_t sock_tmp;
|
|
||||||
struct sockaddr_in sock;
|
|
||||||
socklen_t sock_len;
|
|
||||||
|
|
||||||
// open a new socket ...
|
|
||||||
socket_fd = open_socket(0 /* no specific port */, INADDR_LOOPBACK, 0 /* UDP */);
|
|
||||||
if(socket_fd < 0) {
|
|
||||||
traceEvent(TRACE_ERROR, "port_map_thread failed to open a socket to management port");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// ... and connect to local mgmt port
|
|
||||||
sock_tmp.family = AF_INET;
|
|
||||||
memcpy(&sock_tmp.addr.v4, &addr_tmp, IPV4_SIZE);
|
|
||||||
sock_tmp.port = param->mgmt_port;
|
|
||||||
sock_len = sizeof(sock);
|
|
||||||
fill_sockaddr((struct sockaddr*)&sock, sock_len, &sock_tmp);
|
|
||||||
connect(socket_fd, (struct sockaddr*)&sock, sock_len);
|
|
||||||
|
|
||||||
// prepare a subscription request in 'udp_buf' of length 'msg_len'
|
|
||||||
// !!! dummy
|
|
||||||
udp_buf[0] = '\n';
|
|
||||||
msg_len = 1;
|
|
||||||
send(socket_fd, udp_buf, msg_len, 0 /*flags*/);
|
|
||||||
// note: 'msg_len' and 'sock' get re-used hereafter
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
FD_ZERO(&socket_mask);
|
|
||||||
FD_SET(socket_fd, &socket_mask);
|
|
||||||
|
|
||||||
wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS;
|
|
||||||
wait_time.tv_usec = 0;
|
|
||||||
|
|
||||||
ret = select(socket_fd + 1, &socket_mask, NULL, NULL, &wait_time);
|
|
||||||
|
|
||||||
if(ret > 0) {
|
|
||||||
if(FD_ISSET(socket_fd, &socket_mask)) {
|
|
||||||
// get the data
|
|
||||||
sock_len = sizeof(sock);
|
|
||||||
msg_len = recv(socket_fd, udp_buf, N2N_PKT_BUF_SIZE, 0 /*flags*/);
|
|
||||||
|
|
||||||
// check message format, first message could be the still buffered answer to the subscription request
|
|
||||||
// !!!
|
|
||||||
if(1 /* !!! correct message format */) {
|
|
||||||
// delete an eventually previous port mapping
|
|
||||||
if(param->mapped_port)
|
|
||||||
n2n_del_port_mapping(param->mapped_port);
|
|
||||||
// extract port from message and set accordingly if valid
|
|
||||||
param->mapped_port = 0; // !!!
|
|
||||||
if(param->mapped_port)
|
|
||||||
n2n_set_port_mapping(param->mapped_port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0; /* should never happen */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int port_map_create_thread (n2n_port_map_parameter_t **param, uint16_t mgmt_port) {
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// create parameter structure
|
|
||||||
*param = (n2n_port_map_parameter_t*)calloc(1, sizeof(n2n_port_map_parameter_t));
|
|
||||||
if(*param) {
|
|
||||||
// initialize
|
|
||||||
(*param)->mgmt_port = mgmt_port;
|
|
||||||
} else {
|
|
||||||
traceEvent(TRACE_WARNING, "port_map_create_thread was unable to create parameter structure");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create thread
|
|
||||||
ret = pthread_create(&((*param)->id), NULL, port_map_thread, (void *)*param);
|
|
||||||
if(ret) {
|
|
||||||
traceEvent(TRACE_WARNING, "port_map_create_thread failed to create port mapping thread with error number %d", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void port_map_cancel_thread (n2n_port_map_parameter_t *param) {
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD
|
|
||||||
pthread_cancel(param->id);
|
|
||||||
if(param->mapped_port)
|
|
||||||
n2n_del_port_mapping(param->mapped_port);
|
|
||||||
free(param);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAVE_PORT_FORWARDING
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ LDFLAGS+=-L..
|
||||||
|
|
||||||
N2N_LIB=../libn2n.a
|
N2N_LIB=../libn2n.a
|
||||||
|
|
||||||
TOOLS=n2n-benchmark n2n-keygen n2n-route
|
TOOLS=n2n-benchmark n2n-keygen n2n-route n2n-portfwd
|
||||||
TOOLS+=@ADDITIONAL_TOOLS@
|
TOOLS+=@ADDITIONAL_TOOLS@
|
||||||
|
|
||||||
TESTS=tests-compress tests-elliptic tests-hashing tests-transform
|
TESTS=tests-compress tests-elliptic tests-hashing tests-transform
|
||||||
|
@ -27,6 +27,7 @@ all: $(TOOLS) $(TESTS)
|
||||||
n2n-benchmark.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
n2n-benchmark.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
||||||
n2n-keygen.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
n2n-keygen.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
||||||
n2n-route.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
n2n-route.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
||||||
|
n2n-portfwd.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
||||||
|
|
||||||
n2n-decode: n2n-decode.c $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
n2n-decode: n2n-decode.c $(N2N_LIB) $(HEADERS) ../Makefile Makefile
|
||||||
$(CC) $(CFLAGS) $< $(LDFLAGS) $(LDLIBS) -lpcap -o $@
|
$(CC) $(CFLAGS) $< $(LDFLAGS) $(LDLIBS) -lpcap -o $@
|
||||||
|
|
376
tools/n2n-portfwd.c
Normal file
376
tools/n2n-portfwd.c
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
/**
|
||||||
|
* (C) 2007-22 - ntop.org and contributors
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "n2n.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define WITH_PORT 1
|
||||||
|
#define CORRECT_TAG 2
|
||||||
|
|
||||||
|
#define SOCKET_TIMEOUT 2
|
||||||
|
#define INFO_INTERVAL 5
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define STDIN_FILENO _fileno(stdin)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct n2n_portfwd_conf {
|
||||||
|
uint16_t port; /* management port */
|
||||||
|
} n2n_portfwd_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
static int keep_running = 1; /* for main loop, handled by signals */
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
// PLATFORM-DEPENDANT CODE (FOR NON-MANDATORY FEATURE)
|
||||||
|
|
||||||
|
|
||||||
|
void set_term_handler(const void *handler) {
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
signal(SIGTERM, handler);
|
||||||
|
signal(SIGINT, handler);
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
SetConsoleCtrlHandler(handler, TRUE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
BOOL WINAPI term_handler (DWORD sig) {
|
||||||
|
#else
|
||||||
|
static void term_handler (int sig) {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int called = 0;
|
||||||
|
|
||||||
|
if(called) {
|
||||||
|
traceEvent(TRACE_NORMAL, "ok, leaving now");
|
||||||
|
_exit(0);
|
||||||
|
} else {
|
||||||
|
traceEvent(TRACE_NORMAL, "shutting down...");
|
||||||
|
called = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_running = 0;
|
||||||
|
#ifdef WIN32
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
SOCKET connect_to_management_port (n2n_portfwd_conf_t *ppp) {
|
||||||
|
|
||||||
|
SOCKET ret;
|
||||||
|
struct sockaddr_in sock_addr;
|
||||||
|
|
||||||
|
ret = socket (PF_INET, SOCK_DGRAM, 0);
|
||||||
|
if((int)ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sock_addr.sin_family = AF_INET;
|
||||||
|
sock_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
sock_addr.sin_port = htons(ppp->port);
|
||||||
|
if(0 != connect(ret, (struct sockaddr *)&sock_addr, sizeof(sock_addr)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
int get_port_from_json (uint16_t *port, json_object_t *json, char *key, int tag, int flags) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
char *colon = NULL;
|
||||||
|
|
||||||
|
if(NULL == json)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(i = 0; i < json->count; i++) {
|
||||||
|
if(json->pairs[i].type == JSON_STRING) {
|
||||||
|
if(!strcmp(json->pairs[i].key, key)) {
|
||||||
|
// cut off port from IP address
|
||||||
|
if((colon = strchr(json->pairs[i].value->string_value, ':'))) {
|
||||||
|
if(*colon != '\0') {
|
||||||
|
*port = atoi(colon + 1);
|
||||||
|
flags |= WITH_PORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!strcmp(json->pairs[i].key, "_tag" )) {
|
||||||
|
if(atoi(json->pairs[i].value->string_value) == tag) {
|
||||||
|
flags |= CORRECT_TAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(json->pairs[i].type == JSON_OBJECT) {
|
||||||
|
flags |= get_port_from_json(port, json, key, tag, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// taken from https://web.archive.org/web/20170407122137/http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/
|
||||||
|
int kbhit () {
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set fds;
|
||||||
|
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
|
||||||
|
select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
return FD_ISSET(STDIN_FILENO, &fds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
static void help (int level) {
|
||||||
|
|
||||||
|
if(level == 0) return; /* no help required */
|
||||||
|
|
||||||
|
printf(" n2n-portfwd [-t <manangement_port>] [-V] [-v]"
|
||||||
|
"\n"
|
||||||
|
"\n This tool tries to find a router in local network and asks it to"
|
||||||
|
"\n forward the edge's port(UDP and TCP) by sending corresponding"
|
||||||
|
"\n UPnP and PMP requests."
|
||||||
|
"\n\n Adapt port (default: %d) to match your edge's management port"
|
||||||
|
"\n configuration."
|
||||||
|
"\n\n Verbosity can be increased or decreased with -V or -v , repeat as"
|
||||||
|
"\n as needed."
|
||||||
|
"\n\n",
|
||||||
|
N2N_EDGE_MGMT_PORT);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int set_option (n2n_portfwd_conf_t *ppp, int optkey, char *optargument) {
|
||||||
|
|
||||||
|
switch(optkey) {
|
||||||
|
case 't': /* management port */ {
|
||||||
|
uint16_t port = atoi(optargument);
|
||||||
|
if(port) {
|
||||||
|
ppp->port = port;
|
||||||
|
} else {
|
||||||
|
traceEvent(TRACE_WARNING, "invalid management port provided with '-t'");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'V': /* more verbose */ {
|
||||||
|
setTraceLevel(getTraceLevel() + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'v': /* less verbose */ {
|
||||||
|
setTraceLevel(getTraceLevel() - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: /* unknown option */ {
|
||||||
|
return 1; /* for help */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char* argv[]) {
|
||||||
|
|
||||||
|
n2n_portfwd_conf_t ppp;
|
||||||
|
uint8_t c;
|
||||||
|
SOCKET sock;
|
||||||
|
size_t msg_len;
|
||||||
|
char udp_buf[N2N_PKT_BUF_SIZE];
|
||||||
|
fd_set socket_mask;
|
||||||
|
struct timeval wait_time;
|
||||||
|
time_t now = 0;
|
||||||
|
time_t last_info_req = 0;
|
||||||
|
json_object_t *json;
|
||||||
|
int ret;
|
||||||
|
int tag_info;
|
||||||
|
uint16_t port = 0, current_port = 0;
|
||||||
|
|
||||||
|
// version
|
||||||
|
print_n2n_version();
|
||||||
|
|
||||||
|
// ensure prerequisites
|
||||||
|
#ifndef HAVE_MINIUPNP
|
||||||
|
traceEvent(TRACE_WARNING, "no miniupnp support compiled");
|
||||||
|
#else
|
||||||
|
traceEvent(TRACE_NORMAL, "compiled with miniupnp support");
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_NATPMP
|
||||||
|
traceEvent(TRACE_WARNING, "no natpmp support compiled");
|
||||||
|
#else
|
||||||
|
traceEvent(TRACE_NORMAL, "compiled with natpmp support");
|
||||||
|
#endif
|
||||||
|
#if !defined(HAVE_MINIUPNP) && !defined(HAVE_NATPMP)
|
||||||
|
traceEvent(TRACE_WARNING, "no port forwarding method found");
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// handle signals to properly end the tool
|
||||||
|
set_term_handler(term_handler);
|
||||||
|
|
||||||
|
// init data structure
|
||||||
|
ppp.port = N2N_EDGE_MGMT_PORT;
|
||||||
|
setTraceLevel(2); /* NORMAL, should already be default */
|
||||||
|
n2n_srand(n2n_seed());
|
||||||
|
|
||||||
|
// get command line options and eventually overwrite initialized conf
|
||||||
|
while((c = getopt_long(argc, argv, "t:vV", NULL, NULL)) != '?') {
|
||||||
|
if(c == 255) break;
|
||||||
|
help(set_option(&ppp, c, optarg));
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify conf and react with output to conf-related changes
|
||||||
|
// (nothing to do)
|
||||||
|
|
||||||
|
// additional checks
|
||||||
|
// (nothing to do)
|
||||||
|
|
||||||
|
// connect to mamagement port
|
||||||
|
traceEvent(TRACE_NORMAL, "connecting to edge management port %d", ppp.port);
|
||||||
|
sock = connect_to_management_port(&ppp);
|
||||||
|
if(sock == -1) {
|
||||||
|
traceEvent(TRACE_ERROR, "unable to open socket for management port connection");
|
||||||
|
goto end_route_tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
// output status
|
||||||
|
traceEvent(TRACE_NORMAL, "press ENTER to end the program");
|
||||||
|
|
||||||
|
reset_main_loop:
|
||||||
|
|
||||||
|
wait_time.tv_sec = SOCKET_TIMEOUT;
|
||||||
|
wait_time.tv_usec = 0;
|
||||||
|
port = 0;
|
||||||
|
current_port = 0;
|
||||||
|
tag_info = 0;
|
||||||
|
|
||||||
|
// main loop
|
||||||
|
// read answer packet by packet which are only accepted if a corresponding request was sent before
|
||||||
|
// of which we know about by having set the related tag, tag_info
|
||||||
|
// a valid sock address indicates that we have seen a valid answer to the info request
|
||||||
|
while(keep_running && !kbhit()) {
|
||||||
|
// current time
|
||||||
|
now = time(NULL);
|
||||||
|
|
||||||
|
// check if we need to send info request again
|
||||||
|
if(now > last_info_req + INFO_INTERVAL) {
|
||||||
|
// send info read request
|
||||||
|
while(!(tag_info = ((uint32_t)n2n_rand()) >> 23));
|
||||||
|
msg_len = 0;
|
||||||
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
|
||||||
|
"r %u info\n", tag_info);
|
||||||
|
ret = send(sock, udp_buf, msg_len, 0);
|
||||||
|
last_info_req = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for any answer to info or read request
|
||||||
|
FD_ZERO(&socket_mask);
|
||||||
|
FD_SET(sock, &socket_mask);
|
||||||
|
ret = select(sock + 1, &socket_mask, NULL, NULL, &wait_time);
|
||||||
|
|
||||||
|
// refresh current time after having waited
|
||||||
|
now = time(NULL);
|
||||||
|
|
||||||
|
if(ret > 0) {
|
||||||
|
if(FD_ISSET(sock, &socket_mask)) {
|
||||||
|
msg_len = recv(sock, udp_buf, sizeof(udp_buf), 0);
|
||||||
|
if((msg_len > 0) && (msg_len < sizeof(udp_buf))) {
|
||||||
|
// make sure it is a string and replace all newlines with spaces
|
||||||
|
udp_buf[msg_len] = '\0';
|
||||||
|
for (char *p = udp_buf; (p = strchr(p, '\n')) != NULL; p++) *p = ' ';
|
||||||
|
traceEvent(TRACE_DEBUG, "received '%s' from management port", udp_buf);
|
||||||
|
|
||||||
|
// handle the answer, json needs to be freed later
|
||||||
|
json = json_parse(udp_buf);
|
||||||
|
|
||||||
|
// look for local edge information
|
||||||
|
if(tag_info) {
|
||||||
|
// local IP address port
|
||||||
|
port = 0;
|
||||||
|
ret = get_port_from_json(&port, json, "sockaddr", tag_info, 0);
|
||||||
|
if(ret == (WITH_PORT | CORRECT_TAG)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "received information about edge port %d", port);
|
||||||
|
// evaluate current situation and take appropriate action
|
||||||
|
if(port != current_port) {
|
||||||
|
traceEvent(TRACE_NORMAL, "found edge port %d", port);
|
||||||
|
if(current_port)
|
||||||
|
n2n_del_port_mapping(current_port);
|
||||||
|
if(port)
|
||||||
|
n2n_set_port_mapping(port);
|
||||||
|
current_port = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need for current json object anymore
|
||||||
|
json_free(json);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// can this happen? reset the loop
|
||||||
|
traceEvent(TRACE_ERROR, "loop reset");
|
||||||
|
goto reset_main_loop;
|
||||||
|
}
|
||||||
|
} else if(ret == 0) {
|
||||||
|
// select() timeout
|
||||||
|
// action required?
|
||||||
|
} else {
|
||||||
|
// select() error
|
||||||
|
// action required?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end_route_tool:
|
||||||
|
|
||||||
|
// delete port forwarding if any
|
||||||
|
if(current_port)
|
||||||
|
n2n_del_port_mapping(current_port);
|
||||||
|
|
||||||
|
// close connection
|
||||||
|
closesocket(sock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user