mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
commit
8542ba0db6
|
@ -19,10 +19,12 @@
|
||||||
|
|
||||||
uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len,
|
uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len,
|
||||||
char * community_name, he_context_t * ctx,
|
char * community_name, he_context_t * ctx,
|
||||||
he_context_t * ctx_iv, uint16_t * checksum);
|
he_context_t * ctx_iv,
|
||||||
|
uint64_t * stamp, uint16_t * checksum);
|
||||||
|
|
||||||
int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx,
|
int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx,
|
||||||
he_context_t * ctx_iv, uint16_t checksum);
|
he_context_t * ctx_iv,
|
||||||
|
uint64_t stamp, uint16_t checksum);
|
||||||
|
|
||||||
|
|
||||||
void packet_header_setup_key (const char * community_name, he_context_t ** ctx,
|
void packet_header_setup_key (const char * community_name, he_context_t ** ctx,
|
||||||
|
|
|
@ -193,6 +193,7 @@ struct peer_info {
|
||||||
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;
|
||||||
|
uint64_t last_valid_time_stamp;
|
||||||
|
|
||||||
UT_hash_handle hh; /* makes this structure hashable */
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
};
|
};
|
||||||
|
@ -303,8 +304,9 @@ struct n2n_edge {
|
||||||
n2n_trans_op_t transop; /**< The transop to use when encoding */
|
n2n_trans_op_t transop; /**< The transop to use when encoding */
|
||||||
n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */
|
n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */
|
||||||
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
|
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
|
||||||
n2n_edge_callbacks_t cb; /**< API callbacks */
|
n2n_edge_callbacks_t cb; /**< API callbacks */
|
||||||
void *user_data; /**< Can hold user data */
|
void *user_data; /**< Can hold user data */
|
||||||
|
uint64_t sn_last_valid_time_stamp;/*< last valid time stamp from supernode */
|
||||||
|
|
||||||
/* Sockets */
|
/* Sockets */
|
||||||
n2n_sock_t supernode;
|
n2n_sock_t supernode;
|
||||||
|
@ -428,6 +430,11 @@ SOCKET open_socket(int local_port, int bind_any);
|
||||||
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 );
|
||||||
|
|
||||||
|
/* Header encryption */
|
||||||
|
uint64_t time_stamp(void);
|
||||||
|
uint64_t initial_time_stamp (void);
|
||||||
|
int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp);
|
||||||
|
|
||||||
/* Operations on peer_info lists. */
|
/* Operations on peer_info lists. */
|
||||||
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 );
|
||||||
|
|
229
src/edge_utils.c
229
src/edge_utils.c
|
@ -17,7 +17,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "n2n.h"
|
#include "n2n.h"
|
||||||
#include "header_encryption.h"
|
|
||||||
#include "edge_utils_win32.h"
|
#include "edge_utils_win32.h"
|
||||||
|
|
||||||
/* heap allocation for compression as per lzo example doc */
|
/* heap allocation for compression as per lzo example doc */
|
||||||
|
@ -194,6 +193,7 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
|
||||||
eee->known_peers = NULL;
|
eee->known_peers = NULL;
|
||||||
eee->pending_peers = NULL;
|
eee->pending_peers = NULL;
|
||||||
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
|
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
|
||||||
|
eee->sn_last_valid_time_stamp = initial_time_stamp ();
|
||||||
|
|
||||||
pearson_hash_init();
|
pearson_hash_init();
|
||||||
|
|
||||||
|
@ -381,6 +381,42 @@ static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn) {
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
|
static const int definitely_from_supernode = 1;
|
||||||
|
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* For a given packet, find the apporopriate internal last valid time stamp for lookup
|
||||||
|
* and verify it (and also update, if applicable).
|
||||||
|
*/
|
||||||
|
static int find_peer_time_stamp_and_verify (n2n_edge_t * eee,
|
||||||
|
int from_supernode, n2n_mac_t mac,
|
||||||
|
uint64_t stamp) {
|
||||||
|
|
||||||
|
uint64_t * previous_stamp = NULL;
|
||||||
|
|
||||||
|
if(from_supernode) {
|
||||||
|
// from supernode
|
||||||
|
previous_stamp = &(eee->sn_last_valid_time_stamp);
|
||||||
|
} else {
|
||||||
|
// from (peer) edge
|
||||||
|
struct peer_info *peer;
|
||||||
|
HASH_FIND_PEER(eee->pending_peers, mac, peer);
|
||||||
|
if(!peer) {
|
||||||
|
HASH_FIND_PEER(eee->known_peers, mac, peer);
|
||||||
|
}
|
||||||
|
if(peer) {
|
||||||
|
// time_stamp_verify_and_update allows the pointer a previous stamp to be NULL
|
||||||
|
// if it is a (so far) unknown peer
|
||||||
|
previous_stamp = &(peer->last_valid_time_stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// failure --> 0; success --> 1
|
||||||
|
return ( time_stamp_verify_and_update (stamp, previous_stamp) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************** */
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*
|
*
|
||||||
* Register over multicast in case there is a peer on the same network listening
|
* Register over multicast in case there is a peer on the same network listening
|
||||||
|
@ -432,6 +468,7 @@ static void register_with_new_peer(n2n_edge_t * eee,
|
||||||
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 */
|
||||||
scan->last_seen = 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. */
|
||||||
|
scan->last_valid_time_stamp = initial_time_stamp ();
|
||||||
|
|
||||||
HASH_ADD_PEER(eee->pending_peers, scan);
|
HASH_ADD_PEER(eee->pending_peers, scan);
|
||||||
|
|
||||||
|
@ -731,7 +768,8 @@ static void send_register_super(n2n_edge_t * eee,
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
||||||
eee->conf.header_iv_ctx, pearson_hash_16 (pktbuf, idx));
|
eee->conf.header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
||||||
|
|
||||||
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode);
|
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode);
|
||||||
}
|
}
|
||||||
|
@ -763,9 +801,10 @@ static void send_query_peer( n2n_edge_t * eee,
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED){
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED){
|
||||||
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
||||||
eee->conf.header_iv_ctx, pearson_hash_16 (pktbuf, idx));
|
eee->conf.header_iv_ctx,
|
||||||
}
|
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
||||||
sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) );
|
}
|
||||||
|
sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send a REGISTER packet to another edge. */
|
/** Send a REGISTER packet to another edge. */
|
||||||
|
@ -810,7 +849,8 @@ static void send_register(n2n_edge_t * eee,
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
||||||
eee->conf.header_iv_ctx, pearson_hash_16 (pktbuf, idx));
|
eee->conf.header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
||||||
|
|
||||||
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, remote_peer);
|
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, remote_peer);
|
||||||
}
|
}
|
||||||
|
@ -853,7 +893,8 @@ static void send_register_ack(n2n_edge_t * eee,
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
|
||||||
eee->conf.header_iv_ctx, pearson_hash_16 (pktbuf, idx));
|
eee->conf.header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
||||||
|
|
||||||
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, remote_peer);
|
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, remote_peer);
|
||||||
}
|
}
|
||||||
|
@ -1242,6 +1283,7 @@ static int check_query_peer_info(n2n_edge_t *eee, time_t now, n2n_mac_t mac) {
|
||||||
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 */
|
||||||
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 ();
|
||||||
|
|
||||||
HASH_ADD_PEER(eee->pending_peers, scan);
|
HASH_ADD_PEER(eee->pending_peers, scan);
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1513,8 @@ void edge_send_packet2net(n2n_edge_t * eee,
|
||||||
|
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (pktbuf, headerIdx, eee->conf.header_encryption_ctx,
|
packet_header_encrypt (pktbuf, headerIdx, eee->conf.header_encryption_ctx,
|
||||||
eee->conf.header_iv_ctx, pearson_hash_16 (pktbuf, idx));
|
eee->conf.header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (pktbuf, idx));
|
||||||
|
|
||||||
#ifdef MTU_ASSERT_VALUE
|
#ifdef MTU_ASSERT_VALUE
|
||||||
{
|
{
|
||||||
|
@ -1564,6 +1607,7 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
n2n_sock_t sender;
|
n2n_sock_t sender;
|
||||||
n2n_sock_t * orig_sender=NULL;
|
n2n_sock_t * orig_sender=NULL;
|
||||||
time_t now=0;
|
time_t now=0;
|
||||||
|
uint64_t stamp = 0;
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -1601,10 +1645,16 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
uint16_t checksum = 0;
|
uint16_t checksum = 0;
|
||||||
if( packet_header_decrypt (udp_buf, recvlen, (char *)eee->conf.community_name, eee->conf.header_encryption_ctx,
|
if( packet_header_decrypt (udp_buf, recvlen, (char *)eee->conf.community_name, eee->conf.header_encryption_ctx,
|
||||||
eee->conf.header_iv_ctx, &checksum) == 0) {
|
eee->conf.header_iv_ctx,
|
||||||
|
&stamp, &checksum) == 0) {
|
||||||
traceEvent(TRACE_DEBUG, "readFromIPSocket failed to decrypt header.");
|
traceEvent(TRACE_DEBUG, "readFromIPSocket failed to decrypt header.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// time stamp verification follows in the packet specific section as it requires to determine the
|
||||||
|
// sender from the hash list by its MAC, or the packet might be from the supernode, this all depends
|
||||||
|
// on packet type, path taken (via supernode) and packet structure (MAC is not always in the same place)
|
||||||
|
|
||||||
if (checksum != pearson_hash_16 (udp_buf, recvlen)) {
|
if (checksum != pearson_hash_16 (udp_buf, recvlen)) {
|
||||||
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped packet due to checksum error.");
|
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped packet due to checksum error.");
|
||||||
return;
|
return;
|
||||||
|
@ -1630,23 +1680,30 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
switch(msg_type) {
|
switch(msg_type) {
|
||||||
case MSG_TYPE_PACKET:
|
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;
|
||||||
|
|
||||||
decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx);
|
decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
if(is_valid_peer_sock(&pkt.sock))
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
orig_sender = &(pkt.sock);
|
if(!find_peer_time_stamp_and_verify (eee, from_supernode, pkt.srcMac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped PACKET due to time stamp error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!from_supernode) {
|
if(is_valid_peer_sock(&pkt.sock))
|
||||||
/* This is a P2P packet from the peer. We purge a pending
|
orig_sender = &(pkt.sock);
|
||||||
* registration towards the possibly nat-ted peer address as we now have
|
|
||||||
* a valid channel. We still use check_peer_registration_needed in
|
if(!from_supernode) {
|
||||||
* handle_PACKET to double check this.
|
/* This is a P2P packet from the peer. We purge a pending
|
||||||
*/
|
* registration towards the possibly nat-ted peer address as we now have
|
||||||
traceEvent(TRACE_DEBUG, "Got P2P packet");
|
* a valid channel. We still use check_peer_registration_needed in
|
||||||
find_and_remove_peer(&eee->pending_peers, pkt.srcMac);
|
* handle_PACKET to double check this.
|
||||||
}
|
*/
|
||||||
|
traceEvent(TRACE_DEBUG, "Got P2P packet");
|
||||||
|
find_and_remove_peer(&eee->pending_peers, pkt.srcMac);
|
||||||
|
}
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "Rx PACKET from %s (sender=%s) [%u B]",
|
traceEvent(TRACE_INFO, "Rx PACKET from %s (sender=%s) [%u B]",
|
||||||
sock_to_cstr(sockbuf1, &sender),
|
sock_to_cstr(sockbuf1, &sender),
|
||||||
|
@ -1664,8 +1721,15 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
|
|
||||||
decode_REGISTER(®, &cmn, udp_buf, &rem, &idx);
|
decode_REGISTER(®, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
if(is_valid_peer_sock(®.sock))
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
orig_sender = &(reg.sock);
|
if(!find_peer_time_stamp_and_verify (eee, from_supernode, reg.srcMac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER due to time stamp error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_valid_peer_sock(®.sock))
|
||||||
|
orig_sender = &(reg.sock);
|
||||||
|
|
||||||
via_multicast = !memcmp(reg.dstMac, null_mac, 6);
|
via_multicast = !memcmp(reg.dstMac, null_mac, 6);
|
||||||
|
|
||||||
|
@ -1708,8 +1772,15 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
|
|
||||||
decode_REGISTER_ACK(&ra, &cmn, udp_buf, &rem, &idx);
|
decode_REGISTER_ACK(&ra, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
if(is_valid_peer_sock(&ra.sock))
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
orig_sender = &(ra.sock);
|
if(!find_peer_time_stamp_and_verify (eee, !definitely_from_supernode, ra.srcMac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER_ACK due to time stamp error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_valid_peer_sock(&ra.sock))
|
||||||
|
orig_sender = &(ra.sock);
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "Rx REGISTER_ACK src=%s dst=%s from peer %s (%s)",
|
traceEvent(TRACE_INFO, "Rx REGISTER_ACK src=%s dst=%s from peer %s (%s)",
|
||||||
macaddr_str(mac_buf1, ra.srcMac),
|
macaddr_str(mac_buf1, ra.srcMac),
|
||||||
|
@ -1724,59 +1795,73 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
{
|
{
|
||||||
n2n_REGISTER_SUPER_ACK_t ra;
|
n2n_REGISTER_SUPER_ACK_t ra;
|
||||||
|
|
||||||
if(eee->sn_wait)
|
if(eee->sn_wait)
|
||||||
{
|
{
|
||||||
decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx);
|
decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
if(is_valid_peer_sock(&ra.sock))
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
orig_sender = &(ra.sock);
|
if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER_SUPER_ACK due to time stamp error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK myMAC=%s [%s] (external %s). Attempts %u",
|
if(is_valid_peer_sock(&ra.sock))
|
||||||
macaddr_str(mac_buf1, ra.edgeMac),
|
orig_sender = &(ra.sock);
|
||||||
sock_to_cstr(sockbuf1, &sender),
|
|
||||||
sock_to_cstr(sockbuf2, orig_sender),
|
|
||||||
(unsigned int)eee->sup_attempts);
|
|
||||||
|
|
||||||
if(0 == memcmp(ra.cookie, eee->last_cookie, N2N_COOKIE_SIZE))
|
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK myMAC=%s [%s] (external %s). Attempts %u",
|
||||||
{
|
macaddr_str(mac_buf1, ra.edgeMac),
|
||||||
if(ra.num_sn > 0)
|
sock_to_cstr(sockbuf1, &sender),
|
||||||
{
|
sock_to_cstr(sockbuf2, orig_sender),
|
||||||
traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK backup supernode at %s",
|
(unsigned int)eee->sup_attempts);
|
||||||
sock_to_cstr(sockbuf1, &(ra.sn_bak)));
|
|
||||||
}
|
|
||||||
|
|
||||||
eee->last_sup = now;
|
if(0 == memcmp(ra.cookie, eee->last_cookie, N2N_COOKIE_SIZE))
|
||||||
eee->sn_wait=0;
|
{
|
||||||
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */
|
if(ra.num_sn > 0)
|
||||||
|
{
|
||||||
|
traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK backup supernode at %s",
|
||||||
|
sock_to_cstr(sockbuf1, &(ra.sn_bak)));
|
||||||
|
}
|
||||||
|
|
||||||
if(eee->cb.sn_registration_updated)
|
eee->last_sup = now;
|
||||||
eee->cb.sn_registration_updated(eee, now, &sender);
|
eee->sn_wait=0;
|
||||||
|
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */
|
||||||
|
|
||||||
/* NOTE: the register_interval should be chosen by the edge node
|
if(eee->cb.sn_registration_updated)
|
||||||
* based on its NAT configuration. */
|
eee->cb.sn_registration_updated(eee, now, &sender);
|
||||||
//eee->conf.register_interval = ra.lifetime;
|
|
||||||
}
|
/* NOTE: the register_interval should be chosen by the edge node
|
||||||
else
|
* based on its NAT configuration. */
|
||||||
{
|
//eee->conf.register_interval = ra.lifetime;
|
||||||
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old cookie.");
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
else
|
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old cookie.");
|
||||||
{
|
}
|
||||||
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER.");
|
}
|
||||||
}
|
else
|
||||||
break;
|
{
|
||||||
|
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
} case MSG_TYPE_PEER_INFO: {
|
} case MSG_TYPE_PEER_INFO: {
|
||||||
n2n_PEER_INFO_t pi;
|
n2n_PEER_INFO_t pi;
|
||||||
struct peer_info * scan;
|
struct peer_info * scan;
|
||||||
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
|
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
|
||||||
|
|
||||||
if(!is_valid_peer_sock(&pi.sock)) {
|
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]",
|
if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp)) {
|
||||||
sock_to_cstr(sockbuf1, &pi.sock),
|
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped PEER_INFO due to time stamp error.");
|
||||||
macaddr_str(mac_buf1, pi.mac) );
|
return;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!is_valid_peer_sock(&pi.sock)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]",
|
||||||
|
sock_to_cstr(sockbuf1, &pi.sock),
|
||||||
|
macaddr_str(mac_buf1, pi.mac) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
HASH_FIND_PEER(eee->pending_peers, pi.mac, scan);
|
HASH_FIND_PEER(eee->pending_peers, pi.mac, scan);
|
||||||
if(scan) {
|
if(scan) {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len,
|
uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len,
|
||||||
char * community_name, he_context_t * ctx,
|
char * community_name, he_context_t * ctx,
|
||||||
he_context_t * ctx_iv, uint16_t * checksum) {
|
he_context_t * ctx_iv, uint64_t * stamp, uint16_t * checksum) {
|
||||||
|
|
||||||
// assemble IV
|
// assemble IV
|
||||||
// the last four are ASCII "n2n!" and do not get overwritten
|
// the last four are ASCII "n2n!" and do not get overwritten
|
||||||
|
@ -35,9 +35,10 @@ uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len,
|
||||||
// to full 128 bit IV
|
// to full 128 bit IV
|
||||||
memcpy (iv, packet, 12);
|
memcpy (iv, packet, 12);
|
||||||
|
|
||||||
// extract checksum (last 16 bit) blended in IV
|
// extract time stamp (first 64 bit) and checksum (last 16 bit) blended in IV
|
||||||
speck_he_iv_decrypt (iv, (speck_context_t*)ctx_iv);
|
speck_he_iv_decrypt (iv, (speck_context_t*)ctx_iv);
|
||||||
*checksum = be16toh (((uint16_t*)iv)[5]);
|
*checksum = be16toh (((uint16_t*)iv)[5]);
|
||||||
|
*stamp = be64toh (((uint64_t*)iv)[0]);
|
||||||
|
|
||||||
memcpy (iv, packet, 12);
|
memcpy (iv, packet, 12);
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len,
|
||||||
/* ********************************************************************** */
|
/* ********************************************************************** */
|
||||||
|
|
||||||
int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx,
|
int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx,
|
||||||
he_context_t * ctx_iv, uint16_t checksum) {
|
he_context_t * ctx_iv, uint64_t stamp, uint16_t checksum) {
|
||||||
|
|
||||||
uint8_t iv[16];
|
uint8_t iv[16];
|
||||||
uint16_t *iv16 = (uint16_t*)&iv;
|
uint16_t *iv16 = (uint16_t*)&iv;
|
||||||
|
@ -79,7 +80,7 @@ int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_
|
||||||
|
|
||||||
memcpy (&packet[16], &packet[00], 4);
|
memcpy (&packet[16], &packet[00], 4);
|
||||||
|
|
||||||
iv64[0] = n2n_rand ();
|
iv64[0] = htobe64 (stamp);
|
||||||
iv16[4] = n2n_rand ();
|
iv16[4] = n2n_rand ();
|
||||||
iv16[5] = htobe16 (checksum);
|
iv16[5] = htobe16 (checksum);
|
||||||
iv32[3] = htobe32 (magic);
|
iv32[3] = htobe32 (magic);
|
||||||
|
|
92
src/n2n.c
92
src/n2n.c
|
@ -22,6 +22,13 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define PURGE_REGISTRATION_FREQUENCY 30
|
||||||
|
#define REGISTRATION_TIMEOUT 60
|
||||||
|
|
||||||
|
#define TIME_STAMP_FRAME 0x0000001000000000LL /* clocks of different computers are allowed +/- 16 seconds to be off */
|
||||||
|
#define TIME_STAMP_JITTER 0x0000000027100000LL /* we allow a packet to arrive 160 ms (== 0x27100 us) before another
|
||||||
|
* set to 0x0000000000000000LL if increasing (or equal) time stamps allowed only */
|
||||||
static const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
static const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
static const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */
|
static const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */
|
||||||
static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */
|
static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */
|
||||||
|
@ -380,3 +387,88 @@ int sock_equal(const n2n_sock_t * a,
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *********************************************** */
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(__GNUC__)
|
||||||
|
int gettimeofday(struct timeval *tp, void *tzp) {
|
||||||
|
time_t clock;
|
||||||
|
struct tm tm;
|
||||||
|
SYSTEMTIME wtm;
|
||||||
|
GetLocalTime(&wtm);
|
||||||
|
tm.tm_year = wtm.wYear - 1900;
|
||||||
|
tm.tm_mon = wtm.wMonth - 1;
|
||||||
|
tm.tm_mday = wtm.wDay;
|
||||||
|
tm.tm_hour = wtm.wHour;
|
||||||
|
tm.tm_min = wtm.wMinute;
|
||||||
|
tm.tm_sec = wtm.wSecond;
|
||||||
|
tm.tm_isdst = -1;
|
||||||
|
clock = mktime(&tm);
|
||||||
|
tp->tv_sec = clock;
|
||||||
|
tp->tv_usec = wtm.wMilliseconds * 1000;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// returns a time stamp for use with replay protection
|
||||||
|
uint64_t time_stamp (void) {
|
||||||
|
|
||||||
|
struct timeval tod;
|
||||||
|
uint64_t micro_seconds;
|
||||||
|
|
||||||
|
gettimeofday (&tod, NULL);
|
||||||
|
/* We will (roughly) calculate the microseconds since 1970 leftbound into the return value.
|
||||||
|
The leading 32 bits are used for tv_sec. The following 20 bits (sufficent as microseconds
|
||||||
|
fraction never exceeds 1,000,000,) encode the value tv_usec. The remaining lowest 12 bits
|
||||||
|
are kept random for use in IV */
|
||||||
|
micro_seconds = n2n_rand();
|
||||||
|
micro_seconds = ( (((uint64_t)(tod.tv_sec) << 32) + (tod.tv_usec << 12))
|
||||||
|
| (micro_seconds >> 52) );
|
||||||
|
// more exact but more costly due to the multiplication:
|
||||||
|
// micro_seconds = (tod.tv_sec * 1000000 + tod.tv_usec) << 12) | ...
|
||||||
|
|
||||||
|
return (micro_seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns an initial time stamp for use with replay protection
|
||||||
|
uint64_t initial_time_stamp (void) {
|
||||||
|
|
||||||
|
return ( time_stamp() - TIME_STAMP_FRAME );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// checks if a provided time stamp is consistent with current time and previously valid time stamps
|
||||||
|
// and, in case of validity, updates the "last valid time stamp"
|
||||||
|
int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp) {
|
||||||
|
|
||||||
|
int64_t diff; // do not change to unsigned
|
||||||
|
|
||||||
|
// is it around current time (+/- allowed deviation TIME_STAMP_FRAME)?
|
||||||
|
diff = stamp - time_stamp();
|
||||||
|
// abs()
|
||||||
|
diff = (diff < 0 ? -diff : diff);
|
||||||
|
if(diff >= TIME_STAMP_FRAME) {
|
||||||
|
traceEvent(TRACE_DEBUG, "time_stamp_verify_and_update found a timestamp out of allowed frame.");
|
||||||
|
return (0); // failure
|
||||||
|
}
|
||||||
|
|
||||||
|
// if applicable: is it higher than previous time stamp (including allowed deviation of TIME_STAMP_JITTER)?
|
||||||
|
if(NULL != previous_stamp) {
|
||||||
|
// if no jitter allowed, reset lowest three (random) nybbles; the codnition shoudl already be evaluated by the compiler
|
||||||
|
if(TIME_STAMP_JITTER == 0) {
|
||||||
|
stamp = (stamp >> 12) << 12;
|
||||||
|
*previous_stamp = (*previous_stamp >> 12) << 12;
|
||||||
|
}
|
||||||
|
diff = stamp - *previous_stamp + TIME_STAMP_JITTER;
|
||||||
|
if(diff <= 0) {
|
||||||
|
traceEvent(TRACE_DEBUG, "time_stamp_verify_and_update found a timestamp too old compared to previous.");
|
||||||
|
return (0); // failure
|
||||||
|
}
|
||||||
|
// for not allowing to exploit the allowed TIME_STAMP_JITTER to "turn the clock backwards",
|
||||||
|
// set the higher of the values
|
||||||
|
*previous_stamp = (stamp > *previous_stamp ? stamp : *previous_stamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1); // success
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "n2n.h"
|
#include "n2n.h"
|
||||||
#include "header_encryption.h"
|
|
||||||
|
|
||||||
#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out)
|
#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out)
|
||||||
|
|
||||||
|
@ -51,6 +50,8 @@ static int process_udp(n2n_sn_t *sss,
|
||||||
size_t udp_size,
|
size_t udp_size,
|
||||||
time_t now);
|
time_t now);
|
||||||
|
|
||||||
|
/* ************************************** */
|
||||||
|
|
||||||
static int try_forward(n2n_sn_t * sss,
|
static int try_forward(n2n_sn_t * sss,
|
||||||
const struct sn_community *comm,
|
const struct sn_community *comm,
|
||||||
const n2n_common_t * cmn,
|
const n2n_common_t * cmn,
|
||||||
|
@ -266,6 +267,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));
|
||||||
|
scan->last_valid_time_stamp = initial_time_stamp ();
|
||||||
|
|
||||||
HASH_ADD_PEER(comm->edges, scan);
|
HASH_ADD_PEER(comm->edges, scan);
|
||||||
|
|
||||||
|
@ -296,6 +298,31 @@ static int update_edge(n2n_sn_t *sss,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* For a given packet, find the apporopriate internal last valid time stamp for lookup
|
||||||
|
* and verify it (and also update, if applicable).
|
||||||
|
*/
|
||||||
|
static int find_edge_time_stamp_and_verify (struct peer_info * edges,
|
||||||
|
int from_supernode, n2n_mac_t mac,
|
||||||
|
uint64_t stamp) {
|
||||||
|
|
||||||
|
uint64_t * previous_stamp = NULL;
|
||||||
|
|
||||||
|
if(!from_supernode) {
|
||||||
|
struct peer_info *edge;
|
||||||
|
HASH_FIND_PEER(edges, mac, edge);
|
||||||
|
if(edge) {
|
||||||
|
// time_stamp_verify_and_update allows the pointer a previous stamp to be NULL
|
||||||
|
// if it is a (so far) unknown edge
|
||||||
|
previous_stamp = &(edge->last_valid_time_stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// failure --> 0; success --> 1
|
||||||
|
return ( time_stamp_verify_and_update (stamp, previous_stamp) );
|
||||||
|
}
|
||||||
|
|
||||||
static int purge_expired_communities(n2n_sn_t *sss,
|
static int purge_expired_communities(n2n_sn_t *sss,
|
||||||
time_t* p_last_purge,
|
time_t* p_last_purge,
|
||||||
time_t now)
|
time_t now)
|
||||||
|
@ -325,6 +352,7 @@ static int purge_expired_communities(n2n_sn_t *sss,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int process_mgmt(n2n_sn_t *sss,
|
static int process_mgmt(n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr_in *sender_sock,
|
||||||
const uint8_t *mgmt_buf,
|
const uint8_t *mgmt_buf,
|
||||||
|
@ -447,6 +475,7 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
n2n_sock_str_t sockbuf;
|
n2n_sock_str_t sockbuf;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
struct sn_community *comm, *tmp;
|
struct sn_community *comm, *tmp;
|
||||||
|
uint64_t stamp;
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]",
|
traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]",
|
||||||
udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)),
|
udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)),
|
||||||
|
@ -493,7 +522,11 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
continue;
|
continue;
|
||||||
uint16_t checksum = 0;
|
uint16_t checksum = 0;
|
||||||
if ( (ret = packet_header_decrypt (udp_buf, udp_size, comm->community, comm->header_encryption_ctx,
|
if ( (ret = packet_header_decrypt (udp_buf, udp_size, comm->community, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx, &checksum)) ) {
|
comm->header_iv_ctx,
|
||||||
|
&stamp, &checksum)) ) {
|
||||||
|
// time stamp verification follows in the packet specific section as it requires to determine the
|
||||||
|
// sender from the hash list by its MAC, this all depends on packet type and packet structure
|
||||||
|
// (MAC is not always in the same place)
|
||||||
if (checksum != pearson_hash_16 (udp_buf, udp_size)) {
|
if (checksum != pearson_hash_16 (udp_buf, udp_size)) {
|
||||||
traceEvent(TRACE_DEBUG, "process_udp dropped packet due to checksum error.");
|
traceEvent(TRACE_DEBUG, "process_udp dropped packet due to checksum error.");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -564,6 +597,14 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
sss->stats.last_fwd=now;
|
sss->stats.last_fwd=now;
|
||||||
decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx);
|
decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
|
// already checked for valid comm
|
||||||
|
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
|
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, pkt.srcMac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "process_udp dropped PACKET due to time stamp error.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unicast = (0 == is_multi_broadcast(pkt.dstMac));
|
unicast = (0 == is_multi_broadcast(pkt.dstMac));
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "RX PACKET (%s) %s -> %s %s",
|
traceEvent(TRACE_DEBUG, "RX PACKET (%s) %s -> %s %s",
|
||||||
|
@ -593,7 +634,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (rec_buf, oldEncx, comm->header_encryption_ctx,
|
packet_header_encrypt (rec_buf, oldEncx, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx, pearson_hash_16 (rec_buf, encx));
|
comm->header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (rec_buf, encx));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Already from a supernode. Nothing to modify, just pass to
|
/* Already from a supernode. Nothing to modify, just pass to
|
||||||
|
@ -606,7 +648,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (rec_buf, idx, comm->header_encryption_ctx,
|
packet_header_encrypt (rec_buf, idx, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx, pearson_hash_16 (rec_buf, udp_size));
|
comm->header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (rec_buf, udp_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Common section to forward the final product. */
|
/* Common section to forward the final product. */
|
||||||
|
@ -635,6 +678,14 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
sss->stats.last_fwd=now;
|
sss->stats.last_fwd=now;
|
||||||
decode_REGISTER(®, &cmn, udp_buf, &rem, &idx);
|
decode_REGISTER(®, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
|
// already checked for valid comm
|
||||||
|
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
|
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.srcMac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER due to time stamp error.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unicast = (0 == is_multi_broadcast(reg.dstMac));
|
unicast = (0 == is_multi_broadcast(reg.dstMac));
|
||||||
|
|
||||||
if(unicast) {
|
if(unicast) {
|
||||||
|
@ -667,7 +718,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (rec_buf, encx, comm->header_encryption_ctx,
|
packet_header_encrypt (rec_buf, encx, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx, pearson_hash_16 (rec_buf, encx));
|
comm->header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (rec_buf, encx));
|
||||||
|
|
||||||
try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */
|
try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */
|
||||||
} else
|
} else
|
||||||
|
@ -690,6 +742,15 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
++(sss->stats.reg_super);
|
++(sss->stats.reg_super);
|
||||||
decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx);
|
decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
|
if (comm) {
|
||||||
|
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
|
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Before we move any further, we need to check if the requested
|
Before we move any further, we need to check if the requested
|
||||||
community is allowed by the supernode. In case it is not we do
|
community is allowed by the supernode. In case it is not we do
|
||||||
|
@ -739,7 +800,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx,
|
packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx, pearson_hash_16 (ackbuf, encx));
|
comm->header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (ackbuf, encx));
|
||||||
|
|
||||||
sendto(sss->sock, ackbuf, encx, 0,
|
sendto(sss->sock, ackbuf, encx, 0,
|
||||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
|
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
|
||||||
|
@ -766,6 +828,14 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx );
|
decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx );
|
||||||
|
|
||||||
|
// already checked for valid comm
|
||||||
|
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
|
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, query.srcMac, stamp)) {
|
||||||
|
traceEvent(TRACE_DEBUG, "process_udp dropped QUERY_PEER due to time stamp error.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s",
|
traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s",
|
||||||
macaddr_str( mac_buf, query.srcMac ),
|
macaddr_str( mac_buf, query.srcMac ),
|
||||||
macaddr_str( mac_buf2, query.targetMac ) );
|
macaddr_str( mac_buf2, query.targetMac ) );
|
||||||
|
@ -787,7 +857,8 @@ static int process_udp(n2n_sn_t * sss,
|
||||||
|
|
||||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||||
packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx,
|
packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx,
|
||||||
comm->header_iv_ctx, pearson_hash_16 (encbuf, encx));
|
comm->header_iv_ctx,
|
||||||
|
time_stamp (), pearson_hash_16 (encbuf, encx));
|
||||||
|
|
||||||
sendto( sss->sock, encbuf, encx, 0,
|
sendto( sss->sock, encbuf, encx, 0,
|
||||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
|
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
|
||||||
|
|
|
@ -18,26 +18,6 @@
|
||||||
|
|
||||||
#include "n2n.h"
|
#include "n2n.h"
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__)
|
|
||||||
static int gettimeofday(struct timeval *tp, void *tzp)
|
|
||||||
{
|
|
||||||
time_t clock;
|
|
||||||
struct tm tm;
|
|
||||||
SYSTEMTIME wtm;
|
|
||||||
GetLocalTime(&wtm);
|
|
||||||
tm.tm_year = wtm.wYear - 1900;
|
|
||||||
tm.tm_mon = wtm.wMonth - 1;
|
|
||||||
tm.tm_mday = wtm.wDay;
|
|
||||||
tm.tm_hour = wtm.wHour;
|
|
||||||
tm.tm_min = wtm.wMinute;
|
|
||||||
tm.tm_sec = wtm.wSecond;
|
|
||||||
tm.tm_isdst = -1;
|
|
||||||
clock = mktime(&tm);
|
|
||||||
tp->tv_sec = clock;
|
|
||||||
tp->tv_usec = wtm.wMilliseconds * 1000;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t PKT_CONTENT[]={
|
uint8_t PKT_CONTENT[]={
|
||||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
|
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user