mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-05 12:20:36 +01:00
core: fix up connectivity state checks
We want to start the connectivity checks when any device gets activated, and stop them when all devices get deactivated. We also want to make sure it's running if a device gets deactivated but other devices are still active. If multiple devices are activated and if the default device gets deactivated, the other device may become the default device and we'll need a connectivity check for that device since we can't do per-device checks yet. Also, if connectivity checking is enabled at compile-time but not enabled at runtime, the connectivity bits should always report "connected" to preserve previous behavior, and this code makes it clearer how that is handled.
This commit is contained in:
parent
d47072a1a1
commit
5937861ca7
3 changed files with 85 additions and 51 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue