+can_reach_async_got_address (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object);
+ GTask *task = user_data;
+ GNetworkMonitorBase *base = g_task_get_source_object (task);
+ GSocketAddress *addr;
+ GError *error = NULL;
+
+ addr = g_socket_address_enumerator_next_finish (enumerator, result, &error);
+ if (!addr)
+ {
+ if (error)
+ {
+ /* Either the user cancelled, or DNS resolution failed */
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+ else
+ {
+ /* Resolved all addresses, none matched */
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE,
+ _("Host unreachable"));
+ g_object_unref (task);
+ return;
+ }
+ }
+
+ if (g_network_monitor_base_can_reach_sockaddr (base, addr))
+ {
+ g_object_unref (addr);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
+ g_object_unref (addr);
+
+ g_socket_address_enumerator_next_async (enumerator,
+ g_task_get_cancellable (task),
+ can_reach_async_got_address, task);
+}
+
+static void
+g_network_monitor_base_can_reach_async (GNetworkMonitor *monitor,
+ GSocketConnectable *connectable,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ GSocketAddressEnumerator *enumerator;
+
+ task = g_task_new (monitor, cancellable, callback, user_data);
+
+ if (G_NETWORK_MONITOR_BASE (monitor)->priv->networks->len == 0)
+ {
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE,
+ _("Network unreachable"));
+ g_object_unref (task);
+ return;
+ }
+
+ enumerator = g_socket_connectable_proxy_enumerate (connectable);
+ g_socket_address_enumerator_next_async (enumerator, cancellable,
+ can_reach_async_got_address, task);
+ g_object_unref (enumerator);
+}
+
+static gboolean
+g_network_monitor_base_can_reach_finish (GNetworkMonitor *monitor,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void