diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c index ce5558b96f..67fd3a0d3b 100644 --- a/src/nm-connectivity.c +++ b/src/nm-connectivity.c @@ -71,6 +71,22 @@ nm_connectivity_get_connected (NMConnectivity *connectivity) return NM_CONNECTIVITY_GET_PRIVATE (connectivity)->connected; } +static void +update_connected (NMConnectivity *self, gboolean connected) +{ + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + gboolean old_connected = priv->connected; + + if (priv->uri == NULL || priv->interval == 0) { + /* Default to connected if no checks are to be run */ + priv->connected = TRUE; + } else + priv->connected = connected; + + if (priv->connected != old_connected) + g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_CONNECTED); +} + static void nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { @@ -103,62 +119,74 @@ nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_ g_free (uri_string); /* update connectivity and emit signal */ - if (priv->connected != connected_new) { - priv->connected = connected_new; - g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_CONNECTED); - } + update_connected (self, connected_new); priv->running = FALSE; g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_RUNNING); } - -void -nm_connectivity_check (NMConnectivity *self) +static gboolean +run_check (gpointer user_data) { + NMConnectivity *self = NM_CONNECTIVITY (user_data); NMConnectivityPrivate *priv; SoupURI *soup_uri; SoupMessage *msg; - g_return_if_fail (NM_IS_CONNECTIVITY (self)); + g_return_val_if_fail (NM_IS_CONNECTIVITY (self), FALSE); priv = NM_CONNECTIVITY_GET_PRIVATE (self); - if (priv->running) - return; + /* check given url async */ + soup_uri = soup_uri_new (priv->uri); + if (soup_uri && SOUP_URI_VALID_FOR_HTTP (soup_uri)) { + msg = soup_message_new_from_uri ("GET", soup_uri); + soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); + soup_session_queue_message (priv->soup_session, + msg, + nm_connectivity_check_cb, + self); - if (priv->uri) { - /* check given url async */ - soup_uri = soup_uri_new (priv->uri); - if (soup_uri && SOUP_URI_VALID_FOR_HTTP (soup_uri)) { - msg = soup_message_new_from_uri ("GET", soup_uri); - soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); - soup_session_queue_message (priv->soup_session, - msg, - nm_connectivity_check_cb, - self); + priv->running = TRUE; + g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_RUNNING); + nm_log_dbg (LOGD_CORE, "Connectivity check with uri '%s' started.", priv->uri); + } else + nm_log_err (LOGD_CORE, "Invalid uri '%s' for connectivity check.", priv->uri); - priv->running = TRUE; - g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_RUNNING); - nm_log_dbg (LOGD_CORE, "Connectivity check with uri '%s' started.", priv->uri); - } else - nm_log_err (LOGD_CORE, "Invalid uri '%s' for connectivity check.", priv->uri); + if (soup_uri) + soup_uri_free (soup_uri); - if (soup_uri) - soup_uri_free (soup_uri); - } else { - /* No URI given - default is connected */ - if (!priv->connected) { - priv->connected = TRUE; - g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_CONNECTED); - } - } + return TRUE; /* keep firing */ } -static gboolean -do_check (gpointer user_data) +void +nm_connectivity_start_check (NMConnectivity *self) { - nm_connectivity_check (NM_CONNECTIVITY (user_data)); - return TRUE; /* keep checking */ + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + if (!priv->uri || !priv->interval) { + nm_connectivity_stop_check (self); + return; + } + + if (priv->check_id == 0) + priv->check_id = g_timeout_add_seconds (priv->interval, run_check, self); + + /* Start an immediate check */ + if (priv->running == FALSE) + run_check (self); +} + +void +nm_connectivity_stop_check (NMConnectivity *self) +{ + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + if (priv->check_id) { + g_source_remove (priv->check_id); + priv->check_id = 0; + } + + update_connected (self, FALSE); } NMConnectivity * @@ -167,7 +195,6 @@ nm_connectivity_new (const gchar *check_uri, const gchar *check_response) { NMConnectivity *self; - NMConnectivityPrivate *priv; self = g_object_new (NM_TYPE_CONNECTIVITY, NM_CONNECTIVITY_URI, check_uri, @@ -175,11 +202,7 @@ nm_connectivity_new (const gchar *check_uri, NM_CONNECTIVITY_RESPONSE, check_response ? check_response : DEFAULT_RESPONSE, NULL); g_return_val_if_fail (self != NULL, NULL); - - /* Kick off a check if required */ - priv = NM_CONNECTIVITY_GET_PRIVATE (self); - if (priv->uri && priv->interval) - priv->check_id = g_timeout_add_seconds (priv->interval, do_check, self); + update_connected (self, FALSE); return self; } diff --git a/src/nm-connectivity.h b/src/nm-connectivity.h index 91854e1885..cecc66766d 100644 --- a/src/nm-connectivity.h +++ b/src/nm-connectivity.h @@ -57,7 +57,9 @@ NMConnectivity *nm_connectivity_new (const gchar *check_uri, guint check_interval, const gchar *check_response); -void nm_connectivity_check (NMConnectivity *connectivity); +void nm_connectivity_start_check (NMConnectivity *connectivity); + +void nm_connectivity_stop_check (NMConnectivity *connectivity); gboolean nm_connectivity_get_connected (NMConnectivity *connectivity); diff --git a/src/nm-manager.c b/src/nm-manager.c index 2c437e2f45..3e08cf30a6 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -470,7 +470,8 @@ manager_device_state_changed (NMDevice *device, NMDeviceStateReason reason, gpointer user_data) { - NMManager *manager = NM_MANAGER (user_data); + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); switch (new_state) { case NM_DEVICE_STATE_UNMANAGED: @@ -478,18 +479,26 @@ manager_device_state_changed (NMDevice *device, case NM_DEVICE_STATE_DISCONNECTED: case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_FAILED: - g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); + g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS); break; default: break; } - nm_manager_update_state (manager); + nm_manager_update_state (self); #if WITH_CONCHECK - /* trigger a connectivity check */ - if (new_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_ACTIVATED) - nm_connectivity_check (NM_MANAGER_GET_PRIVATE (manager)->connectivity); + if (priv->state >= NM_STATE_CONNECTED_LOCAL) { + if (old_state == NM_DEVICE_STATE_ACTIVATED || new_state == NM_DEVICE_STATE_ACTIVATED) { + /* Still connected, but a device activated or deactivated; make sure + * we still have connectivity on the other activated devices. + */ + nm_connectivity_start_check (priv->connectivity); + } + } else { + /* Cannot be connected if no devices are activated */ + nm_connectivity_stop_check (priv->connectivity); + } #endif }