diff options
Diffstat (limited to 'src/nm-connectivity.c')
| -rw-r--r-- | src/nm-connectivity.c | 69 |
1 files changed, 57 insertions, 12 deletions
diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c index 8a324a5c..85bd70ae 100644 --- a/src/nm-connectivity.c +++ b/src/nm-connectivity.c @@ -44,7 +44,7 @@ typedef struct { #if WITH_CONCHECK SoupSession *soup_session; - gboolean running; + guint pending_checks; guint check_id; #endif @@ -69,12 +69,33 @@ nm_connectivity_get_state (NMConnectivity *connectivity) return NM_CONNECTIVITY_GET_PRIVATE (connectivity)->state; } +static const char * +state_name (NMConnectivityState state) +{ + switch (state) { + case NM_CONNECTIVITY_UNKNOWN: + return "UNKNOWN"; + case NM_CONNECTIVITY_NONE: + return "NONE"; + case NM_CONNECTIVITY_LIMITED: + return "LIMITED"; + case NM_CONNECTIVITY_PORTAL: + return "PORTAL"; + case NM_CONNECTIVITY_FULL: + return "FULL"; + default: + return "???"; + } +} + static void update_state (NMConnectivity *self, NMConnectivityState state) { NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); if (priv->state != state) { + nm_log_dbg (LOGD_CONCHECK, "Connectivity state changed from %s to %s", + state_name (priv->state), state_name (state)); priv->state = state; g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_STATE); } @@ -93,6 +114,7 @@ nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_ self = NM_CONNECTIVITY (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); g_object_unref (self); priv = NM_CONNECTIVITY_GET_PRIVATE (self); + priv->pending_checks--; if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) { nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' failed with '%s'.", @@ -124,10 +146,11 @@ nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_ } done: + update_state (self, new_state); + g_simple_async_result_set_op_res_gssize (simple, new_state); g_simple_async_result_complete (simple); - - update_state (self, new_state); + g_object_unref (simple); } static void @@ -136,11 +159,9 @@ run_check_complete (GObject *object, gpointer user_data) { NMConnectivity *self = NM_CONNECTIVITY (object); - NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); GError *error = NULL; nm_connectivity_check_finish (self, result, &error); - priv->running = FALSE; if (error) { nm_log_err (LOGD_CONCHECK, "Connectivity check failed: %s", error->message); g_error_free (error); @@ -151,14 +172,23 @@ static gboolean run_check (gpointer user_data) { NMConnectivity *self = NM_CONNECTIVITY (user_data); - NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); nm_connectivity_check_async (self, run_check_complete, NULL); - priv->running = TRUE; - nm_log_dbg (LOGD_CONCHECK, "Connectivity check with uri '%s' started.", priv->uri); - return TRUE; } + +static gboolean +idle_start_periodic_checks (gpointer user_data) +{ + NMConnectivity *self = user_data; + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + priv->check_id = g_timeout_add_seconds (priv->interval, run_check, self); + if (!priv->pending_checks) + run_check (self); + + return FALSE; +} #endif void @@ -167,12 +197,14 @@ nm_connectivity_set_online (NMConnectivity *self, { #if WITH_CONCHECK NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); +#endif + nm_log_dbg (LOGD_CONCHECK, "nm_connectivity_set_online(%s)", online ? "TRUE" : "FALSE"); + +#if WITH_CONCHECK if (online && priv->uri && priv->interval) { if (!priv->check_id) - priv->check_id = g_timeout_add_seconds (priv->interval, run_check, self); - if (!priv->running) - run_check (self); + priv->check_id = g_timeout_add (0, idle_start_periodic_checks, self); return; } else if (priv->check_id) { @@ -201,6 +233,13 @@ nm_connectivity_check_async (NMConnectivity *self, g_return_if_fail (NM_IS_CONNECTIVITY (self)); priv = NM_CONNECTIVITY_GET_PRIVATE (self); +#if WITH_CONCHECK + if (callback == run_check_complete) + nm_log_dbg (LOGD_CONCHECK, "Periodic connectivity check started with uri '%s'.", priv->uri); + else +#endif + nm_log_dbg (LOGD_CONCHECK, "Connectivity check started with uri '%s'.", priv->uri); + simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data, nm_connectivity_check_async); @@ -208,10 +247,13 @@ nm_connectivity_check_async (NMConnectivity *self, if (priv->uri && priv->interval) { msg = soup_message_new ("GET", priv->uri); soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); + /* Disable HTTP/1.1 keepalive; the connection should not persist */ + soup_message_headers_append (msg->request_headers, "Connection", "close"); soup_session_queue_message (priv->soup_session, msg, nm_connectivity_check_cb, simple); + priv->pending_checks++; return; } @@ -219,6 +261,7 @@ nm_connectivity_check_async (NMConnectivity *self, g_simple_async_result_set_op_res_gssize (simple, priv->state); g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); } NMConnectivityState @@ -291,6 +334,8 @@ set_property (GObject *object, guint property_id, g_free (priv->uri); priv->uri = NULL; } + if (uri) + soup_uri_free (uri); } #endif break; |