mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
added time stamp blending and sending
This commit is contained in:
parent
d3e823af98
commit
895bbc2844
|
@ -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,
|
||||||
|
|
|
@ -428,6 +428,10 @@ 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);
|
||||||
|
int time_stamp_verify (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 );
|
||||||
|
|
|
@ -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 */
|
||||||
|
@ -731,7 +730,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,7 +763,8 @@ 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) );
|
||||||
}
|
}
|
||||||
|
@ -810,7 +811,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 +855,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);
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1474,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 +1568,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 +1606,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;
|
||||||
|
@ -1635,6 +1646,15 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
|
|
||||||
decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx);
|
decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx);
|
||||||
|
|
||||||
|
// !!!
|
||||||
|
/* if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
|
||||||
|
|
||||||
|
if ( !time_stamp_verify (stamp, &... !!!) ) {
|
||||||
|
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped packet due to time stamp error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
if(is_valid_peer_sock(&pkt.sock))
|
if(is_valid_peer_sock(&pkt.sock))
|
||||||
orig_sender = &(pkt.sock);
|
orig_sender = &(pkt.sock);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
15
src/n2n.c
15
src/n2n.c
|
@ -427,14 +427,14 @@ uint64_t time_stamp (void) {
|
||||||
|
|
||||||
|
|
||||||
// checks if a provided time stamp is consistent with current time and previously valid time stamps
|
// checks if a provided time stamp is consistent with current time and previously valid time stamps
|
||||||
// returns the time stamp to store as "last valid time stamp" or zero in case of invalid time stamp
|
// and, in case of validity, replaces the "last valid time stamp"
|
||||||
// REVISIT during the years 2035...2038
|
// REVISIT during the years 2035...2038
|
||||||
uint64_t time_stamp_verify (uint64_t stamp, uint64_t previous_stamp) {
|
int time_stamp_verify (uint64_t stamp, uint64_t * previous_stamp) {
|
||||||
|
|
||||||
int64_t diff; // do not change to unsigned
|
int64_t diff; // do not change to unsigned
|
||||||
|
|
||||||
// is it higher than previous time stamp (including allowed deviation of TIME_STAMP_JITTER)?
|
// is it higher than previous time stamp (including allowed deviation of TIME_STAMP_JITTER)?
|
||||||
diff = stamp - previous_stamp + TIME_STAMP_JITTER;
|
diff = stamp - *previous_stamp + TIME_STAMP_JITTER;
|
||||||
if(diff > 0) {
|
if(diff > 0) {
|
||||||
|
|
||||||
// is it around current time (+/- allowed deviation TIME_STAMP_FRAME)?
|
// is it around current time (+/- allowed deviation TIME_STAMP_FRAME)?
|
||||||
|
@ -445,16 +445,17 @@ uint64_t time_stamp_verify (uint64_t stamp, uint64_t previous_stamp) {
|
||||||
if(diff < TIME_STAMP_FRAME) {
|
if(diff < TIME_STAMP_FRAME) {
|
||||||
|
|
||||||
// for not allowing to exploit the allowed TIME_STAMP_JITTER to "turn the clock backwards",
|
// for not allowing to exploit the allowed TIME_STAMP_JITTER to "turn the clock backwards",
|
||||||
// return the higher value, max()
|
// set the higher of the values
|
||||||
return (stamp > previous_stamp ? stamp : previous_stamp);
|
*previous_stamp = (stamp > *previous_stamp ? stamp : *previous_stamp);
|
||||||
|
return (1); // success
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
traceEvent(TRACE_DEBUG, "time_stamp_verify found a timestamp out of allowed frame.");
|
traceEvent(TRACE_DEBUG, "time_stamp_verify found a timestamp out of allowed frame.");
|
||||||
return (0);
|
return (0); // failure
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
traceEvent(TRACE_DEBUG, "time_stamp_verify found a timestamp too old / older than previous.");
|
traceEvent(TRACE_DEBUG, "time_stamp_verify found a timestamp too old / older than previous.");
|
||||||
return (0);
|
return (0); // failure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
@ -391,6 +390,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)),
|
||||||
|
@ -437,7 +437,8 @@ 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)) ) {
|
||||||
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;
|
||||||
|
@ -537,7 +538,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
|
||||||
|
@ -550,7 +552,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. */
|
||||||
|
@ -611,7 +614,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
|
||||||
|
@ -683,7 +687,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));
|
||||||
|
@ -731,7 +736,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) );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user