Cosmetic changes to improve edge registration tracing

This commit is contained in:
emanuele-f 2019-05-05 19:09:51 +02:00
parent fbc3754601
commit 856dbae44c
4 changed files with 120 additions and 122 deletions

View File

@ -54,12 +54,17 @@
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); static void send_register(n2n_edge_t * eee, const n2n_sock_t * remote_peer);
static void check_peer(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_sock_t * peer);
static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port); static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port);
static void supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn); static void supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn);
static void check_known_peer_sock_change(n2n_edge_t * eee,
uint8_t from_supernode,
const n2n_mac_t mac,
const n2n_sock_t * peer,
time_t when);
/* ************************************** */ /* ************************************** */
@ -205,6 +210,26 @@ edge_init_error:
/* ***************************************************** */ /* ***************************************************** */
static inline void update_peer_seen(struct peer_info *peer, time_t t) {
peer->last_seen = t;
}
/* ***************************************************** */
static void remove_peer_from_list(struct peer_info **head, struct peer_info *prev,
struct peer_info *scan) {
/* Remove the peer. */
if(prev == NULL)
/* scan was head of list */
*head = scan->next;
else
prev->next = scan->next;
free(scan);
}
/* ***************************************************** */
/** Resolve the supernode IP address. /** Resolve the supernode IP address.
* *
* REVISIT: This is a really bad idea. The edge will block completely while the * REVISIT: This is a really bad idea. The edge will block completely while the
@ -294,7 +319,7 @@ 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 try_send_register(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_sock_t * peer) {
@ -303,6 +328,7 @@ static void try_send_register(n2n_edge_t * eee,
macstr_t mac_buf; macstr_t mac_buf;
n2n_sock_str_t sockbuf; n2n_sock_str_t sockbuf;
/* TODO: remove from pending_peers after a timeout was reached to retry */
if(scan == NULL) { if(scan == NULL) {
scan = calloc(1, sizeof(struct peer_info)); scan = calloc(1, sizeof(struct peer_info));
@ -329,7 +355,7 @@ static void try_send_register(n2n_edge_t * eee,
/* ************************************** */ /* ************************************** */
/** 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(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_sock_t * peer) {
@ -337,27 +363,25 @@ static void check_peer(n2n_edge_t * eee,
if(scan == NULL) { if(scan == NULL) {
/* Not in known_peers - start the REGISTER process. */ /* Not in known_peers - start the REGISTER process. */
try_send_register(eee, from_supernode, mac, peer); register_with_new_peer(eee, from_supernode, mac, peer);
} else { } else {
/* Already in known_peers. */ /* Already in known_peers. */
time_t now = time(NULL); time_t now = time(NULL);
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 */
update_peer_address(eee, from_supernode, mac, peer, now); check_known_peer_sock_change(eee, from_supernode, mac, peer, now);
} }
} }
} }
/* ************************************** */ /* ************************************** */
/* Move the peer from the pending_peers list to the known_peers lists. /* Confirm that a pending peer is reachable directly via P2P.
* *
* peer must be a pointer to an element of the pending_peers list. * peer must be a pointer to an element of the pending_peers list.
*
* Called by main loop when Rx a REGISTER_ACK.
*/ */
static void set_peer_operational(n2n_edge_t * eee, static void peer_set_p2p_confirmed(n2n_edge_t * eee,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_sock_t * peer) { const n2n_sock_t * peer) {
struct peer_info * prev = NULL; struct peer_info * prev = NULL;
@ -365,7 +389,7 @@ static void set_peer_operational(n2n_edge_t * eee,
macstr_t mac_buf; macstr_t mac_buf;
n2n_sock_str_t sockbuf; n2n_sock_str_t sockbuf;
traceEvent(TRACE_INFO, "set_peer_operational: %s -> %s", traceEvent(TRACE_INFO, "peer_set_p2p_confirmed: %s -> %s",
macaddr_str(mac_buf, mac), macaddr_str(mac_buf, mac),
sock_to_cstr(sockbuf, peer)); sock_to_cstr(sockbuf, peer));
@ -409,7 +433,7 @@ static void set_peer_operational(n2n_edge_t * eee,
traceEvent(TRACE_INFO, "Pending peers list size=%u", traceEvent(TRACE_INFO, "Pending peers list size=%u",
(unsigned int)peer_list_size(eee->pending_peers)); (unsigned int)peer_list_size(eee->pending_peers));
traceEvent(TRACE_INFO, "Operational peers list size=%u", traceEvent(TRACE_INFO, "Known peers list size=%u",
(unsigned int)peer_list_size(eee->known_peers)); (unsigned int)peer_list_size(eee->known_peers));
@ -457,14 +481,9 @@ int is_empty_ip_address(const n2n_sock_t * sock) {
/* ************************************** */ /* ************************************** */
/** Keep the known_peers list straight. /** Check if a known peer socket has changed and possibly register again.
*
* Ignore broadcast L2 packets, and packets with invalid public_ip.
* If the dst_mac is in known_peers make sure the entry is correct:
* - if the public_ip socket has changed, erase the entry
* - if the same, update its last_seen = when
*/ */
void update_peer_address(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_sock_t * peer,
@ -476,69 +495,41 @@ void update_peer_address(n2n_edge_t * eee,
macstr_t mac_buf; macstr_t mac_buf;
if(is_empty_ip_address(peer)) if(is_empty_ip_address(peer))
{ return;
/* Not to be registered. */
return;
}
if(0 == memcmp(mac, broadcast_mac, N2N_MAC_SIZE)) if(!memcmp(mac, broadcast_mac, N2N_MAC_SIZE))
{ return;
/* Not to be registered. */
return;
}
/* Search the peer in known_peers */
while(scan != NULL) while(scan != NULL) {
{
if(memcmp(mac, scan->mac_addr, N2N_MAC_SIZE) == 0) if(memcmp(mac, scan->mac_addr, N2N_MAC_SIZE) == 0)
{
break; break;
}
prev = scan; prev = scan;
scan = scan->next; scan = scan->next;
} }
if(NULL == scan) if(!scan)
{ /* Not in known_peers */
/* Not in known_peers. */ return;
return;
}
if(0 != sock_equal(&(scan->sock), peer)) if(!sock_equal(&(scan->sock), peer)) {
{ if(!from_supernode) {
if(0 == from_supernode) /* 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),
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 to be reachable. */ /* The peer has changed public socket. It can no longer be assumed to be reachable. */
/* Remove the peer. */ remove_peer_from_list(&eee->known_peers, prev, scan);
if(NULL == prev)
{
/* scan was head of list */
eee->known_peers = scan->next;
}
else
{
prev->next = scan->next;
}
free(scan);
try_send_register(eee, from_supernode, mac, peer); register_with_new_peer(eee, 0 /* p2p */, mac, 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 /* TODO add max registration check */
{ update_peer_seen(scan, when);
/* Found and unchanged. */
scan->last_seen = when;
}
} }
/* ************************************** */ /* ************************************** */
@ -782,7 +773,7 @@ static int handle_PACKET(n2n_edge_t * eee,
} }
/* Update the sender in peer table entry */ /* Update the sender in peer table entry */
check_peer(eee, from_supernode, pkt->srcMac, orig_sender); check_peer_registration_needed(eee, from_supernode, pkt->srcMac, orig_sender);
/* Handle transform. */ /* Handle transform. */
{ {
@ -1308,7 +1299,9 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE;
if(0 == memcmp(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE)) { if(0 == memcmp(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE)) {
if(msg_type == MSG_TYPE_PACKET) { switch(msg_type) {
case MSG_TYPE_PACKET:
{
/* process PACKET - most frequent so first in list. */ /* process PACKET - most frequent so first in list. */
n2n_PACKET_t pkt; n2n_PACKET_t pkt;
@ -1324,7 +1317,10 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
sock_to_cstr(sockbuf2, orig_sender)); sock_to_cstr(sockbuf2, orig_sender));
handle_PACKET(eee, &cmn, &pkt, orig_sender, udp_buf+idx, recvlen-idx); handle_PACKET(eee, &cmn, &pkt, orig_sender, udp_buf+idx, recvlen-idx);
} else if(msg_type == MSG_TYPE_REGISTER) { break;
}
case MSG_TYPE_REGISTER:
{
/* Another edge is registering with us */ /* Another edge is registering with us */
n2n_REGISTER_t reg; n2n_REGISTER_t reg;
n2n_mac_t null_mac = { '\0' }; n2n_mac_t null_mac = { '\0' };
@ -1342,11 +1338,11 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
sock_to_cstr(sockbuf2, orig_sender)); sock_to_cstr(sockbuf2, orig_sender));
if(!memcmp(reg.dstMac, eee->device.mac_addr, 6)) if(!memcmp(reg.dstMac, eee->device.mac_addr, 6))
check_peer(eee, from_supernode, reg.srcMac, orig_sender); check_peer_registration_needed(eee, from_supernode, reg.srcMac, orig_sender);
else if(// (sender.port == N2N_MULTICAST_PORT) && else if(// (sender.port == N2N_MULTICAST_PORT) &&
(!memcmp(reg.dstMac, null_mac, 6))) { /* Announce via a multicast socket */ (!memcmp(reg.dstMac, null_mac, 6))) { /* Announce via a multicast socket */
if(memcmp(reg.srcMac, eee->device.mac_addr, 6)) /* It's not our self-announce */ if(memcmp(reg.srcMac, eee->device.mac_addr, 6)) /* It's not our self-announce */
check_peer(eee, from_supernode, reg.srcMac, orig_sender); check_peer_registration_needed(eee, from_supernode, reg.srcMac, orig_sender);
else { else {
traceEvent(TRACE_INFO, "Skipping REGISTER from self"); traceEvent(TRACE_INFO, "Skipping REGISTER from self");
skip_register = 1; /* do not register with ourselves */ skip_register = 1; /* do not register with ourselves */
@ -1355,9 +1351,10 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
if(!skip_register) if(!skip_register)
send_register_ack(eee, orig_sender, &reg); send_register_ack(eee, orig_sender, &reg);
} break;
else if(msg_type == MSG_TYPE_REGISTER_ACK) }
{ case MSG_TYPE_REGISTER_ACK:
{
/* Peer edge is acknowledging our register request */ /* Peer edge is acknowledging our register request */
n2n_REGISTER_ACK_t ra; n2n_REGISTER_ACK_t ra;
@ -1372,11 +1369,11 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf1, &sender),
sock_to_cstr(sockbuf2, orig_sender)); sock_to_cstr(sockbuf2, orig_sender));
/* Move from pending_peers to known_peers; ignore if not in pending. */ peer_set_p2p_confirmed(eee, ra.srcMac, &sender);
set_peer_operational(eee, ra.srcMac, &sender); break;
} }
else if(msg_type == MSG_TYPE_REGISTER_SUPER_ACK) case MSG_TYPE_REGISTER_SUPER_ACK:
{ {
n2n_REGISTER_SUPER_ACK_t ra; n2n_REGISTER_SUPER_ACK_t ra;
if(eee->sn_wait) if(eee->sn_wait)
@ -1420,18 +1417,15 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
{ {
traceEvent(TRACE_WARNING, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER."); traceEvent(TRACE_WARNING, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER.");
} }
} break;
else }
{ default:
/* Not a known message type */ /* Not a known message type */
traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type);
return; return;
} } /* switch(msg_type) */
} /* if (community match) */ } else /* if (community match) */
else traceEvent(TRACE_WARNING, "Received packet with invalid community");
{
traceEvent(TRACE_WARNING, "Received packet with invalid community");
}
} }
/* ************************************** */ /* ************************************** */

35
n2n.c
View File

@ -460,27 +460,24 @@ extern char * sock_to_cstr(n2n_sock_str_t out,
} }
} }
/* @return zero if the two sockets are equivalent. */ /* @return 1 if the two sockets are equivalent. */
int sock_equal(const n2n_sock_t * a, int sock_equal(const n2n_sock_t * a,
const n2n_sock_t * b) { const n2n_sock_t * b) {
if(a->port != b->port) { return 1; } if(a->port != b->port) { return(0); }
if(a->family != b->family) { return 1; } if(a->family != b->family) { return(0); }
switch(a->family) {
case AF_INET:
if(0 != memcmp(a->addr.v4, b->addr.v4, IPV4_SIZE)) {
return 1;
}
break;
default:
if(0 != memcmp(a->addr.v6, b->addr.v6, IPV6_SIZE)) {
return 1;
}
break;
}
return 0; switch(a->family) {
case AF_INET:
if(memcmp(a->addr.v4, b->addr.v4, IPV4_SIZE))
return(0);
break;
default:
if(memcmp(a->addr.v6, b->addr.v6, IPV6_SIZE))
return(0);
break;
}
/* equal */
return(1);
} }

