X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/8d1d183ef5293bcd1e68dd4154b00a8a64d33fa8..11ab0da64ef849cf3d035ecaa08dd581144f1ad7:/svc/conntrack.in diff --git a/svc/conntrack.in b/svc/conntrack.in index 73793037..061d6d76 100644 --- a/svc/conntrack.in +++ b/svc/conntrack.in @@ -94,6 +94,9 @@ def toposort(cmp, things): if done: break +def parse_address(addrstr): + return unpack('>L', S.inet_aton(addrstr))[0] + ###-------------------------------------------------------------------------- ### Parse the configuration file. @@ -170,12 +173,12 @@ class Config (object): ## and MASK is either a dotted-quad or a single integer N indicating ## a mask with N leading ones followed by trailing zeroes. slash = net.index('/') - addr, = unpack('>L', S.inet_aton(net[:slash])) - if net.find('.', slash + 1) >= 0: - mask, = unpack('>L', S.inet_aton(net[:slash])) - else: + addr = parse_address(net[:slash]) + if net[slash + 1:].isdigit(): n = int(net[slash + 1:], 10) mask = (1 << 32) - (1 << 32 - n) + else: + mask = parse_address(net[slash + 1:]) pats.append((tag, peer, addr & mask, mask)) ## Annoyingly, RawConfigParser doesn't preserve the order of options. @@ -197,7 +200,7 @@ CF = None def straddr(a): return a is None and '#' or S.inet_ntoa(pack('>L', a)) def strmask(m): for i in xrange(33): - if m == 0xffffffff ^ ((1 << (32 - i)) - 1): return i + if m == 0xffffffff ^ ((1 << (32 - i)) - 1): return str(i) return straddr(m) def cmd_showconfig(): @@ -211,7 +214,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)', @@ -229,7 +232,7 @@ def localaddr(peer): try: sk.connect((peer, 1)) addr, _ = sk.getsockname() - addr, = unpack('>L', S.inet_aton(addr)) + addr = parse_address(addr) return addr except S.error: return None @@ -237,11 +240,42 @@ def localaddr(peer): sk.close() _kick = T.Queue() +_delay = None + +def cancel_delay(): + global _delay + if _delay is not None: + if T._debug: print '# cancel delayed kick' + G.source_remove(_delay) + _delay = None + +def netupdown(upness, reason): + """ + Add or kill peers according to whether the network is up or down. + + UPNESS is true if the network is up, or false if it's down. + """ + + _kick.put((upness, reason)) + +def delay_netupdown(upness, reason): + global _delay + cancel_delay() + def _func(): + global _delay + if T._debug: print '# delayed %s: %s' % (upness, reason) + _delay = None + netupdown(upness, reason) + return False + if T._debug: print '# delaying %s: %s' % (upness, reason) + _delay = G.timeout_add(2000, _func) + def kickpeers(): while True: upness, reason = _kick.get() if T._debug: print '# kickpeers %s: %s' % (upness, reason) select = [] + cancel_delay() ## Make sure the configuration file is up-to-date. Don't worry if we ## can't do anything useful. @@ -332,15 +366,6 @@ def kickpeers(): SM.notify('conntrack', upness and 'up' or 'down', *select + reason) for c in changes: c() -def netupdown(upness, reason): - """ - Add or kill peers according to whether the network is up or down. - - UPNESS is true if the network is up, or false if it's down. - """ - - _kick.put((upness, reason)) - ###-------------------------------------------------------------------------- ### NetworkManager monitor. @@ -391,13 +416,13 @@ class NetworkManagerMonitor (object): def _nm_state(me, state): if state in NM_CONNSTATES: - netupdown(True, ['nm', 'connected']) + delay_netupdown(True, ['nm', 'connected']) else: - netupdown(False, ['nm', 'disconnected']) + delay_netupdown(False, ['nm', 'disconnected']) def _nm_connchange(me, props): - if props.get('Default', False): - netupdown(True, ['nm', 'default-connection-change']) + if props.get('Default', False) or props.get('Default6', False): + delay_netupdown(True, ['nm', 'default-connection-change']) ##-------------------------------------------------------------------------- ### Connman monitor. @@ -429,7 +454,7 @@ class ConnManMonitor (object): def _cm_state(me, prop, value): if prop != 'State': return - netupdown(value == 'online', ['connman', value]) + delay_netupdown(value == 'online', ['connman', value]) ###-------------------------------------------------------------------------- ### Maemo monitor. @@ -470,10 +495,10 @@ class MaemoICdMonitor (object): def _icd_state(me, iap, ty, state, hunoz): if state == 'CONNECTED': me._iap = iap - netupdown(True, ['icd', 'connected', iap]) + delay_netupdown(True, ['icd', 'connected', iap]) elif state == 'IDLE' and iap == me._iap: me._iap = None - netupdown(False, ['icd', 'idle']) + delay_netupdown(False, ['icd', 'idle']) ###-------------------------------------------------------------------------- ### D-Bus connection tracking. @@ -585,8 +610,9 @@ def init(): DBM.addmon(NetworkManagerMonitor()) DBM.addmon(ConnManMonitor()) DBM.addmon(MaemoICdMonitor()) - G.timeout_add_seconds(30, lambda: (netupdown(True, ['interval-timer']) - or True)) + G.timeout_add_seconds(30, lambda: (_delay is not None or + netupdown(True, ['interval-timer']) or + True)) def parse_options(): """