|
@ -342,7 +342,7 @@ static int mgmt_auth (n2n_edge_t *eee, const struct sockaddr_in sender_sock, enu |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void handleMgmtJson (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock) { |
|
|
static void handleMgmtJson (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock) { |
|
|
|
|
|
|
|
|
char cmdlinebuf[80]; |
|
|
char cmdlinebuf[80]; |
|
|
enum n2n_mgmt_type type; |
|
|
enum n2n_mgmt_type type; |
|
@ -455,3 +455,234 @@ void handleMgmtJson (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in se |
|
|
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); |
|
|
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Read a datagram from the management UDP socket and take appropriate
|
|
|
|
|
|
* action. */ |
|
|
|
|
|
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, strerror(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 - msg_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) getTraceLevel()); |
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"> +OK traceLevel=%u\n", (unsigned int) getTraceLevel()); |
|
|
|
|
|
|
|
|
|
|
|
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) getTraceLevel()); |
|
|
|
|
|
|
|
|
|
|
|
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_len), |
|
|
|
|
|
"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_len), |
|
|
|
|
|
" ### | TAP | MAC | EDGE | HINT | LAST SEEN | UPTIME\n"); |
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"=============================================================================================================\n"); |
|
|
|
|
|
|
|
|
|
|
|
// dump nodes with forwarding through supernodes
|
|
|
|
|
|
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) { |
|
|
|
|
|
++num_pending_peers; |
|
|
|
|
|
net = htonl(peer->dev_addr.net_addr); |
|
|
|
|
|
snprintf(time_buf, sizeof(time_buf), "%9u", (unsigned int)(now - peer->last_seen)); |
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"%4u | %-15s | %-17s | %-21s | %-15s | %9s |\n", |
|
|
|
|
|
++num, |
|
|
|
|
|
(peer->dev_addr.net_addr == 0) ? "" : inet_ntoa(*(struct 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_len), |
|
|
|
|
|
"-------------------------------------------------------------------------------------------------------------\n"); |
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"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->last_seen)); |
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"%4u | %-15s | %-17s | %-21s | %-15s | %9s |\n", |
|
|
|
|
|
++num, |
|
|
|
|
|
(peer->dev_addr.net_addr == 0) ? "" : inet_ntoa(*(struct 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_len), |
|
|
|
|
|
"-------------------------------------------------------------------------------------------------------------\n"); |
|
|
|
|
|
|
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"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->last_seen)); |
|
|
|
|
|
snprintf(uptime_buf, sizeof(uptime_buf), "%10u", (unsigned int)(peer->uptime)); |
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_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_buf, 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_len), |
|
|
|
|
|
"=============================================================================================================\n"); |
|
|
|
|
|
|
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"uptime %lu | ", |
|
|
|
|
|
time(NULL) - eee->start_time); |
|
|
|
|
|
|
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"pend_peers %u | ", |
|
|
|
|
|
num_pending_peers); |
|
|
|
|
|
|
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"known_peers %u | ", |
|
|
|
|
|
num_known_peers); |
|
|
|
|
|
|
|
|
|
|
|
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), |
|
|
|
|
|
"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_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), |
|
|
|
|
|
"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_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*/, |
|
|
|
|
|
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); |
|
|
|
|
|
} |
|
|