Browse Source

Enhanced edge management console function.

1. Edge can view the IP address and socket information of the connected tap adapter through the management console (127.0.0.1:5644);
2. Repair two memory leaks;
3. Fix several code errors and redundant logic;
pull/369/head
fengdaolong 4 years ago
parent
commit
6bdfdf6be4
  1. 1
      include/n2n_wire.h
  2. 2
      src/edge.c
  3. 347
      src/edge_utils.c
  4. 14
      src/sn_utils.c
  5. 56
      src/wire.c

1
include/n2n_wire.h

@ -125,6 +125,7 @@ typedef struct n2n_REGISTER
n2n_mac_t srcMac; /**< MAC of registering party */ n2n_mac_t srcMac; /**< MAC of registering party */
n2n_mac_t dstMac; /**< MAC of target edge */ n2n_mac_t dstMac; /**< MAC of target edge */
n2n_sock_t sock; /**< REVISIT: unused? */ n2n_sock_t sock; /**< REVISIT: unused? */
n2n_ip_subnet_t dev_addr; /**< IP address of the tuntap adapter. */
} n2n_REGISTER_t; } n2n_REGISTER_t;
typedef struct n2n_REGISTER_ACK typedef struct n2n_REGISTER_ACK

2
src/edge.c

@ -978,9 +978,9 @@ int main(int argc, char* argv[]) {
#endif #endif
/* Cleanup */ /* Cleanup */
edge_term(eee);
edge_term_conf(&eee->conf); edge_term_conf(&eee->conf);
tuntap_close(&eee->device); tuntap_close(&eee->device);
edge_term(eee);
return(rc); return(rc);
} }

347
src/edge_utils.c

