manager: force connectivity check when there is a default active connection

The interaction between the manager state and connectivity check code
is tricky. When there is an active connection with a default route and
NMConnectivity reports full connectivity, we set the CONNECTED_GLOBAL
state. However, if the connectivity check hasn't run yet, we stay in
CONNECTED_SITE state. If there are also other connections that are
activating, the state is set to CONNECTING.

This is a problem, because in CONNECTING we never run the connectivity
check and thus we fail to recognize that there is full connectivity
until a periodic check is run.

To solve this, schedule the connectivity check every time there is an
active connection with default route, even if other connection are
still activating, so that the check result can make the state progress
to CONNECTED_GLOBAL.
This commit is contained in:
Beniamino Galvani 2016-10-28 14:59:25 +02:00
parent 948a183d48
commit 084da69a30

View file

@ -767,7 +767,7 @@ checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data)
}
static NMState
find_best_device_state (NMManager *manager)
find_best_device_state (NMManager *manager, gboolean *force_connectivity_check)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
NMState best_state = NM_STATE_DISCONNECTED;
@ -785,6 +785,7 @@ find_best_device_state (NMManager *manager)
return NM_STATE_CONNECTED_GLOBAL;
best_state = NM_STATE_CONNECTED_SITE;
NM_SET_OUT (force_connectivity_check, TRUE);
} else {
if (best_state < NM_STATE_CONNECTING)
best_state = NM_STATE_CONNECTED_LOCAL;
@ -838,6 +839,7 @@ nm_manager_update_state (NMManager *manager)
{
NMManagerPrivate *priv;
NMState new_state = NM_STATE_DISCONNECTED;
gboolean force_connectivity_check = FALSE;
g_return_if_fail (NM_IS_MANAGER (manager));
@ -846,11 +848,11 @@ nm_manager_update_state (NMManager *manager)
if (manager_sleeping (manager))
new_state = NM_STATE_ASLEEP;
else
new_state = find_best_device_state (manager);
new_state = find_best_device_state (manager, &force_connectivity_check);
nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL);
if (new_state == NM_STATE_CONNECTED_SITE) {
if (new_state == NM_STATE_CONNECTED_SITE || force_connectivity_check) {
nm_connectivity_check_async (priv->connectivity,
checked_connectivity,
g_object_ref (manager));