Improved handling of queue-jumping packets on receive
authorBrandon L Black <blblack@gmail.com>
Sat, 13 Nov 2010 18:05:51 +0000 (12:05 -0600)
committerGuus Sliepen <guus@tinc-vpn.org>
Sat, 13 Nov 2010 20:25:48 +0000 (21:25 +0100)
src/net_packet.c
src/node.h

index b35f72d..9c55129 100644 (file)
@@ -298,9 +298,13 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
        if(replaywin) {
                if(inpkt->seqno != n->received_seqno + 1) {
                        if(inpkt->seqno >= n->received_seqno + replaywin * 8) {
        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);
                                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))) {
                                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))) {
@@ -313,7 +317,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
                                        n->late[(i / 8) % replaywin] |= 1 << i % 8;
                        }
                }
                                        n->late[(i / 8) % replaywin] |= 1 << i % 8;
                        }
                }
-       
+
+               n->farfuture = 0;
                n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8);
        }
 
                n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8);
        }
 
index de0f8c8..7bac28e 100644 (file)
@@ -77,6 +77,7 @@ typedef struct node_t {
 
        uint32_t sent_seqno;                    /* Sequence number last sent to this node */
        uint32_t received_seqno;                /* Sequence number last received from this node */
 
        uint32_t sent_seqno;                    /* Sequence number last sent to this node */
        uint32_t received_seqno;                /* Sequence number last received from this node */
+       uint32_t farfuture;                     /* Packets in a row that have arrived from the far future */
        unsigned char* late;                    /* Bitfield marking late packets */
 
        length_t mtu;                           /* Maximum size of packets to send to this node */
        unsigned char* late;                    /* Bitfield marking late packets */
 
        length_t mtu;                           /* Maximum size of packets to send to this node */