Browse Source

removed jitter allowance for systemic packets

pull/427/head
Logan007 4 years ago
parent
commit
2c77729acf
  1. 2
      doc/Crypto.md
  2. 2
      include/n2n.h
  3. 2
      include/n2n_define.h
  4. 14
      src/edge_utils.c
  5. 12
      src/n2n.c
  6. 12
      src/sn_utils.c

2
doc/Crypto.md

@ -191,6 +191,8 @@ Upon receival, the time stamp as well as the checksum can be extracted from the
- The (remote) time stamp is checked against the local clock. It may not deviate more than plus/minus 16 seconds. So, edges and supernode need to keep a somewhat current time. This limit can be adjusted by changing the `TIME_STAMP_FRAME` definition. It is time-zone indifferent as UTC is used.
- However, the systemic packets such as REGISTER_SUPER are not allowed any time stamp jitter because n2n relies on the actual sender's socket. A replay from another IP within any allowed jitter time frame would deviate the traffic which shall be prevented (even if it remains undecryptable). Under absolutely rare (!) circumstances, this might cause a re-registration requirement which happens automatically but might cause a small delay – security (including network availability) first!
- Valid (remote) time stamps get stored as "last valid time stamp" seen from each node (supernode and edges). So, a newly arriving packet's time stamp can be compared to the last valid one. It should be equal or higher. However, as UDP packets may overtake each other just by taking another path through the internet, they are allowed to be 160 millisecond earlier than the last valid one. This limit can be adjusted by changing the `TIME_STAMP_JITTER` definition.
The way the IV is used for replay protection and for checksumming makes enabled header encryption a prerequisite for these features.

2
include/n2n.h

@ -459,7 +459,7 @@ int sock_equal( const n2n_sock_t * a,
/* 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);
int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp, int allow_jitter);
/* Operations on peer_info lists. */
size_t purge_peer_list( struct peer_info ** peer_list,

2
include/n2n_define.h

@ -50,6 +50,8 @@
#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 */
#define TIME_STAMP_ALLOW_JITTER 1 /* constant for allowing or... */
#define TIME_STAMP_NO_JITTER 0 /* not allowing jitter to be considered */
/* N2N compression indicators. */
/* Compression is disabled by default for outgoing packets if no cli

14
src/edge_utils.c

@ -394,7 +394,7 @@ static const int definitely_from_supernode = 1;
*/
static int find_peer_time_stamp_and_verify (n2n_edge_t * eee,
int from_supernode, const n2n_mac_t mac,
uint64_t stamp) {
uint64_t stamp, int allow_jitter) {
uint64_t * previous_stamp = NULL;
@ -416,7 +416,7 @@ static int find_peer_time_stamp_and_verify (n2n_edge_t * eee,
}
// failure --> 0; success --> 1
return ( time_stamp_verify_and_update (stamp, previous_stamp) );
return ( time_stamp_verify_and_update (stamp, previous_stamp, allow_jitter) );
}
/* ************************************** */
@ -1787,7 +1787,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx);
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
if(!find_peer_time_stamp_and_verify (eee, from_supernode, pkt.srcMac, stamp)) {
if(!find_peer_time_stamp_and_verify (eee, from_supernode, pkt.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) {
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped PACKET due to time stamp error.");
return;
}
@ -1827,7 +1827,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
decode_REGISTER(&reg, &cmn, udp_buf, &rem, &idx);
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
if(!find_peer_time_stamp_and_verify (eee, from_supernode, reg.srcMac, stamp)) {
if(!find_peer_time_stamp_and_verify (eee, from_supernode, reg.srcMac, stamp, TIME_STAMP_NO_JITTER)) {
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER due to time stamp error.");
return;
}
@ -1878,7 +1878,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
decode_REGISTER_ACK(&ra, &cmn, udp_buf, &rem, &idx);
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
if(!find_peer_time_stamp_and_verify (eee, !definitely_from_supernode, ra.srcMac, stamp)) {
if(!find_peer_time_stamp_and_verify (eee, !definitely_from_supernode, ra.srcMac, stamp, TIME_STAMP_NO_JITTER)) {
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER_ACK due to time stamp error.");
return;
}
@ -1918,7 +1918,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx);
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp)) {
if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp, TIME_STAMP_NO_JITTER)) {
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER_SUPER_ACK due to time stamp error.");
return;
}
@ -1988,7 +1988,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) {
if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp)) {
if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp, TIME_STAMP_ALLOW_JITTER)) {
traceEvent(TRACE_DEBUG, "readFromIPSocket dropped PEER_INFO due to time stamp error.");
return;
}

12
src/n2n.c

@ -468,7 +468,7 @@ uint64_t initial_time_stamp (void) {
// 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) {
int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp, int allow_jitter) {
int64_t diff; // do not change to unsigned
@ -483,12 +483,14 @@ int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp) {
// 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) {
// always reset lowest three (random) nybbles -- important in case of no jitter, do not if() to avoid jumping
stamp = (stamp >> 12) << 12;
*previous_stamp = (*previous_stamp >> 12) << 12;
}
diff = stamp - *previous_stamp + TIME_STAMP_JITTER;
diff = stamp - *previous_stamp;
if (allow_jitter)
diff += 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

12
src/sn_utils.c

@ -456,7 +456,7 @@ int assign_one_ip_subnet(n2n_sn_t *sss,
*/
static int find_edge_time_stamp_and_verify (struct peer_info * edges,
int from_supernode, n2n_mac_t mac,
uint64_t stamp) {
uint64_t stamp, int allow_jitter) {
uint64_t * previous_stamp = NULL;
@ -471,7 +471,7 @@ static int find_edge_time_stamp_and_verify (struct peer_info * edges,
}
// failure --> 0; success --> 1
return ( time_stamp_verify_and_update (stamp, previous_stamp) );
return ( time_stamp_verify_and_update (stamp, previous_stamp, allow_jitter) );
}
static int purge_expired_communities(n2n_sn_t *sss,
@ -784,7 +784,7 @@ static int process_udp(n2n_sn_t * sss,
// 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)) {
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, pkt.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) {
traceEvent(TRACE_DEBUG, "process_udp dropped PACKET due to time stamp error.");
return -1;
}
@ -865,7 +865,7 @@ static int process_udp(n2n_sn_t * sss,
// 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)) {
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.srcMac, stamp, TIME_STAMP_NO_JITTER)) {
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER due to time stamp error.");
return -1;
}
@ -936,7 +936,7 @@ static int process_udp(n2n_sn_t * sss,
if (comm) {
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp)) {
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp, TIME_STAMP_NO_JITTER)) {
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error.");
return -1;
}
@ -1054,7 +1054,7 @@ static int process_udp(n2n_sn_t * sss,
// 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)) {
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, query.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) {
traceEvent(TRACE_DEBUG, "process_udp dropped QUERY_PEER due to time stamp error.");
return -1;
}

Loading…
Cancel
Save