chiark / gitweb /
svc/conntrack.in: Force reconnection on local IP address changes.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 15 May 2010 18:41:07 +0000 (19:41 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 15 May 2010 18:42:47 +0000 (19:42 +0100)
ICd or NetworkManager might roam to a new network, and tell us about it;
but if we decided that we wanted to stick with the same peer
specification then our peer will continue with the wrong IP address until
watch gets a ping timeout.

Of course, this doesn't trap other reasons we might change IP addresses
without anyone noticing, such as roaming to a different 3G NAT thingummy.

svc/conntrack.in

index 47f66f4d4485660a861f009818eeb6e3694eeb2c..b80f92edc0a4e88cc2ca8c99fad12bac14f6614d 100644 (file)
@@ -214,6 +214,7 @@ def localaddr(peer):
 
 _kick = T.Queue()
 def kickpeers():
+  lastip = {}
   while True:
     upness, reason = _kick.get()
 
@@ -233,35 +234,44 @@ def kickpeers():
       addr = localaddr(CF.testaddr)
       if addr is None:
         upness = False
+    else:
+      addr = None
 
     ## Now decide what to do.
     changes = []
     for g, pp in CF.groups:
 
       ## Find out which peer in the group ought to be active.
-      want = None                       # unequal to any string
-      if upness:
-        for t, p, a, m in pp:
-          if p is None:
-            aq = addr
-          else:
-            aq = localaddr(p)
-          if aq is not None and (aq & m) == a:
-            want = t
-            break
+      ip = None
+      map = {}
+      want = None
+      for t, p, a, m in pp:
+        if p is None or not upness:
+          ipq = addr
+        else:
+          ipq = localaddr(p)
+        if upness and ip is None and \
+              ipq is not None and (ipq & m) == a:
+          map[t] = 'up'
+          want = t
+          ip = ipq
+        else:
+          map[t] = 'down'
 
       ## Shut down the wrong ones.
       found = False
       for p in peers:
-        if p == want:
+        what = map.get(p, 'leave')
+        if what == 'up':
           found = True
-        elif p.startswith(g) and p != want:
+        elif what == 'down':
           changes.append(lambda p=p: SM.kill(p))
 
       ## Start the right one if necessary.
-      if want is not None and not found:
+      if want is not None and (not found or ip != lastip.get(g, None)):
         changes.append(lambda: T._simple(SM.svcsubmit('connect', 'active',
                                                       want)))
+      lastip[g] = ip
 
     ## Commit the changes.
     if changes: