static void run_with_enumerator (gboolean synchronous, GSocketAddressEnumerator *enumerator) { GError *error = NULL; if (synchronous) { GSocketAddress *sockaddr; while ((sockaddr = g_socket_address_enumerator_next (enumerator, cancellable, &error))) { print_proxy_address (sockaddr); g_object_unref (sockaddr); } if (error) print_and_free_error (error); } else { GMainLoop *loop = g_main_loop_new (NULL, FALSE); g_socket_address_enumerator_next_async (enumerator, cancellable, _proxy_enumerate_cb, loop); g_main_loop_run (loop); g_main_loop_unref (loop); } }
static void proxy_lookup_cb (GObject *object, GAsyncResult *result, gpointer user_data) { GTask *task = user_data; GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); g_clear_error (&priv->last_error); priv->proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (object), result, &priv->last_error); priv->next_proxy = priv->proxies; if (priv->last_error) { complete_async (task); return; } else { next_enumerator (priv); if (priv->addr_enum) { g_socket_address_enumerator_next_async (priv->addr_enum, g_task_get_cancellable (task), address_enumerate_cb, task); return; } } complete_async (task); }
static void _proxy_enumerate_cb (GObject *object, GAsyncResult *result, gpointer user_data) { GError *error = NULL; GMainLoop *loop = user_data; GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object); GSocketAddress *sockaddr; sockaddr = g_socket_address_enumerator_next_finish (enumerator, result, &error); if (sockaddr) { print_proxy_address (sockaddr); g_socket_address_enumerator_next_async (enumerator, cancellable, _proxy_enumerate_cb, loop); g_object_unref (sockaddr); } else { if (error) print_and_free_error (error); g_main_loop_quit (loop); } }
static void next_proxy (GTask *task) { GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); if (*priv->next_proxy) { g_object_unref (priv->addr_enum); priv->addr_enum = NULL; if (priv->dest_ips) { g_resolver_free_addresses (priv->dest_ips); priv->dest_ips = NULL; } next_enumerator (priv); if (priv->addr_enum) { g_socket_address_enumerator_next_async (priv->addr_enum, g_task_get_cancellable (task), address_enumerate_cb, task); return; } } complete_async (task); }
static void g_proxy_address_enumerator_next_async (GSocketAddressEnumerator *enumerator, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator); GTask *task; task = g_task_new (enumerator, cancellable, callback, user_data); g_task_set_task_data (task, priv, NULL); if (priv->proxies == NULL) { GProxyResolver *resolver = g_proxy_resolver_get_default (); g_proxy_resolver_lookup_async (resolver, priv->dest_uri, cancellable, proxy_lookup_cb, task); return; } if (priv->addr_enum) { if (priv->proxy_address) { return_result (task); return; } else { g_socket_address_enumerator_next_async (priv->addr_enum, cancellable, address_enumerate_cb, task); return; } } complete_async (task); }
/** * cockpit_stream_connect: * @name: name for pipe, for debugging * @address: socket address to connect to * * Create a new pipe connected as a client to the given socket * address, which can be a unix or inet address. Will connect * in stream mode. * * If the connection fails, a pipe is still returned. It will * close once the main loop is run with an appropriate problem. * * Returns: (transfer full): newly allocated CockpitStream. */ CockpitStream * cockpit_stream_connect (const gchar *name, GSocketConnectable *connectable, CockpitStreamOptions *options) { CockpitStream *stream; g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL); stream = g_object_new (COCKPIT_TYPE_STREAM, "io-stream", NULL, "name", name, NULL); if (options) stream->priv->options = cockpit_stream_options_ref (options); stream->priv->connecting = g_socket_connectable_enumerate (connectable); g_socket_address_enumerator_next_async (stream->priv->connecting, NULL, on_address_next, g_object_ref (stream)); return stream; }
static void do_async_connectable (GSocketAddressEnumerator *enumerator) { g_socket_address_enumerator_next_async (enumerator, cancellable, got_next_async, NULL); }
static void on_socket_connect (GObject *object, GAsyncResult *result, gpointer user_data) { CockpitStream *self = user_data; GError *error = NULL; g_socket_connection_connect_finish (G_SOCKET_CONNECTION (object), result, &error); if (!error && !self->priv->closed) { g_debug ("%s: connected", self->priv->name); if (self->priv->options && self->priv->options->tls_client) { self->priv->io = g_tls_client_connection_new (G_IO_STREAM (object), NULL, &error); if (self->priv->io) { g_debug ("%s: tls handshake", self->priv->name); g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (self->priv->io), self->priv->options->tls_client_flags); if (self->priv->options->tls_cert) { g_tls_connection_set_certificate (G_TLS_CONNECTION (self->priv->io), self->priv->options->tls_cert); } if (self->priv->options->tls_database) { g_tls_connection_set_database (G_TLS_CONNECTION (self->priv->io), self->priv->options->tls_database); } /* We track data end the same way we do for HTTP */ g_tls_connection_set_require_close_notify (G_TLS_CONNECTION (self->priv->io), FALSE); } } else { self->priv->io = g_object_ref (object); } } if (error) { g_debug ("%s: couldn't connect: %s", self->priv->name, error->message); g_clear_error (&self->priv->connect_error); self->priv->connect_error = error; g_socket_address_enumerator_next_async (self->priv->connecting, NULL, on_address_next, g_object_ref (self)); } else { initialize_io (self); } g_object_unref (object); g_object_unref (self); }