chiark / gitweb /
(Python): Use more modern `raise' syntax.
[tripe] / svc / conntrack.in
index c86a7d8211e1b442cefec0f70ad945aa2b3258a6..3368295a46ec8d743dee349a503243dcca6b55ac 100644 (file)
 ###
 ### This file is part of Trivial IP Encryption (TrIPE).
 ###
-### TrIPE is free software; you can redistribute it and/or modify
-### it under the terms of the GNU General Public License as published by
-### the Free Software Foundation; either version 2 of the License, or
-### (at your option) any later version.
+### TrIPE is free software: you can redistribute it and/or modify it under
+### the terms of the GNU General Public License as published by the Free
+### Software Foundation; either version 3 of the License, or (at your
+### option) any later version.
 ###
-### TrIPE is distributed in the hope that it will be useful,
-### but WITHOUT ANY WARRANTY; without even the implied warranty of
-### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-### GNU General Public License for more details.
+### TrIPE is distributed in the hope that it will be useful, but WITHOUT
+### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+### FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+### for more details.
 ###
 ### You should have received a copy of the GNU General Public License
-### along with TrIPE; if not, write to the Free Software Foundation,
-### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+### along with TrIPE.  If not, see <https://www.gnu.org/licenses/>.
 
 VERSION = '@VERSION@'
 
@@ -39,7 +38,8 @@ import tripe as T
 import dbus as D
 for i in ['mainloop', 'mainloop.glib']:
   __import__('dbus.%s' % i)
-import gobject as G
+try: from gi.repository import GLib as G
+except ImportError: import gobject as G
 from struct import pack, unpack
 
 SM = T.svcmgr
@@ -194,7 +194,7 @@ class Config (object):
 ### This will be a configuration file.
 CF = None
 
-def straddr(a): return S.inet_ntoa(pack('>L', a))
+def straddr(a): return a is None and '#<none>' or S.inet_ntoa(pack('>L', a))
 def strmask(m):
   for i in xrange(33):
     if m == 0xffffffff ^ ((1 << (32 - i)) - 1): return i
@@ -211,7 +211,7 @@ def cmd_showgroup(g):
       pats = p
       break
   else:
-    raise T.TripeJobError, 'unknown-group', g
+    raise T.TripeJobError('unknown-group', g)
   for t, p, a, m in pats:
     T.svcinfo('peer', t,
               'target', p or '(default)',
@@ -321,7 +321,7 @@ def kickpeers():
       if want is not None and not found:
         def _(want = want):
           try:
-            SM.svcsubmit('connect', 'active', want)
+            list(SM.svcsubmit('connect', 'active', want))
           except T.TripeError, exc:
             SM.warn('conntrack', 'connect-failed', want, *exc.args)
         if T._debug: print '#   peer %s: bring up' % want
@@ -344,12 +344,21 @@ def netupdown(upness, reason):
 ###--------------------------------------------------------------------------
 ### NetworkManager monitor.
 
+DBPROPS_IFACE = 'org.freedesktop.DBus.Properties'
+
 NM_NAME = 'org.freedesktop.NetworkManager'
 NM_PATH = '/org/freedesktop/NetworkManager'
 NM_IFACE = NM_NAME
 NMCA_IFACE = NM_NAME + '.Connection.Active'
 
-NM_STATE_CONNECTED = 3
+NM_STATE_CONNECTED = 3 #obsolete
+NM_STATE_CONNECTED_LOCAL = 50
+NM_STATE_CONNECTED_SITE = 60
+NM_STATE_CONNECTED_GLOBAL = 70
+NM_CONNSTATES = set([NM_STATE_CONNECTED,
+                     NM_STATE_CONNECTED_LOCAL,
+                     NM_STATE_CONNECTED_SITE,
+                     NM_STATE_CONNECTED_GLOBAL])
 
 class NetworkManagerMonitor (object):
   """
@@ -368,21 +377,20 @@ class NetworkManagerMonitor (object):
   def attach(me, bus):
     try:
       nm = bus.get_object(NM_NAME, NM_PATH)
-      state = nm.Get(NM_IFACE, 'State')
-      if state == NM_STATE_CONNECTED:
+      state = nm.Get(NM_IFACE, 'State', dbus_interface = DBPROPS_IFACE)
+      if state in NM_CONNSTATES:
         netupdown(True, ['nm', 'initially-connected'])
       else:
         netupdown(False, ['nm', 'initially-disconnected'])
-    except D.DBusException:
-      pass
-    bus.add_signal_receiver(me._nm_state, 'StateChanged', NM_IFACE,
-                            NM_NAME, NM_PATH)
-    bus.add_signal_receiver(me._nm_connchange,
-                            'PropertiesChanged', NMCA_IFACE,
-                            NM_NAME, None)
+    except D.DBusException, e:
+      if T._debug: print '# exception attaching to network-manager: %s' % e
+    bus.add_signal_receiver(me._nm_state, 'StateChanged',
+                            NM_IFACE, NM_NAME, NM_PATH)
+    bus.add_signal_receiver(me._nm_connchange, 'PropertiesChanged',
+                            NMCA_IFACE, NM_NAME, None)
 
   def _nm_state(me, state):
-    if state == NM_STATE_CONNECTED:
+    if state in NM_CONNSTATES:
       netupdown(True, ['nm', 'connected'])
     else:
       netupdown(False, ['nm', 'disconnected'])
@@ -391,6 +399,38 @@ class NetworkManagerMonitor (object):
     if props.get('Default', False):
       netupdown(True, ['nm', 'default-connection-change'])
 
+##--------------------------------------------------------------------------
+### Connman monitor.
+
+CM_NAME = 'net.connman'
+CM_PATH = '/'
+CM_IFACE = 'net.connman.Manager'
+
+class ConnManMonitor (object):
+  """
+  Watch ConnMan signls for changes in network state.
+  """
+
+  ## Strategy.  Everything seems to be usefully encoded in the `State'
+  ## property.  If it's `offline', `idle' or `ready' then we don't expect a
+  ## network connection.  During handover from one network to another, the
+  ## property passes through `ready' to `online'.
+
+  def attach(me, bus):
+    try:
+      cm = bus.get_object(CM_NAME, CM_PATH)
+      props = cm.GetProperties(dbus_interface = CM_IFACE)
+      state = props['State']
+      netupdown(state == 'online', ['connman', 'initially-%s' % state])
+    except D.DBusException, e:
+      if T._debug: print '# exception attaching to connman: %s' % e
+    bus.add_signal_receiver(me._cm_state, 'PropertyChanged',
+                            CM_IFACE, CM_NAME, CM_PATH)
+
+  def _cm_state(me, prop, value):
+    if prop != 'State': return
+    netupdown(value == 'online', ['connman', value])
+
 ###--------------------------------------------------------------------------
 ### Maemo monitor.
 
@@ -421,7 +461,8 @@ class MaemoICdMonitor (object):
       except D.DBusException:
         me._iap = None
         netupdown(False, ['icd', 'initially-disconnected'])
-    except D.DBusException:
+    except D.DBusException, e:
+      if T._debug: print '# exception attaching to icd: %s' % e
       me._iap = None
     bus.add_signal_receiver(me._icd_state, 'status_changed', ICD_IFACE,
                             ICD_NAME, ICD_PATH)
@@ -542,6 +583,7 @@ def init():
   T.Coroutine(kickpeers, name = 'kickpeers').switch()
   DBM = DBusMonitor()
   DBM.addmon(NetworkManagerMonitor())
+  DBM.addmon(ConnManMonitor())
   DBM.addmon(MaemoICdMonitor())
   G.timeout_add_seconds(30, lambda: (netupdown(True, ['interval-timer'])
                                      or True))