mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
Replace peers linked list with hash
This commit is contained in:
parent
b5c59c0e56
commit
447c3ad8c3
207
edge_utils.c
207
edge_utils.c
|
@ -222,42 +222,15 @@ edge_init_error:
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ***************************************************** */
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
static int find_and_remove_peer(struct peer_info **head, const n2n_mac_t mac) {
|
static int find_and_remove_peer(struct peer_info **head, const n2n_mac_t mac) {
|
||||||
struct peer_info *prev = NULL;
|
struct peer_info *peer;
|
||||||
struct peer_info *scan = *head;
|
|
||||||
|
|
||||||
while(scan != NULL) {
|
HASH_FIND_PEER(*head, mac, peer);
|
||||||
if(memcmp(scan->mac_addr, mac, N2N_MAC_SIZE) == 0)
|
if(peer) {
|
||||||
break; /* found. */
|
HASH_DEL(*head, peer);
|
||||||
|
free(peer);
|
||||||
prev = scan;
|
|
||||||
scan = scan->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(scan) {
|
|
||||||
remove_peer_from_list(head, prev, scan);
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,10 +349,12 @@ static void register_with_new_peer(n2n_edge_t * eee,
|
||||||
const n2n_mac_t mac,
|
const n2n_mac_t mac,
|
||||||
const n2n_sock_t * peer) {
|
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 = find_peer_by_mac(eee->pending_peers, mac);
|
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);
|
||||||
|
|
||||||
/* 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));
|
||||||
|
@ -387,16 +362,16 @@ static void register_with_new_peer(n2n_edge_t * eee,
|
||||||
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 = REGISTER_SUPER_INTERVAL_DFL; /* TODO: should correspond to the peer supernode registration timeout */
|
||||||
update_peer_seen(scan, time(NULL)); /* Don't change this it marks the pending peer for removal. */
|
scan->last_seen = time(NULL); /* Don't change this it marks the pending peer for removal. */
|
||||||
|
|
||||||
peer_list_add(&(eee->pending_peers), scan);
|
HASH_ADD_PEER(eee->pending_peers, scan);
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "=== new pending %s -> %s",
|
traceEvent(TRACE_DEBUG, "=== new pending %s -> %s",
|
||||||
macaddr_str(mac_buf, scan->mac_addr),
|
macaddr_str(mac_buf, scan->mac_addr),
|
||||||
sock_to_cstr(sockbuf, &(scan->sock)));
|
sock_to_cstr(sockbuf, &(scan->sock)));
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "Pending peers list size=%u",
|
traceEvent(TRACE_INFO, "Pending peers list size=%u",
|
||||||
(unsigned int)peer_list_size(eee->pending_peers));
|
HASH_COUNT(eee->pending_peers));
|
||||||
|
|
||||||
/* trace Sending REGISTER */
|
/* trace Sending REGISTER */
|
||||||
send_register(eee, &(scan->sock), mac);
|
send_register(eee, &(scan->sock), mac);
|
||||||
|
@ -416,7 +391,9 @@ 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) {
|
||||||
struct peer_info * scan = find_peer_by_mac(eee->known_peers, mac);
|
struct peer_info *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. */
|
||||||
|
@ -445,66 +422,38 @@ 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,
|
||||||
time_t now) {
|
time_t now) {
|
||||||
struct peer_info * prev = NULL;
|
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;
|
||||||
|
|
||||||
scan=eee->pending_peers;
|
HASH_FIND_PEER(eee->pending_peers, mac, scan);
|
||||||
|
|
||||||
while (NULL != scan)
|
if(scan) {
|
||||||
{
|
HASH_DEL(eee->pending_peers, scan);
|
||||||
if(0 == memcmp(scan->mac_addr, mac, N2N_MAC_SIZE))
|
|
||||||
{
|
|
||||||
break; /* found. */
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = scan;
|
/* Add scan to known_peers. */
|
||||||
scan = scan->next;
|
HASH_ADD_PEER(eee->known_peers, scan);
|
||||||
}
|
|
||||||
|
|
||||||
if(scan)
|
scan->sock = *peer;
|
||||||
{
|
scan->last_p2p = now;
|
||||||
|
|
||||||
|
traceEvent(TRACE_NORMAL, "P2P connection enstablished: %s [%s]",
|
||||||
|
macaddr_str(mac_buf, mac),
|
||||||
|
sock_to_cstr(sockbuf, peer));
|
||||||
|
|
||||||
/* Remove scan from pending_peers. */
|
traceEvent(TRACE_DEBUG, "=== new peer %s -> %s",
|
||||||
if(prev)
|
macaddr_str(mac_buf, scan->mac_addr),
|
||||||
{
|
sock_to_cstr(sockbuf, &(scan->sock)));
|
||||||
prev->next = scan->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eee->pending_peers = scan->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add scan to known_peers. */
|
traceEvent(TRACE_INFO, "Pending peers list size=%u",
|
||||||
scan->next = eee->known_peers;
|
HASH_COUNT(eee->pending_peers));
|
||||||
eee->known_peers = scan;
|
|
||||||
|
|
||||||
scan->sock = *peer;
|
traceEvent(TRACE_INFO, "Known peers list size=%u",
|
||||||
scan->last_p2p = now;
|
HASH_COUNT(eee->known_peers));
|
||||||
|
|
||||||
traceEvent(TRACE_NORMAL, "P2P connection enstablished: %s [%s]",
|
scan->last_seen = now;
|
||||||
macaddr_str(mac_buf, mac),
|
} else
|
||||||
sock_to_cstr(sockbuf, peer));
|
traceEvent(TRACE_DEBUG, "Failed to find sender in pending_peers.");
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "=== new peer %s -> %s",
|
|
||||||
macaddr_str(mac_buf, scan->mac_addr),
|
|
||||||
sock_to_cstr(sockbuf, &(scan->sock)));
|
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "Pending peers list size=%u",
|
|
||||||
(unsigned int)peer_list_size(eee->pending_peers));
|
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "Known peers list size=%u",
|
|
||||||
(unsigned int)peer_list_size(eee->known_peers));
|
|
||||||
|
|
||||||
|
|
||||||
update_peer_seen(scan, now);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traceEvent(TRACE_DEBUG, "Failed to find sender in pending_peers.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
@ -548,8 +497,7 @@ static void check_known_peer_sock_change(n2n_edge_t * eee,
|
||||||
const n2n_mac_t mac,
|
const n2n_mac_t mac,
|
||||||
const n2n_sock_t * peer,
|
const n2n_sock_t * peer,
|
||||||
time_t when) {
|
time_t when) {
|
||||||
struct peer_info *scan = eee->known_peers;
|
struct peer_info *scan;
|
||||||
struct peer_info *prev = NULL; /* use to remove bad registrations. */
|
|
||||||
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;
|
||||||
|
@ -561,13 +509,7 @@ static void check_known_peer_sock_change(n2n_edge_t * eee,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Search the peer in known_peers */
|
/* Search the peer in known_peers */
|
||||||
while(scan != NULL) {
|
HASH_FIND_PEER(eee->known_peers, mac, scan);
|
||||||
if(memcmp(mac, scan->mac_addr, N2N_MAC_SIZE) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
prev = scan;
|
|
||||||
scan = scan->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!scan)
|
if(!scan)
|
||||||
/* Not in known_peers */
|
/* Not in known_peers */
|
||||||
|
@ -581,14 +523,15 @@ static void check_known_peer_sock_change(n2n_edge_t * eee,
|
||||||
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_peer_from_list(&eee->known_peers, prev, scan);
|
HASH_DEL(eee->known_peers, scan);
|
||||||
|
free(scan);
|
||||||
|
|
||||||
register_with_new_peer(eee, from_supernode, mac, peer);
|
register_with_new_peer(eee, from_supernode, 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
|
||||||
update_peer_seen(scan, when);
|
scan->last_seen = when;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
@ -1043,8 +986,8 @@ static void readFromMgmtSocket(n2n_edge_t * eee, int * keep_running) {
|
||||||
|
|
||||||
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",
|
"peers pend:%u full:%u\n",
|
||||||
(unsigned int)peer_list_size(eee->pending_peers),
|
HASH_COUNT(eee->pending_peers),
|
||||||
(unsigned int)peer_list_size(eee->known_peers));
|
HASH_COUNT(eee->known_peers));
|
||||||
|
|
||||||
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",
|
"last super:%lu(%ld sec ago) p2p:%lu(%ld sec ago)\n",
|
||||||
|
@ -1104,23 +1047,18 @@ static int is_ethMulticast(const void * buf, size_t bufsize) {
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
static int check_query_peer_info(n2n_edge_t *eee, time_t now, n2n_mac_t mac) {
|
static int check_query_peer_info(n2n_edge_t *eee, time_t now, n2n_mac_t mac) {
|
||||||
struct peer_info *scan = eee->pending_peers;
|
struct peer_info *scan;
|
||||||
|
|
||||||
while(scan != NULL) {
|
HASH_FIND_PEER(eee->pending_peers, mac, scan);
|
||||||
if(memcmp(scan->mac_addr, mac, N2N_MAC_SIZE) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
scan = scan->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!scan) {
|
if(!scan) {
|
||||||
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 = REGISTER_SUPER_INTERVAL_DFL; /* TODO: should correspond to the peer supernode registration timeout */
|
||||||
update_peer_seen(scan, 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. */
|
||||||
|
|
||||||
peer_list_add(&(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 > REGISTER_SUPER_INTERVAL_DFL) {
|
||||||
|
@ -1138,8 +1076,7 @@ static int check_query_peer_info(n2n_edge_t *eee, time_t now, n2n_mac_t mac) {
|
||||||
static int find_peer_destination(n2n_edge_t * eee,
|
static int find_peer_destination(n2n_edge_t * eee,
|
||||||
n2n_mac_t mac_address,
|
n2n_mac_t mac_address,
|
||||||
n2n_sock_t * destination) {
|
n2n_sock_t * destination) {
|
||||||
struct peer_info *scan = eee->known_peers;
|
struct peer_info *scan;
|
||||||
struct peer_info *prev = NULL;
|
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
n2n_sock_str_t sockbuf;
|
n2n_sock_str_t sockbuf;
|
||||||
int retval=0;
|
int retval=0;
|
||||||
|
@ -1155,31 +1092,21 @@ static int find_peer_destination(n2n_edge_t * eee,
|
||||||
mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF,
|
mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF,
|
||||||
mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF);
|
mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF);
|
||||||
|
|
||||||
while(scan != NULL) {
|
HASH_FIND_PEER(eee->known_peers, mac_address, scan);
|
||||||
traceEvent(TRACE_DEBUG, "Evaluating peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X]",
|
|
||||||
scan->mac_addr[0] & 0xFF, scan->mac_addr[1] & 0xFF, scan->mac_addr[2] & 0xFF,
|
|
||||||
scan->mac_addr[3] & 0xFF, scan->mac_addr[4] & 0xFF, scan->mac_addr[5] & 0xFF
|
|
||||||
);
|
|
||||||
|
|
||||||
if((scan->last_seen > 0) &&
|
if(scan && (scan->last_seen > 0)) {
|
||||||
(memcmp(mac_address, scan->mac_addr, N2N_MAC_SIZE) == 0)) {
|
if((now - scan->last_p2p) >= (scan->timeout / 2)) {
|
||||||
if((now - scan->last_p2p) >= (scan->timeout / 2)) {
|
/* Too much time passed since we saw the peer, need to register again
|
||||||
/* Too much time passed since we saw the peer, need to register again
|
* since the peer address may have changed. */
|
||||||
* since the peer address may have changed. */
|
traceEvent(TRACE_DEBUG, "Refreshing idle known peer");
|
||||||
traceEvent(TRACE_DEBUG, "Refreshing idle known peer");
|
HASH_DEL(eee->known_peers, scan);
|
||||||
remove_peer_from_list(&eee->known_peers, prev, scan);
|
free(scan);
|
||||||
/* NOTE: registration will be performed upon the receival of the next response packet */
|
/* NOTE: registration will be performed upon the receival of the next response packet */
|
||||||
} else {
|
} else {
|
||||||
/* Valid known peer found */
|
/* Valid known peer found */
|
||||||
memcpy(destination, &scan->sock, sizeof(n2n_sock_t));
|
memcpy(destination, &scan->sock, sizeof(n2n_sock_t));
|
||||||
retval=1;
|
retval=1;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = scan;
|
|
||||||
scan = scan->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(retval == 0) {
|
if(retval == 0) {
|
||||||
|
@ -1593,7 +1520,7 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scan = find_peer_by_mac( eee->pending_peers, pi.mac );
|
HASH_FIND_PEER(eee->pending_peers, pi.mac, scan);
|
||||||
if (scan) {
|
if (scan) {
|
||||||
scan->sock = pi.sock;
|
scan->sock = pi.sock;
|
||||||
traceEvent(TRACE_INFO, "Rx PEER_INFO on %s",
|
traceEvent(TRACE_INFO, "Rx PEER_INFO on %s",
|
||||||
|
@ -1728,14 +1655,14 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
|
||||||
/* Finished processing select data. */
|
/* Finished processing select data. */
|
||||||
update_supernode_reg(eee, nowTime);
|
update_supernode_reg(eee, nowTime);
|
||||||
|
|
||||||
numPurged = purge_expired_registrations(&(eee->known_peers), &last_purge_known);
|
numPurged = purge_expired_registrations(&eee->known_peers, &last_purge_known);
|
||||||
numPurged += purge_expired_registrations(&(eee->pending_peers), &last_purge_pending);
|
numPurged += purge_expired_registrations(&eee->pending_peers, &last_purge_pending);
|
||||||
|
|
||||||
if(numPurged > 0) {
|
if(numPurged > 0) {
|
||||||
traceEvent(TRACE_INFO, "%u peers removed. now: pending=%u, operational=%u",
|
traceEvent(TRACE_INFO, "%u peers removed. now: pending=%u, operational=%u",
|
||||||
numPurged,
|
numPurged,
|
||||||
(unsigned int)peer_list_size(eee->pending_peers),
|
HASH_COUNT(eee->pending_peers),
|
||||||
(unsigned int)peer_list_size(eee->known_peers));
|
HASH_COUNT(eee->known_peers));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eee->conf.dyn_ip_mode &&
|
if(eee->conf.dyn_ip_mode &&
|
||||||
|
@ -1773,8 +1700,8 @@ void edge_term(n2n_edge_t * eee) {
|
||||||
if(eee->udp_multicast_sock >= 0)
|
if(eee->udp_multicast_sock >= 0)
|
||||||
closesocket(eee->udp_multicast_sock);
|
closesocket(eee->udp_multicast_sock);
|
||||||
|
|
||||||
clear_peer_list(&(eee->pending_peers));
|
clear_peer_list(&eee->pending_peers);
|
||||||
clear_peer_list(&(eee->known_peers));
|
clear_peer_list(&eee->known_peers);
|
||||||
|
|
||||||
eee->transop.deinit(&eee->transop);
|
eee->transop.deinit(&eee->transop);
|
||||||
free(eee);
|
free(eee);
|
||||||
|
|
113
n2n.c
113
n2n.c
|
@ -263,57 +263,6 @@ void print_n2n_version() {
|
||||||
|
|
||||||
/* *********************************************** */
|
/* *********************************************** */
|
||||||
|
|
||||||
/** Find the peer entry in list with mac_addr equal to mac.
|
|
||||||
*
|
|
||||||
* Does not modify the list.
|
|
||||||
*
|
|
||||||
* @return NULL if not found; otherwise pointer to peer entry.
|
|
||||||
*/
|
|
||||||
struct peer_info * find_peer_by_mac(struct peer_info * list, const n2n_mac_t mac)
|
|
||||||
{
|
|
||||||
while(list != NULL)
|
|
||||||
{
|
|
||||||
if(0 == memcmp(mac, list->mac_addr, 6))
|
|
||||||
{
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the number of elements in the list.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
size_t peer_list_size(const struct peer_info * list)
|
|
||||||
{
|
|
||||||
size_t retval=0;
|
|
||||||
|
|
||||||
while(list)
|
|
||||||
{
|
|
||||||
++retval;
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Add new to the head of list. If list is NULL; create it.
|
|
||||||
*
|
|
||||||
* The item new is added to the head of the list. New is modified during
|
|
||||||
* insertion. list takes ownership of new.
|
|
||||||
*/
|
|
||||||
void peer_list_add(struct peer_info * * list,
|
|
||||||
struct peer_info * newp)
|
|
||||||
{
|
|
||||||
newp->next = *list;
|
|
||||||
newp->last_seen = time(NULL);
|
|
||||||
*list = newp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t purge_expired_registrations(struct peer_info ** peer_list, time_t* p_last_purge) {
|
size_t purge_expired_registrations(struct peer_info ** peer_list, time_t* p_last_purge) {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
size_t num_reg = 0;
|
size_t num_reg = 0;
|
||||||
|
@ -334,37 +283,16 @@ size_t purge_expired_registrations(struct peer_info ** peer_list, time_t* p_last
|
||||||
size_t purge_peer_list(struct peer_info ** peer_list,
|
size_t purge_peer_list(struct peer_info ** peer_list,
|
||||||
time_t purge_before)
|
time_t purge_before)
|
||||||
{
|
{
|
||||||
struct peer_info *scan;
|
struct peer_info *scan, *tmp;
|
||||||
struct peer_info *prev;
|
|
||||||
size_t retval=0;
|
size_t retval=0;
|
||||||
|
|
||||||
scan = *peer_list;
|
HASH_ITER(hh, *peer_list, scan, tmp) {
|
||||||
prev = NULL;
|
if(scan->last_seen < purge_before) {
|
||||||
while(scan != NULL)
|
HASH_DEL(*peer_list, scan);
|
||||||
{
|
retval++;
|
||||||
if(scan->last_seen < purge_before)
|
free(scan);
|
||||||
{
|
|
||||||
struct peer_info *next = scan->next;
|
|
||||||
|
|
||||||
if(prev == NULL)
|
|
||||||
{
|
|
||||||
*peer_list = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prev->next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
++retval;
|
|
||||||
free(scan);
|
|
||||||
scan = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prev = scan;
|
|
||||||
scan = scan->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -372,29 +300,14 @@ size_t purge_peer_list(struct peer_info ** peer_list,
|
||||||
/** Purge all items from the peer_list and return the number of items that were removed. */
|
/** Purge all items from the peer_list and return the number of items that were removed. */
|
||||||
size_t clear_peer_list(struct peer_info ** peer_list)
|
size_t clear_peer_list(struct peer_info ** peer_list)
|
||||||
{
|
{
|
||||||
struct peer_info *scan;
|
struct peer_info *scan, *tmp;
|
||||||
struct peer_info *prev;
|
|
||||||
size_t retval=0;
|
size_t retval=0;
|
||||||
|
|
||||||
scan = *peer_list;
|
HASH_ITER(hh, *peer_list, scan, tmp) {
|
||||||
prev = NULL;
|
HASH_DEL(*peer_list, scan);
|
||||||
while(scan != NULL)
|
retval++;
|
||||||
{
|
free(scan);
|
||||||
struct peer_info *next = scan->next;
|
}
|
||||||
|
|
||||||
if(prev == NULL)
|
|
||||||
{
|
|
||||||
*peer_list = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prev->next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
++retval;
|
|
||||||
free(scan);
|
|
||||||
scan = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
15
n2n.h
15
n2n.h
|
@ -169,16 +169,22 @@ typedef char ipstr_t[32];
|
||||||
typedef char macstr_t[N2N_MACSTR_SIZE];
|
typedef char macstr_t[N2N_MACSTR_SIZE];
|
||||||
|
|
||||||
struct peer_info {
|
struct peer_info {
|
||||||
struct peer_info * next;
|
|
||||||
n2n_community_t community_name;
|
|
||||||
n2n_mac_t mac_addr;
|
n2n_mac_t mac_addr;
|
||||||
|
n2n_community_t community_name;
|
||||||
n2n_sock_t sock;
|
n2n_sock_t sock;
|
||||||
int timeout;
|
int timeout;
|
||||||
time_t last_seen;
|
time_t last_seen;
|
||||||
time_t last_p2p;
|
time_t last_p2p;
|
||||||
time_t last_sent_query;
|
time_t last_sent_query;
|
||||||
|
|
||||||
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define HASH_ADD_PEER(head,add) \
|
||||||
|
HASH_ADD(hh,head,mac_addr,sizeof(n2n_mac_t),add)
|
||||||
|
#define HASH_FIND_PEER(head,mac,out) \
|
||||||
|
HASH_FIND(hh,head,mac,sizeof(n2n_mac_t),out)
|
||||||
|
|
||||||
#define N2N_EDGE_SN_HOST_SIZE 48
|
#define N2N_EDGE_SN_HOST_SIZE 48
|
||||||
#define N2N_EDGE_NUM_SUPERNODES 2
|
#define N2N_EDGE_NUM_SUPERNODES 2
|
||||||
#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */
|
#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */
|
||||||
|
@ -275,11 +281,6 @@ int sock_equal( const n2n_sock_t * a,
|
||||||
const n2n_sock_t * b );
|
const n2n_sock_t * b );
|
||||||
|
|
||||||
/* Operations on peer_info lists. */
|
/* Operations on peer_info lists. */
|
||||||
struct peer_info * find_peer_by_mac( struct peer_info * list,
|
|
||||||
const n2n_mac_t mac );
|
|
||||||
void peer_list_add( struct peer_info * * list,
|
|
||||||
struct peer_info * newp );
|
|
||||||
size_t peer_list_size( const struct peer_info * list );
|
|
||||||
size_t purge_peer_list( struct peer_info ** peer_list,
|
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 );
|
||||||
|
|
32
sn.c
32
sn.c
|
@ -106,7 +106,7 @@ static void deinit_sn(n2n_sn_t * sss)
|
||||||
}
|
}
|
||||||
sss->mgmt_sock=-1;
|
sss->mgmt_sock=-1;
|
||||||
|
|
||||||
purge_peer_list(&(sss->edges), 0xffffffff);
|
clear_peer_list(&sss->edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ static int update_edge(n2n_sn_t * sss,
|
||||||
macaddr_str(mac_buf, edgeMac),
|
macaddr_str(mac_buf, edgeMac),
|
||||||
sock_to_cstr(sockbuf, sender_sock));
|
sock_to_cstr(sockbuf, sender_sock));
|
||||||
|
|
||||||
scan = find_peer_by_mac(sss->edges, edgeMac);
|
HASH_FIND_PEER(sss->edges, edgeMac, scan);
|
||||||
|
|
||||||
if(NULL == scan) {
|
if(NULL == scan) {
|
||||||
/* Not known */
|
/* Not known */
|
||||||
|
@ -147,9 +147,7 @@ static int update_edge(n2n_sn_t * sss,
|
||||||
memcpy(&(scan->mac_addr), edgeMac, sizeof(n2n_mac_t));
|
memcpy(&(scan->mac_addr), edgeMac, sizeof(n2n_mac_t));
|
||||||
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
|
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
|
||||||
|
|
||||||
/* insert this guy at the head of the edges list */
|
HASH_ADD_PEER(sss->edges, scan);
|
||||||
scan->next = sss->edges; /* first in list */
|
|
||||||
sss->edges = scan; /* head of list points to new scan */
|
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "update_edge created %s ==> %s",
|
traceEvent(TRACE_INFO, "update_edge created %s ==> %s",
|
||||||
macaddr_str(mac_buf, edgeMac),
|
macaddr_str(mac_buf, edgeMac),
|
||||||
|
@ -229,7 +227,7 @@ static int try_forward(n2n_sn_t * sss,
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
n2n_sock_str_t sockbuf;
|
n2n_sock_str_t sockbuf;
|
||||||
|
|
||||||
scan = find_peer_by_mac(sss->edges, dstMac);
|
HASH_FIND_PEER(sss->edges, dstMac, scan);
|
||||||
|
|
||||||
if(NULL != scan)
|
if(NULL != scan)
|
||||||
{
|
{
|
||||||
|
@ -276,15 +274,13 @@ static int try_broadcast(n2n_sn_t * sss,
|
||||||
const uint8_t * pktbuf,
|
const uint8_t * pktbuf,
|
||||||
size_t pktsize)
|
size_t pktsize)
|
||||||
{
|
{
|
||||||
struct peer_info * scan;
|
struct peer_info *scan, *tmp;
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
n2n_sock_str_t sockbuf;
|
n2n_sock_str_t sockbuf;
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "try_broadcast");
|
traceEvent(TRACE_DEBUG, "try_broadcast");
|
||||||
|
|
||||||
scan = sss->edges;
|
HASH_ITER(hh, sss->edges, scan, tmp) {
|
||||||
while(scan != NULL)
|
|
||||||
{
|
|
||||||
if(0 == (memcmp(scan->community_name, cmn->community, sizeof(n2n_community_t)))
|
if(0 == (memcmp(scan->community_name, cmn->community, sizeof(n2n_community_t)))
|
||||||
&& (0 != memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t))))
|
&& (0 != memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t))))
|
||||||
/* REVISIT: exclude if the destination socket is where the packet came from. */
|
/* REVISIT: exclude if the destination socket is where the packet came from. */
|
||||||
|
@ -311,9 +307,7 @@ static int try_broadcast(n2n_sn_t * sss,
|
||||||
macaddr_str(mac_buf, scan->mac_addr));
|
macaddr_str(mac_buf, scan->mac_addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
scan = scan->next;
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -339,7 +333,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,
|
||||||
"edges %u\n",
|
"edges %u\n",
|
||||||
(unsigned int)peer_list_size(sss->edges));
|
HASH_COUNT(sss->edges));
|
||||||
|
|
||||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||||
"errors %u\n",
|
"errors %u\n",
|
||||||
|
@ -684,7 +678,7 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
macaddr_str( mac_buf, query.srcMac ),
|
macaddr_str( mac_buf, query.srcMac ),
|
||||||
macaddr_str( mac_buf2, query.targetMac ) );
|
macaddr_str( mac_buf2, query.targetMac ) );
|
||||||
|
|
||||||
scan = find_peer_by_mac( sss->edges, query.targetMac );
|
HASH_FIND_PEER(sss->edges, query.targetMac, scan);
|
||||||
if (scan) {
|
if (scan) {
|
||||||
cmn2.ttl = N2N_DEFAULT_TTL;
|
cmn2.ttl = N2N_DEFAULT_TTL;
|
||||||
cmn2.pc = n2n_peer_info;
|
cmn2.pc = n2n_peer_info;
|
||||||
|
@ -895,14 +889,14 @@ static int loadFromFile(const char *path, n2n_sn_t *sss) {
|
||||||
/* *************************************************** */
|
/* *************************************************** */
|
||||||
|
|
||||||
static void dump_registrations(int signo) {
|
static void dump_registrations(int signo) {
|
||||||
struct peer_info * list = sss_node.edges;
|
struct peer_info *list, *tmp;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
u_int num = 0;
|
u_int num = 0;
|
||||||
|
|
||||||
traceEvent(TRACE_NORMAL, "====================================");
|
traceEvent(TRACE_NORMAL, "====================================");
|
||||||
|
|
||||||
while(list != NULL) {
|
HASH_ITER(hh, sss_node.edges, list, tmp) {
|
||||||
if(list->sock.family == AF_INET)
|
if(list->sock.family == AF_INET)
|
||||||
traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][community: %s][last seen: %u sec ago]",
|
traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][community: %s][last seen: %u sec ago]",
|
||||||
++num, macaddr_str(buf, list->mac_addr),
|
++num, macaddr_str(buf, list->mac_addr),
|
||||||
|
@ -915,8 +909,6 @@ static void dump_registrations(int signo) {
|
||||||
++num, macaddr_str(buf, list->mac_addr), list->sock.port,
|
++num, macaddr_str(buf, list->mac_addr), list->sock.port,
|
||||||
(char*)list->community_name,
|
(char*)list->community_name,
|
||||||
now-list->last_seen);
|
now-list->last_seen);
|
||||||
|
|
||||||
list = list->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
traceEvent(TRACE_NORMAL, "====================================");
|
traceEvent(TRACE_NORMAL, "====================================");
|
||||||
|
@ -1063,7 +1055,7 @@ static int run_loop(n2n_sn_t * sss) {
|
||||||
traceEvent(TRACE_DEBUG, "timeout");
|
traceEvent(TRACE_DEBUG, "timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
purge_expired_registrations( &(sss->edges), &last_purge_edges );
|
purge_expired_registrations( &sss->edges, &last_purge_edges );
|
||||||
|
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user