@ -27,18 +27,23 @@ static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
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); static void send_register(n2n_edge_t *eee, const n2n_sock_t *remote_peer, const n2n_mac_t peer_mac);
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,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_sock_t * peer); const n2n_ip_subnet_t *dev_addr,
const n2n_sock_t *peer);
static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, uint8_t tos); static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, uint8_t tos);
static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes); static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes);
static void edge_cleanup_routes(n2n_edge_t *eee); static void edge_cleanup_routes(n2n_edge_t *eee);
static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn); static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn);
static void check_known_peer_sock_change(n2n_edge_t * eee,
static void check_known_peer_sock_change(n2n_edge_t *eee,
uint8_t from_supernode, uint8_t from_supernode,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_sock_t * peer, const n2n_ip_subnet_t *dev_addr,
const n2n_sock_t *peer,
time_t when); time_t when);
/* ************************************** */ /* ************************************** */
@ -447,26 +452,26 @@ static void register_with_local_peers(n2n_edge_t * eee) {
* *
* Called from the main loop when Rx a packet for our device mac. * Called from the main loop when Rx a packet for our device mac.
*/ */
static void register_with_new_peer(n2n_edge_t * eee, static void register_with_new_peer(n2n_edge_t *eee,
uint8_t from_supernode, uint8_t from_supernode,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_sock_t * peer) { const n2n_ip_subnet_t *dev_addr,
const n2n_sock_t *peer) {
/* REVISIT: purge of pending_peers not yet done. */ /* REVISIT: purge of pending_peers not yet done. */
struct peer_info * scan; struct peer_info *scan;
macstr_t mac_buf; macstr_t mac_buf;
n2n_sock_str_t sockbuf; n2n_sock_str_t sockbuf;
HASH_FIND_PEER(eee->pending_peers, mac, scan); HASH_FIND_PEER(eee->pending_peers, mac, scan);
/* NOTE: pending_peers are purged periodically with purge_expired_registrations */ /* NOTE: pending_peers are purged periodically with purge_expired_registrations */
if(scan == NULL) { if (scan == NULL) {
scan = calloc(1, sizeof(struct peer_info)); scan = calloc(1, sizeof(struct peer_info));
memcpy(scan->mac_addr, mac, N2N_MAC_SIZE); memcpy(scan->mac_addr, mac, N2N_MAC_SIZE);
scan->sock = *peer; scan->sock = *peer;
scan->timeout = REGISTER_SUPER_INTERVAL_DFL; /* TODO: should correspond to the peer supernode registration timeout */ scan->timeout = eee->conf.register_interval; /* TODO: should correspond to the peer supernode registration timeout */
scan->last_seen = time(NULL); /* Don't change this it marks the pending peer for removal. */ scan->last_valid_time_stamp = initial_time_stamp();
scan->last_valid_time_stamp = initial_time_stamp ();
HASH_ADD_PEER(eee->pending_peers, scan); HASH_ADD_PEER(eee->pending_peers, scan);
@ -478,17 +483,17 @@ static void register_with_new_peer(n2n_edge_t * eee,
HASH_COUNT(eee->pending_peers)); HASH_COUNT(eee->pending_peers));
/* trace Sending REGISTER */ /* trace Sending REGISTER */
if(from_supernode) { if (from_supernode) {
/* UDP NAT hole punching through supernode. Send to peer first(punch local UDP hole) /* UDP NAT hole punching through supernode. Send to peer first(punch local UDP hole)
* and then ask supernode to forward. Supernode then ask peer to ack. Some nat device * and then ask supernode to forward. Supernode then ask peer to ack. Some nat device
* drop and block ports with incoming UDP packet if out-come traffic does not exist. * drop and block ports with incoming UDP packet if out-come traffic does not exist.
* So we can alternatively set TTL so that the packet sent to peer never really reaches * So we can alternatively set TTL so that the packet sent to peer never really reaches
* The register_ttl is basically nat level + 1. Set it to 1 means host like DMZ. * The register_ttl is basically nat level + 1. Set it to 1 means host like DMZ.
*/ */
if(eee->conf.register_ttl == 1) { if (eee->conf.register_ttl == 1) {
/* We are DMZ host or port is directly accessible. Just let peer to send back the ack */ /* We are DMZ host or port is directly accessible. Just let peer to send back the ack */
#ifndef WIN32 #ifndef WIN32
} else if(eee->conf.register_ttl > 1) { } else if (eee->conf.register_ttl > 1) {
/* Setting register_ttl usually implies that the edge knows the internal net topology /* Setting register_ttl usually implies that the edge knows the internal net topology
* clearly, we can apply aggressive port prediction to support incoming Symmetric NAT * clearly, we can apply aggressive port prediction to support incoming Symmetric NAT
*/ */
@ -497,15 +502,14 @@ static void register_with_new_peer(n2n_edge_t * eee,
n2n_sock_t sock = scan->sock; n2n_sock_t sock = scan->sock;
int alter = 16; /* TODO: set by command line or more reliable prediction method */ int alter = 16; /* TODO: set by command line or more reliable prediction method */
getsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *)(char *)&curTTL, &lenTTL); getsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *) (char *) &curTTL, &lenTTL);
setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL,
(void *)(char *)&eee->conf.register_ttl, (void *) (char *) &eee->conf.register_ttl,
sizeof(eee->conf.register_ttl)); sizeof(eee->conf.register_ttl));
for (; alter > 0; alter--, sock.port++) for (; alter > 0; alter--, sock.port++) {
{
send_register(eee, &sock, mac); send_register(eee, &sock, mac);
} }
setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *)(char *)&curTTL, sizeof(curTTL)); setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *) (char *) &curTTL, sizeof(curTTL));
#endif #endif
} else { /* eee->conf.register_ttl <= 0 */ } else { /* eee->conf.register_ttl <= 0 */
/* Normal STUN */ /* Normal STUN */
@ -518,34 +522,41 @@ static void register_with_new_peer(n2n_edge_t * eee,
} }
register_with_local_peers(eee); register_with_local_peers(eee);
} else } else{
scan->sock = *peer; scan->sock = *peer;
}
scan->last_seen = time(NULL);
if(dev_addr != NULL){
memcpy(&(scan->dev_addr), dev_addr, sizeof(n2n_ip_subnet_t));
}
} }
/* ************************************** */ /* ************************************** */
/** Update the last_seen time for this peer, or get registered. */ /** Update the last_seen time for this peer, or get registered. */
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,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_sock_t * peer) { const n2n_ip_subnet_t *dev_addr,
const n2n_sock_t *peer) {
struct peer_info *scan; struct peer_info *scan;
HASH_FIND_PEER(eee->known_peers, mac, scan); HASH_FIND_PEER(eee->known_peers, mac, scan);
if(scan == NULL) { if (scan == NULL) {
/* Not in known_peers - start the REGISTER process. */ /* Not in known_peers - start the REGISTER process. */
register_with_new_peer(eee, from_supernode, mac, peer); register_with_new_peer(eee, from_supernode, mac, dev_addr, peer);
} else { } else {
/* Already in known_peers. */ /* Already in known_peers. */
time_t now = time(NULL); time_t now = time(NULL);
if(!from_supernode) if (!from_supernode)
scan->last_p2p = now; scan->last_p2p = now;
if((now - scan->last_seen) > 0 /* >= 1 sec */) { if ((now - scan->last_seen) > 0 /* >= 1 sec */) {
/* Don't register too often */ /* Don't register too often */
check_known_peer_sock_change(eee, from_supernode, mac, peer, now); check_known_peer_sock_change(eee, from_supernode, mac, dev_addr, peer, now);
} }
} }
} }
@ -631,31 +642,32 @@ static const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
/** Check if a known peer socket has changed and possibly register again. /** Check if a known peer socket has changed and possibly register again.
*/ */
static void check_known_peer_sock_change(n2n_edge_t * eee, static void check_known_peer_sock_change(n2n_edge_t *eee,
uint8_t from_supernode, uint8_t from_supernode,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_sock_t * peer, const n2n_ip_subnet_t *dev_addr,
const n2n_sock_t *peer,
time_t when) { time_t when) {
struct peer_info *scan; struct peer_info *scan;
n2n_sock_str_t sockbuf1; n2n_sock_str_t sockbuf1;
n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */ n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */
macstr_t mac_buf; macstr_t mac_buf;
if(is_empty_ip_address(peer)) if (is_empty_ip_address(peer))
return; return;
if(!memcmp(mac, broadcast_mac, N2N_MAC_SIZE)) if (!memcmp(mac, broadcast_mac, N2N_MAC_SIZE))
return; return;
/* Search the peer in known_peers */ /* Search the peer in known_peers */
HASH_FIND_PEER(eee->known_peers, mac, scan); HASH_FIND_PEER(eee->known_peers, mac, scan);
if(!scan) if (!scan)
/* Not in known_peers */ /* Not in known_peers */
return; return;
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 changed %s: %s -> %s", traceEvent(TRACE_NORMAL, "Peer changed %s: %s -> %s",
macaddr_str(mac_buf, scan->mac_addr), macaddr_str(mac_buf, scan->mac_addr),
@ -665,7 +677,7 @@ static void check_known_peer_sock_change(n2n_edge_t * eee,
HASH_DEL(eee->known_peers, scan); HASH_DEL(eee->known_peers, scan);
free(scan); free(scan);
register_with_new_peer(eee, from_supernode, mac, peer); register_with_new_peer(eee, from_supernode, mac, dev_addr, 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. */
} }
@ -840,6 +852,9 @@ static void send_register(n2n_edge_t * eee,
idx=0; idx=0;
encode_mac(reg.dstMac, &idx, peer_mac); encode_mac(reg.dstMac, &idx, peer_mac);
} }
reg.dev_addr.net_addr = ntohl(eee->device.ip_addr);
reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask));
idx=0; idx=0;
encode_REGISTER(pktbuf, &idx, &cmn, &reg); encode_REGISTER(pktbuf, &idx, &cmn, &reg);
@ -976,13 +991,12 @@ static const char * supernode_ip(const n2n_edge_t * eee) {
/** A PACKET has arrived containing an encapsulated ethernet datagram - usually /** A PACKET has arrived containing an encapsulated ethernet datagram - usually
* encrypted. */ * encrypted. */
static int handle_PACKET(n2n_edge_t * eee, static int handle_PACKET(n2n_edge_t * eee,
const n2n_common_t * cmn, const uint8_t from_supernode,
const n2n_PACKET_t * pkt, const n2n_PACKET_t * pkt,
const n2n_sock_t * orig_sender, const n2n_sock_t * orig_sender,
uint8_t * payload, uint8_t * payload,
size_t psize) { size_t psize) {
ssize_t data_sent_len; ssize_t data_sent_len;
uint8_t from_supernode;
uint8_t * eth_payload=NULL; uint8_t * eth_payload=NULL;
int retval = -1; int retval = -1;
time_t now; time_t now;
@ -997,8 +1011,6 @@ static int handle_PACKET(n2n_edge_t * eee,
(unsigned int)psize, (unsigned int)pkt->transform); (unsigned int)psize, (unsigned int)pkt->transform);
/* hexdump(payload, psize); */ /* hexdump(payload, psize); */
from_supernode= cmn->flags & N2N_FLAGS_FROM_SUPERNODE;
if(from_supernode) if(from_supernode)
{ {
if(!memcmp(pkt->dstMac, broadcast_mac, N2N_MAC_SIZE)) if(!memcmp(pkt->dstMac, broadcast_mac, N2N_MAC_SIZE))
@ -1013,9 +1025,6 @@ static int handle_PACKET(n2n_edge_t * eee,
eee->last_p2p=now; eee->last_p2p=now;
} }
/* Update the sender in peer table entry */
check_peer_registration_needed(eee, from_supernode, pkt->srcMac, orig_sender);
/* Handle transform. */ /* Handle transform. */
{ {
uint8_t decodebuf[N2N_PKT_BUF_SIZE]; uint8_t decodebuf[N2N_PKT_BUF_SIZE];
@ -1134,185 +1143,223 @@ static int handle_PACKET(n2n_edge_t * eee,
/* ************************************** */ /* ************************************** */
#ifndef WIN32
static char *get_ip_from_arp(dec_ip_str_t buf, const n2n_mac_t req_mac) {
FILE *fd;
dec_ip_str_t ip_str = {'\0'};
char dev_str[N2N_IFNAMSIZ] = {'\0'};
macstr_t mac_str = {'\0'};
n2n_mac_t mac = {'\0'};
strncpy(buf, "0.0.0.0", N2N_NETMASK_STR_SIZE - 1);
if (0 == memcmp(null_mac, req_mac, sizeof(n2n_mac_t))){
traceEvent(TRACE_DEBUG, "MAC address is null.");
return buf;
}
if (!(fd = fopen("/proc/net/arp", "r"))) {
traceEvent(TRACE_ERROR, "Could not open arp table. [%d]: %s", errno, strerror(errno));
return buf;
}
while (!feof(fd) && fgetc(fd) != '\n');
while (!feof(fd) && (fscanf(fd, " %15[0-9.] %*s %*s %17[A-Fa-f0-9:] %*s %15s", ip_str, mac_str, dev_str) == 3)) {
str2mac(mac, mac_str);
if (0 == memcmp(mac, req_mac, sizeof(n2n_mac_t))) {
strncpy(buf, ip_str, N2N_NETMASK_STR_SIZE - 1);
break;
}
}
fclose(fd);
return buf;
}
#endif
/** Read a datagram from the management UDP socket and take appropriate /** Read a datagram from the management UDP socket and take appropriate
* action. */ * action. */
static void readFromMgmtSocket(n2n_edge_t * eee, int * keep_running) { static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) {
uint8_t udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */ char udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */
ssize_t recvlen; ssize_t recvlen;
/* ssize_t sendlen; */ /* ssize_t sendlen; */
struct sockaddr_in sender_sock; struct sockaddr_in sender_sock;
socklen_t i; socklen_t i;
size_t msg_len; size_t msg_len;
time_t now; time_t now;
n2n_sock_str_t sockbuf;
macstr_t mac_buf;
struct peer_info *peer, *tmpPeer; struct peer_info *peer, *tmpPeer;
dec_ip_bit_str_t ip_bit_str = {'\0'}; macstr_t mac_buf;
/* 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; uint32_t num = 0;
now = time(NULL); now = time(NULL);
i = sizeof(sender_sock); i = sizeof(sender_sock);
recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/, recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/,
(struct sockaddr *)&sender_sock, (socklen_t*)&i); (struct sockaddr *) &sender_sock, (socklen_t *) &i);
if(recvlen < 0) if (recvlen < 0) {
{
traceEvent(TRACE_ERROR, "mgmt recvfrom failed with %s", strerror(errno)); traceEvent(TRACE_ERROR, "mgmt recvfrom failed with %s", strerror(errno));
return; /* failed to receive data from UDP */ return; /* failed to receive data from UDP */
} }
if(recvlen >= 4) if ((0 == memcmp(udp_buf, "help", 4)) || (0 == memcmp(udp_buf, "?", 1))) {
{ msg_len = 0;
if(0 == memcmp(udp_buf, "stop", 4))
{
traceEvent(TRACE_ERROR, "stop command received.");
*keep_running = 0;
return;
}
if(0 == memcmp(udp_buf, "help", 4))
{
msg_len=0;
setTraceLevel(getTraceLevel()+1);
msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"Help for edge management console:\n" "Help for edge management console:\n"
" stop Gracefully exit edge\n" "\tstop | Gracefully exit edge\n"
" help This help message\n" "\thelp | This help message\n"
" +verb Increase verbosity of logging\n" "\t+verb | Increase verbosity of logging\n"
" -verb Decrease verbosity of logging\n" "\t-verb | Decrease verbosity of logging\n"
" <enter> Display statistics\n\n"); "\t<enter> | Display statistics\n\n");
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
return; return;
} }
if (0 == memcmp(udp_buf, "stop", 4)) {
traceEvent(TRACE_ERROR, "stop command received.");
*keep_running = 0;
return;
} }
if(recvlen >= 5) if (0 == memcmp(udp_buf, "+verb", 5)) {
{ msg_len = 0;
if(0 == memcmp(udp_buf, "+verb", 5)) setTraceLevel(getTraceLevel() + 1);
{
msg_len=0;
setTraceLevel(getTraceLevel()+1);
traceEvent(TRACE_ERROR, "+verb traceLevel=%u", (unsigned int)getTraceLevel()); traceEvent(TRACE_ERROR, "+verb traceLevel=%u", (unsigned int) getTraceLevel());
msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"> +OK traceLevel=%u\n", (unsigned int)getTraceLevel()); "> +OK traceLevel=%u\n", (unsigned int) getTraceLevel());
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
return; return;
} }
if(0 == memcmp(udp_buf, "-verb", 5)) if (0 == memcmp(udp_buf, "-verb", 5)) {
{ msg_len = 0;
msg_len=0;
if(getTraceLevel() > 0) if (getTraceLevel() > 0) {
{ setTraceLevel(getTraceLevel() - 1);
setTraceLevel(getTraceLevel()-1); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len),
"> -OK traceLevel=%u\n", getTraceLevel()); "> -OK traceLevel=%u\n", getTraceLevel());
} } else {
else msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
{
msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len),
"> -NOK traceLevel=%u\n", getTraceLevel()); "> -NOK traceLevel=%u\n", getTraceLevel());
} }
traceEvent(TRACE_ERROR, "-verb traceLevel=%u", (unsigned int)getTraceLevel()); traceEvent(TRACE_ERROR, "-verb traceLevel=%u", (unsigned int) getTraceLevel());
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
return; return;
} }
}
traceEvent(TRACE_DEBUG, "mgmt status rq"); traceEvent(TRACE_DEBUG, "mgmt status rq");
msg_len=0;
msg_len += snprintf((char*)&udp_buf[msg_len], (N2N_PKT_BUF_SIZE-msg_len),
"STATISTICS FOR EDGE\n");
msg_len += snprintf((char*)&udp_buf[msg_len], N2N_SN_PKTBUF_SIZE - msg_len,
"community: %s\n", eee->conf.community_name);
msg_len += snprintf((char*)&udp_buf[msg_len], N2N_SN_PKTBUF_SIZE - msg_len,
"\tid tun_tap MAC edge last_seen\n");
msg_len += snprintf((char*)&udp_buf[msg_len], N2N_SN_PKTBUF_SIZE - msg_len,
"--- pending peers -------------------------------------------------------------------\n");
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in));
msg_len = 0; msg_len = 0;
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"community: %s\n",
eee->conf.community_name);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
" id tun_tap MAC edge last_seen\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"------------------------------------------------------------------------------\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"supernode_forward:\n");
num = 0;
HASH_ITER(hh, eee->pending_peers, peer, tmpPeer) { HASH_ITER(hh, eee->pending_peers, peer, tmpPeer) {
msg_len += snprintf((char*)&udp_buf[msg_len], N2N_SN_PKTBUF_SIZE - msg_len, ++num_pending_peers;
"\t%-4u %-18s %-17s %-21s %lu\n", if(peer->dev_addr.net_addr == 0) continue;
++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr), net = htonl(peer->dev_addr.net_addr);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
" %-4u %-15s %-17s %-21s %lu\n",
++num, inet_ntoa(*(struct in_addr *) &net),
macaddr_str(mac_buf, peer->mac_addr), macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen); sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen);
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
msg_len = 0; msg_len = 0;
} }
msg_len += snprintf((char*)&udp_buf[msg_len], N2N_SN_PKTBUF_SIZE - msg_len, msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"--- known peers ---------------------------------------------------------------------\n"); "peer_to_peer:\n");
num = 0;
HASH_ITER(hh, eee->known_peers, peer, tmpPeer) { HASH_ITER(hh, eee->known_peers, peer, tmpPeer) {
msg_len += snprintf((char*)&udp_buf[msg_len], N2N_SN_PKTBUF_SIZE - msg_len, ++num_known_peers;
"\t%-4u %-18s %-17s %-21s %lu\n", if(peer->dev_addr.net_addr == 0) continue;
++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr), net = htonl(peer->dev_addr.net_addr);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
" %-4u %-15s %-17s %-21s %lu\n",
++num, inet_ntoa(*(struct in_addr *) &net),
macaddr_str(mac_buf, peer->mac_addr), macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen); sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen);
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
msg_len = 0; msg_len = 0;
} }
msg_len += snprintf((char*)&udp_buf[msg_len], N2N_SN_PKTBUF_SIZE - msg_len, msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"-------------------------------------------------------------------------------------\n"); "------------------------------------------------------------------------------\n");
msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"uptime %lu\n", "uptime %lu | ",
time(NULL) - eee->start_time); time(NULL) - eee->start_time);
msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"paths super:%u,%u p2p:%u,%u\n", "pend_peers %u | ",
(unsigned int)eee->stats.tx_sup, num_pending_peers);
(unsigned int)eee->stats.rx_sup,
(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_len), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"transop |%6u|%6u|\n", "known_peers %u | ",
(unsigned int)eee->transop.tx_cnt, num_known_peers);
(unsigned int)eee->transop.rx_cnt);
msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"peers pend:%u full:%u\n", "transop %u,%u\n",
HASH_COUNT(eee->pending_peers), (unsigned int) eee->transop.tx_cnt,
HASH_COUNT(eee->known_peers)); (unsigned int) eee->transop.rx_cnt);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"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_len), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"last super:%lu(%ld sec ago) p2p:%lu(%ld sec ago)\n", "p2p %u,%u\n",
eee->last_sup, (now-eee->last_sup), eee->last_p2p, (unsigned int) eee->stats.tx_p2p,
(now-eee->last_p2p)); (unsigned int) eee->stats.rx_p2p);
traceEvent(TRACE_DEBUG, "mgmt status sending: %s", udp_buf); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"last_super %ld sec ago | ",
(now - eee->last_sup));
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"last_p2p %ld sec ago\n",
(now - eee->last_p2p));
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"\nType \"help\" to see more commands.\n\n");
/* sendlen = */ sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, /* sendlen = */ sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_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) {
@ -1324,14 +1371,15 @@ static int check_query_peer_info(n2n_edge_t *eee, time_t now, n2n_mac_t mac) {
scan = calloc(1, sizeof(struct peer_info)); scan = calloc(1, sizeof(struct peer_info));
memcpy(scan->mac_addr, mac, N2N_MAC_SIZE); memcpy(scan->mac_addr, mac, N2N_MAC_SIZE);
scan->timeout = REGISTER_SUPER_INTERVAL_DFL; /* TODO: should correspond to the peer supernode registration timeout */ scan->timeout = eee->conf.register_interval; /* TODO: should correspond to the peer supernode registration timeout */
scan->last_seen = now; /* Don't change this it marks the pending peer for removal. */ scan->last_seen = now; /* Don't change this it marks the pending peer for removal. */
scan->last_valid_time_stamp = initial_time_stamp (); scan->last_valid_time_stamp = initial_time_stamp ();
HASH_ADD_PEER(eee->pending_peers, scan); HASH_ADD_PEER(eee->pending_peers, scan);
} }
if(now - scan->last_sent_query > REGISTER_SUPER_INTERVAL_DFL) { if(now - scan->last_sent_query > eee->conf.register_interval) {
send_register(eee, &(eee->supernode), mac);
send_query_peer(eee, scan->mac_addr); send_query_peer(eee, scan->mac_addr);
scan->last_sent_query = now; scan->last_sent_query = now;
return(0); return(0);
@ -1748,7 +1796,10 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
sock_to_cstr(sockbuf2, orig_sender), sock_to_cstr(sockbuf1, &sender), recvlen); sock_to_cstr(sockbuf2, orig_sender), sock_to_cstr(sockbuf1, &sender), recvlen);
} }
handle_PACKET(eee, &cmn, &pkt, orig_sender, udp_buf+idx, recvlen-idx); /* Update the sender in peer table entry */
check_peer_registration_needed(eee, from_supernode, pkt.srcMac, NULL, orig_sender);
handle_PACKET(eee, from_supernode, &pkt, orig_sender, udp_buf+idx, recvlen-idx);
break; break;
} }
case MSG_TYPE_REGISTER: case MSG_TYPE_REGISTER:
@ -1800,7 +1851,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf2, orig_sender)); sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf2, orig_sender));
} }
check_peer_registration_needed(eee, from_supernode, reg.srcMac, orig_sender); check_peer_registration_needed(eee, from_supernode, reg.srcMac, &reg.dev_addr, orig_sender);
break; break;
} }
case MSG_TYPE_REGISTER_ACK: case MSG_TYPE_REGISTER_ACK:

