Better handling of late packets.
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 18 Apr 2003 21:18:36 +0000 (21:18 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 18 Apr 2003 21:18:36 +0000 (21:18 +0000)
src/net_packet.c
src/node.h
src/protocol_key.c

index 07f578e52e2c9aded212a8f0b10aba4630231bcf..724eaa33e06ac3a3a524b99214502c8818748c1d 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net_packet.c,v 1.1.2.26 2003/03/28 13:41:49 guus Exp $
+    $Id: net_packet.c,v 1.1.2.27 2003/04/18 21:18:36 guus Exp $
 */
 
 #include "config.h"
@@ -95,6 +95,7 @@ void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
        int outlen, outpad;
        long int complen = MTU + 12;
        char hmac[EVP_MAX_MD_SIZE];
+       int i;
 
        cp();
 
@@ -133,16 +134,26 @@ 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) {
-               if(debug_lvl >= DEBUG_TRAFFIC)
-                       syslog(LOG_DEBUG,
-                                  _("Got late or replayed packet from %s (%s), seqno %d"),
-                                  n->name, n->hostname, inpkt->seqno);
-               return;
+       if(inpkt->seqno != n->received_seqno + 1) {
+               if(inpkt->seqno >= n->received_seqno + sizeof(n->late) * 8) {
+                       if(debug_lvl >= DEBUG_TRAFFIC)
+                               syslog(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(inpkt->seqno <= n->received_seqno - sizeof(n->late) * 8 || !(n->late[(inpkt->seqno / 8) % sizeof(n->late)] & (1 << inpkt->seqno % 8))) {
+                               syslog(LOG_WARNING, _("Got late or replayed packet from %s (%s), seqno %d, last received %d"),
+                                          n->name, n->hostname, inpkt->seqno, n->received_seqno, n->late[(inpkt->seqno / 8) % sizeof(n->late)]);
+                       } else
+                               for(i = n->received_seqno + 1; i < inpkt->seqno; i++)
+                                       n->late[(inpkt->seqno / 8) % sizeof(n->late)] |= 1 << i % 8;
+               }
        }
-
+       
        n->received_seqno = inpkt->seqno;
-
+       n->late[(n->received_seqno / 8) % sizeof(n->late)] &= ~(1 << n->received_seqno % 8);
+                       
        if(n->received_seqno > MAX_SEQNO)
                keyexpires = 0;
 
index e4dcd5249f7ac62cc76ddebab95c6621d734c825..6e5e68eb0f43b3b688f041b2f6692e1143c30976 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: node.h,v 1.1.2.20 2002/09/09 21:24:41 guus Exp $
+    $Id: node.h,v 1.1.2.21 2003/04/18 21:18:36 guus Exp $
 */
 
 #ifndef __TINC_NODE_H__
@@ -73,6 +73,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 */
+       unsigned char late[16]; /* Bitfield marking late packets */
 } node_t;
 
 extern struct node_t *myself;
index 2453975d1fb345972bcfcb292d1c6bd771f80be5..786a8a17ed9da522595cd7fa989cdd61ff50c0a9 100644 (file)
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol_key.c,v 1.1.4.14 2002/09/09 22:33:03 guus Exp $
+    $Id: protocol_key.c,v 1.1.4.15 2003/04/18 21:18:36 guus Exp $
 */
 
 #include "config.h"
@@ -135,6 +135,7 @@ int req_key_h(connection_t *c)
        if(to == myself) {                      /* Yes, send our own key back */
                mykeyused = 1;
                from->received_seqno = 0;
+               memset(from->late, 0, sizeof(from->late));
                send_ans_key(c, myself, from);
        } else {
                send_req_key(to->nexthop->connection, from, to);