babeld: babelz merge.

Babelz is the last version of the stand-alone babel daemon. In
particular, it use multiple channels to diminuate
interferences. Please refer to this one for more details.
diff --git a/babeld/source.c b/babeld/source.c
index cc4ed44..772112d 100644
--- a/babeld/source.c
+++ b/babeld/source.c
@@ -63,8 +63,10 @@
             continue;
         if(memcmp(src->id, id, 8) != 0)
             continue;
-        if(source_match(src, p, plen))
-           return src;
+        if(src->plen != plen)
+            continue;
+        if(memcmp(src->prefix, p, 16) == 0)
+            return src;
     }
 
     if(!create)
@@ -82,18 +84,32 @@
     src->seqno = seqno;
     src->metric = INFINITY;
     src->time = babel_now.tv_sec;
+    src->route_count = 0;
     src->next = srcs;
     srcs = src;
     return src;
 }
 
+struct source *
+retain_source(struct source *src)
+{
+    assert(src->route_count < 0xffff);
+    src->route_count++;
+    return src;
+}
+
+void
+release_source(struct source *src)
+{
+    assert(src->route_count > 0);
+    src->route_count--;
+}
+
 int
 flush_source(struct source *src)
 {
-    /* This is absolutely horrible -- it makes expire_sources quadratic.
-       But it's not called very often. */
-
-    if (babel_route_get_by_source(src) != NULL)
+    if(src->route_count > 0)
+        /* The source is in use by a route. */
         return 0;
 
     if(srcs == src) {
@@ -109,19 +125,6 @@
     return 1;
 }
 
-int
-source_match(struct source *src,
-             const unsigned char *p, unsigned char plen)
-{
-    if(src->plen != plen)
-        return 0;
-    if(src->prefix[15] != p[15])
-        return 0;
-    if(memcmp(src->prefix, p, 16) != 0)
-        return 0;
-    return 1;
-}
-
 void
 update_source(struct source *src,
               unsigned short seqno, unsigned short metric)
@@ -129,6 +132,10 @@
     if(metric >= INFINITY)
         return;
 
+    /* If a source is expired, pretend that it doesn't exist and update
+       it unconditionally.  This makes ensures that old data will
+       eventually be overridden, and prevents us from getting stuck if
+       a router loses its sequence number. */
     if(src->time < babel_now.tv_sec - SOURCE_GC_TIME ||
        seqno_compare(src->seqno, seqno) < 0 ||
        (src->seqno == seqno && src->metric > metric)) {
@@ -157,3 +164,17 @@
         src = src->next;
     }
 }
+
+void
+check_sources_released(void)
+{
+    struct source *src;
+
+    for(src = srcs; src; src = src->next) {
+        if(src->route_count != 0)
+            fprintf(stderr, "Warning: source %s %s has refcount %d.\n",
+                    format_eui64(src->id),
+                    format_prefix(src->prefix, src->plen),
+                    (int)src->route_count);
+    }
+}