14
src/sn_utils.c

@ -474,9 +474,9 @@ static int process_mgmt(n2n_sn_t *sss,
traceEvent(TRACE_DEBUG, "process_mgmt"); traceEvent(TRACE_DEBUG, "process_mgmt");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"\tid tun_tap MAC edge last_seen\n"); " id tun_tap MAC edge last_seen\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"-------------------------------------------------------------------------------------\n"); "---------------------------------------------------------------------------------\n");
HASH_ITER(hh, sss->communities, community, tmp) { HASH_ITER(hh, sss->communities, community, tmp) {
num_edges += HASH_COUNT(community->edges); num_edges += HASH_COUNT(community->edges);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
@ -487,7 +487,7 @@ static int process_mgmt(n2n_sn_t *sss,
num = 0; num = 0;
HASH_ITER(hh, community->edges, peer, tmpPeer) { HASH_ITER(hh, community->edges, peer, tmpPeer) {
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"\t%-4u %-18s %-17s %-21s %lu\n", " %-4u %-18s %-17s %-21s %lu\n",
++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr), ++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr),
macaddr_str(mac_buf, peer->mac_addr), macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen); sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen);
@ -497,7 +497,7 @@ static int process_mgmt(n2n_sn_t *sss,
} }
} }
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"-------------------------------------------------------------------------------------\n"); "---------------------------------------------------------------------------------\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"uptime %lu | ", (now - sss->start_time)); "uptime %lu | ", (now - sss->start_time));
@ -530,7 +530,7 @@ static int process_mgmt(n2n_sn_t *sss,
"cur_cmnts %u\n", HASH_COUNT(sss->communities)); "cur_cmnts %u\n", HASH_COUNT(sss->communities));
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"last fwd %lu sec ago\n", "last_fwd %lu sec ago | ",
(long unsigned int) (now - sss->stats.last_fwd)); (long unsigned int) (now - sss->stats.last_fwd));
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
@ -811,10 +811,10 @@ static int process_udp(n2n_sn_t * sss,
reg.sock.port = ntohs(sender_sock->sin_port); reg.sock.port = ntohs(sender_sock->sin_port);
memcpy(reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); memcpy(reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
rec_buf = encbuf;
/* Re-encode the header. */ /* Re-encode the header. */
encode_REGISTER(encbuf, &encx, &cmn2, &reg); encode_REGISTER(encbuf, &encx, &cmn2, &reg);
rec_buf = encbuf;
} else { } else {
/* Already from a supernode. Nothing to modify, just pass to /* Already from a supernode. Nothing to modify, just pass to
* destination. */ * destination. */

56
src/wire.c

@ -251,40 +251,42 @@ int decode_sock( n2n_sock_t * sock,
return (idx-idx0); return (idx-idx0);
} }
int encode_REGISTER( uint8_t * base,
size_t * idx, int encode_REGISTER(uint8_t *base,
const n2n_common_t * common, size_t *idx,
const n2n_REGISTER_t * reg ) const n2n_common_t *common,
{ const n2n_REGISTER_t *reg) {
int retval=0; int retval = 0;
retval += encode_common( base, idx, common ); retval += encode_common(base, idx, common);
retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE);
retval += encode_mac( base, idx, reg->srcMac ); retval += encode_mac(base, idx, reg->srcMac);
retval += encode_mac( base, idx, reg->dstMac ); retval += encode_mac(base, idx, reg->dstMac);
if ( 0 != reg->sock.family ) if (0 != reg->sock.family) {
{ retval += encode_sock(base, idx, &(reg->sock));
retval += encode_sock( base, idx, &(reg->sock) );
} }
retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
return retval; return retval;
} }
int decode_REGISTER( n2n_REGISTER_t * reg,
const n2n_common_t * cmn, /* info on how to interpret it */
const uint8_t * base,
size_t * rem,
size_t * idx )
{
size_t retval=0;
memset( reg, 0, sizeof(n2n_REGISTER_t) );
retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx );
retval += decode_mac( reg->srcMac, base, rem, idx );
retval += decode_mac( reg->dstMac, base, rem, idx );
if ( cmn->flags & N2N_FLAGS_SOCKET ) int decode_REGISTER(n2n_REGISTER_t *reg,
{ const n2n_common_t *cmn, /* info on how to interpret it */
retval += decode_sock( &(reg->sock), base, rem, idx ); const uint8_t *base,
size_t *rem,
size_t *idx) {
size_t retval = 0;
memset(reg, 0, sizeof(n2n_REGISTER_t));
retval += decode_buf(reg->cookie, N2N_COOKIE_SIZE, base, rem, idx);
retval += decode_mac(reg->srcMac, base, rem, idx);
retval += decode_mac(reg->dstMac, base, rem, idx);
if (cmn->flags & N2N_FLAGS_SOCKET) {
retval += decode_sock(&(reg->sock), base, rem, idx);
} }
retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
return retval; return retval;
} }

Loading…
Cancel
Save