5
n2n.h
View File

@ -277,11 +277,6 @@ size_t purge_peer_list( struct peer_info ** peer_list,
time_t purge_before ); time_t purge_before );
size_t clear_peer_list( struct peer_info ** peer_list ); size_t clear_peer_list( struct peer_info ** peer_list );
size_t purge_expired_registrations( struct peer_info ** peer_list ); size_t purge_expired_registrations( struct peer_info ** peer_list );
void update_peer_address(n2n_edge_t * eee,
uint8_t from_supernode,
const n2n_mac_t mac,
const n2n_sock_t * peer,
time_t when);
/* Edge conf */ /* Edge conf */
void edge_init_conf_defaults(n2n_edge_conf_t *conf); void edge_init_conf_defaults(n2n_edge_conf_t *conf);

28
sn.c
View File

@ -157,7 +157,7 @@ static int update_edge(n2n_sn_t * sss,
} else { } else {
/* Known */ /* Known */
if((0 != memcmp(community, scan->community_name, sizeof(n2n_community_t))) || if((0 != memcmp(community, scan->community_name, sizeof(n2n_community_t))) ||
(0 != sock_equal(sender_sock, &(scan->sock)))) (!sock_equal(sender_sock, &(scan->sock))))
{ {
memcpy(scan->community_name, community, sizeof(n2n_community_t)); memcpy(scan->community_name, community, sizeof(n2n_community_t));
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
@ -500,7 +500,9 @@ static int process_udp(n2n_sn_t * sss,
--(cmn.ttl); /* The value copied into all forwarded packets. */ --(cmn.ttl); /* The value copied into all forwarded packets. */
if(msg_type == MSG_TYPE_PACKET) { switch(msg_type) {
case MSG_TYPE_PACKET:
{
/* PACKET from one edge to another edge via supernode. */ /* PACKET from one edge to another edge via supernode. */
/* pkt will be modified in place and recoded to an output of potentially /* pkt will be modified in place and recoded to an output of potentially
@ -556,8 +558,10 @@ static int process_udp(n2n_sn_t * sss,
try_forward(sss, &cmn, pkt.dstMac, rec_buf, encx); try_forward(sss, &cmn, pkt.dstMac, rec_buf, encx);
else else
try_broadcast(sss, &cmn, pkt.srcMac, rec_buf, encx); try_broadcast(sss, &cmn, pkt.srcMac, rec_buf, encx);
}/* MSG_TYPE_PACKET */ break;
else if(msg_type == MSG_TYPE_REGISTER) { }
case MSG_TYPE_REGISTER:
{
/* Forwarding a REGISTER from one edge to the next */ /* Forwarding a REGISTER from one edge to the next */
n2n_REGISTER_t reg; n2n_REGISTER_t reg;
@ -606,9 +610,13 @@ static int process_udp(n2n_sn_t * sss,
try_forward(sss, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */ try_forward(sss, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */
} else } else
traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination");
} else if(msg_type == MSG_TYPE_REGISTER_ACK) break;
}
case MSG_TYPE_REGISTER_ACK:
traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) SHould not be via supernode"); traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) SHould not be via supernode");
else if(msg_type == MSG_TYPE_REGISTER_SUPER) { break;
case MSG_TYPE_REGISTER_SUPER:
{
n2n_REGISTER_SUPER_t reg; n2n_REGISTER_SUPER_t reg;
n2n_REGISTER_SUPER_ACK_t ack; n2n_REGISTER_SUPER_ACK_t ack;
n2n_common_t cmn2; n2n_common_t cmn2;
@ -657,11 +665,15 @@ static int process_udp(n2n_sn_t * sss,
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]",
macaddr_str(mac_buf, reg.edgeMac), macaddr_str(mac_buf, reg.edgeMac),
sock_to_cstr(sockbuf, &(ack.sock))); sock_to_cstr(sockbuf, &(ack.sock)));
} else { } else
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'",
(char*)cmn.community); (char*)cmn.community);
} break;
} }
default:
/* Not a known message type */
traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type);
} /* switch(msg_type) */
return 0; return 0;
} }