NetWatcher: detect when networkmanager has lost network connection
This is a better approach to finding both when NM has lost a network connection, and when a new network connection is made by NM. Tested with network-manager 0.9.8.8. This commit was sponsored by Cedric Staub.
This commit is contained in:
parent
a33b30d0c4
commit
bb44df206d
2 changed files with 37 additions and 25 deletions
|
@ -22,7 +22,6 @@ import Utility.NotificationBroadcaster
|
||||||
import Utility.DBus
|
import Utility.DBus
|
||||||
import DBus.Client
|
import DBus.Client
|
||||||
import DBus
|
import DBus
|
||||||
import Data.Word (Word32)
|
|
||||||
import Assistant.NetMessager
|
import Assistant.NetMessager
|
||||||
#else
|
#else
|
||||||
#ifdef linux_HOST_OS
|
#ifdef linux_HOST_OS
|
||||||
|
@ -63,15 +62,19 @@ dbusThread = do
|
||||||
where
|
where
|
||||||
go client = ifM (checkNetMonitor client)
|
go client = ifM (checkNetMonitor client)
|
||||||
( do
|
( do
|
||||||
listenNMConnections client <~> handleconn
|
callback <- asIO1 connchange
|
||||||
listenWicdConnections client <~> handleconn
|
liftIO $ do
|
||||||
|
listenNMConnections client callback
|
||||||
|
listenWicdConnections client callback
|
||||||
, do
|
, do
|
||||||
liftAnnex $
|
liftAnnex $
|
||||||
warning "No known network monitor available through dbus; falling back to polling"
|
warning "No known network monitor available through dbus; falling back to polling"
|
||||||
)
|
)
|
||||||
handleconn = do
|
connchange False = do
|
||||||
debug ["detected network connection"]
|
debug ["detected network disconnection"]
|
||||||
sendRemoteControl LOSTNET
|
sendRemoteControl LOSTNET
|
||||||
|
connchange True = do
|
||||||
|
debug ["detected network connection"]
|
||||||
notifyNetMessagerRestart
|
notifyNetMessagerRestart
|
||||||
handleConnection
|
handleConnection
|
||||||
sendRemoteControl RESUME
|
sendRemoteControl RESUME
|
||||||
|
@ -99,31 +102,40 @@ checkNetMonitor client = do
|
||||||
networkmanager = "org.freedesktop.NetworkManager"
|
networkmanager = "org.freedesktop.NetworkManager"
|
||||||
wicd = "org.wicd.daemon"
|
wicd = "org.wicd.daemon"
|
||||||
|
|
||||||
{- Listens for new NetworkManager connections. -}
|
{- Listens for NetworkManager connections and diconnections.
|
||||||
listenNMConnections :: Client -> IO () -> IO ()
|
-
|
||||||
listenNMConnections client callback =
|
- Connection example (once fully connected):
|
||||||
listen client matcher $ \event ->
|
- [Variant {"ActivatingConnection": Variant (ObjectPath "/"), "PrimaryConnection": Variant (ObjectPath "/org/freedesktop/NetworkManager/ActiveConnection/34"), "State": Variant 70}]
|
||||||
when (Just True == anyM activeconnection (signalBody event)) $
|
-
|
||||||
callback
|
- Disconnection example:
|
||||||
|
- [Variant {"ActiveConnections": Variant []}]
|
||||||
|
-}
|
||||||
|
listenNMConnections :: Client -> (Bool -> IO ()) -> IO ()
|
||||||
|
listenNMConnections client setconnected =
|
||||||
|
listen client matcher $ \event -> mapM_ handle
|
||||||
|
(map dictionaryItems $ mapMaybe fromVariant $ signalBody event)
|
||||||
where
|
where
|
||||||
matcher = matchAny
|
matcher = matchAny
|
||||||
{ matchInterface = Just "org.freedesktop.NetworkManager.Connection.Active"
|
{ matchInterface = Just "org.freedesktop.NetworkManager"
|
||||||
, matchMember = Just "PropertiesChanged"
|
, matchMember = Just "PropertiesChanged"
|
||||||
}
|
}
|
||||||
nm_connection_activated = toVariant (2 :: Word32)
|
nm_active_connections_key = toVariant ("ActiveConnections" :: String)
|
||||||
nm_state_key = toVariant ("State" :: String)
|
nm_activatingconnection_key = toVariant ("ActivatingConnection" :: String)
|
||||||
activeconnection v = do
|
noconnections = Just $ toVariant $ toVariant ([] :: [ObjectPath])
|
||||||
m <- fromVariant v
|
rootconnection = Just $ toVariant $ toVariant $ objectPath_ "/"
|
||||||
vstate <- lookup nm_state_key $ dictionaryItems m
|
handle m
|
||||||
state <- fromVariant vstate
|
| lookup nm_active_connections_key m == noconnections =
|
||||||
return $ state == nm_connection_activated
|
setconnected False
|
||||||
|
| lookup nm_activatingconnection_key m == rootconnection =
|
||||||
|
setconnected True
|
||||||
|
| otherwise = noop
|
||||||
|
|
||||||
{- Listens for new Wicd connections. -}
|
{- Listens for Wicd connections (not currently disconnections). -}
|
||||||
listenWicdConnections :: Client -> IO () -> IO ()
|
listenWicdConnections :: Client -> (Bool -> IO ()) -> IO ()
|
||||||
listenWicdConnections client callback =
|
listenWicdConnections client callback =
|
||||||
listen client matcher $ \event ->
|
listen client matcher $ \event ->
|
||||||
when (any (== wicd_success) (signalBody event)) $
|
when (any (== wicd_success) (signalBody event)) $
|
||||||
callback
|
callback False >> callback True
|
||||||
where
|
where
|
||||||
matcher = matchAny
|
matcher = matchAny
|
||||||
{ matchInterface = Just "org.wicd.daemon"
|
{ matchInterface = Just "org.wicd.daemon"
|
||||||
|
|
|
@ -164,9 +164,9 @@ No pushing is done for CHANGED, since git handles ssh natively.
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
* The NetWatcher does not detect network loss, only network gain,
|
* For wicd, the NetWatcher does not detect network loss, only network gain.
|
||||||
so PAUSE is only sent when a new network is detected, followed
|
So PAUSE is only sent when a new network is detected, followed
|
||||||
immediately by RESUME.
|
immediately by RESUME. This was already fixed for networkmanager.
|
||||||
* Remote system might not be available. Find a smart way to detect it,
|
* Remote system might not be available. Find a smart way to detect it,
|
||||||
ideally w/o generating network traffic. One way might be to check
|
ideally w/o generating network traffic. One way might be to check
|
||||||
if the ssh connection caching control socket exists, for example.
|
if the ssh connection caching control socket exists, for example.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue