X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet_packet.c;h=9c5512996784dfe07029e1e3e65ed7849c500243;hp=44ab55d42c8a550f1fddad9a36c88aec0c813377;hb=0d61d4ae1358553fc8dde350747542f137f5cb8b;hpb=c6ccbadfcf93a7bd4a88dee8ff146b4db7f85e71 diff --git a/src/net_packet.c b/src/net_packet.c index 44ab55d4..9c551299 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -60,6 +60,8 @@ static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999 static void send_udppacket(node_t *, vpn_packet_t *); +unsigned replaywin = 16; + #define MAX_SEQNO 1073741824 // mtuprobes == 1..30: initial discovery, send bursts with 1 second interval @@ -293,25 +295,32 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { inpkt->len -= sizeof(inpkt->seqno); inpkt->seqno = ntohl(inpkt->seqno); - if(inpkt->seqno != n->received_seqno + 1) { - if(inpkt->seqno >= n->received_seqno + sizeof(n->late) * 8) { - logger(LOG_WARNING, "Lost %d packets from %s (%s)", - inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); - - memset(n->late, 0, sizeof(n->late)); - } else if (inpkt->seqno <= n->received_seqno) { - if((n->received_seqno >= sizeof(n->late) * 8 && inpkt->seqno <= n->received_seqno - sizeof(n->late) * 8) || !(n->late[(inpkt->seqno / 8) % sizeof(n->late)] & (1 << inpkt->seqno % 8))) { - logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, inpkt->seqno, n->received_seqno); - return; + if(replaywin) { + if(inpkt->seqno != n->received_seqno + 1) { + if(inpkt->seqno >= n->received_seqno + replaywin * 8) { + if(n->farfuture++ < replaywin >> 2) { + logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); + return; + } + logger(LOG_WARNING, "Lost %d packets from %s (%s)", + inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); + memset(n->late, 0, replaywin); + } else if (inpkt->seqno <= n->received_seqno) { + if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { + logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", + n->name, n->hostname, inpkt->seqno, n->received_seqno); + return; + } + } else { + for(i = n->received_seqno + 1; i < inpkt->seqno; i++) + n->late[(i / 8) % replaywin] |= 1 << i % 8; } - } else { - for(i = n->received_seqno + 1; i < inpkt->seqno; i++) - n->late[(i / 8) % sizeof(n->late)] |= 1 << i % 8; } + + n->farfuture = 0; + n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); } - - n->late[(inpkt->seqno / 8) % sizeof(n->late)] &= ~(1 << inpkt->seqno % 8); if(inpkt->seqno > n->received_seqno) n->received_seqno = inpkt->seqno;