hello reception: only remove UNSPEC duplicates
authorFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 3 Feb 2017 13:45:09 +0000 (14:45 +0100)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Tue, 7 Feb 2017 12:37:58 +0000 (13:37 +0100)
Only UNSPEC links can be duplicates, so only try to remove those.
This is quite a bit faster at the cost of some complexity.

Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
src/process_package.c

index 7f4e229..3a2f383 100644 (file)
@@ -60,6 +60,7 @@
 #include "lq_plugin.h"
 #include "log.h"
 
+#include <assert.h>
 #include <stddef.h>
 
 static void process_message_neighbors(struct neighbor_entry *, const struct hello_message *);
@@ -324,6 +325,10 @@ deserialize_hello(struct hello_message *hello, const void *ser)
   struct ipaddr_str buf;
   const unsigned char *curr_saved;
   unsigned int idx;
+  struct hello_neighbor *neigh_unspec_first_prev = NULL;
+  struct hello_neighbor *neigh_unspec_first = NULL;
+
+  assert(LINK_ORDER[0] == UNSPEC_LINK);
 
   memset (hello, 0, sizeof(*hello));
 
@@ -381,18 +386,24 @@ deserialize_hello(struct hello_message *hello, const void *ser)
 
         neigh->next = hello->neighbors;
         hello->neighbors = neigh;
+
+        if (neigh->link == UNSPEC_LINK) {
+          neigh_unspec_first = neigh;
+        } else if (!neigh_unspec_first_prev) {
+          neigh_unspec_first_prev = neigh;
+        }
       }
     }
   }
 
-  {
+  if (neigh_unspec_first_prev && neigh_unspec_first) {
     struct hello_neighbor *neigh;
-    for (neigh = hello->neighbors; neigh; neigh = neigh->next) {
+    for (neigh = hello->neighbors; neigh && (neigh != neigh_unspec_first); neigh = neigh->next) {
       struct hello_neighbor *neigh_cull;
       struct hello_neighbor *neigh_cull_prev;
       struct hello_neighbor *neigh_cull_next;
 
-      for (neigh_cull_prev = neigh, neigh_cull = neigh->next;
+      for (neigh_cull_prev = neigh_unspec_first_prev, neigh_cull = neigh_unspec_first;
            neigh_cull;
            neigh_cull = neigh_cull_next) {
         neigh_cull_next = neigh_cull->next;
@@ -402,6 +413,10 @@ deserialize_hello(struct hello_message *hello, const void *ser)
           continue;
         }
 
+        if (neigh_cull == neigh_unspec_first) {
+          neigh_unspec_first = neigh_cull_next;
+        }
+
         neigh_cull_prev->next = neigh_cull_next;
         free(neigh_cull);
       }