コード例 #1
0
ファイル: vdagent.c プロジェクト: elmarco/vdagent-gtk
/* TODO: could use dbus, but for portability maybe not..... */
static void
do_connect(SpiceVDAgent *agent)
{
    GError *error = NULL;
    GSocketAddressEnumerator *enumerator;
    GSocketAddress *address;

#ifdef G_OS_UNIX
    agent->socket = g_socket_new(G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error);
    agent->connectable = G_SOCKET_CONNECTABLE(g_unix_socket_address_new(vdagentd_socket));
#endif

    enumerator = g_socket_connectable_enumerate (agent->connectable);
    while (TRUE) {
        address = g_socket_address_enumerator_next (enumerator, agent->cancellable, NULL);
        if (!address) {
            g_error("can't connect to socket");
            exit(1);
        }

        if (g_socket_connect(agent->socket, address, agent->cancellable, &error))
            break;

        g_debug("Connection failed, trying next");
        g_clear_error (&error);
        g_object_unref (address);
    }
    g_object_unref(enumerator);

    agent->connection =
        G_IO_STREAM(g_socket_connection_factory_create_connection(agent->socket));
    g_debug("Connected to %s %p", vdagentd_socket, agent->connection);

    send_xorg_config(agent);
}
コード例 #2
0
ファイル: gvfsftpconnection.c プロジェクト: gicmo/gvfs
/**
 * g_vfs_ftp_connection_accept_data_connection:
 * @conn: a listening connection
 * @cancellable: cancellable to interrupt wait
 * @error: %NULL or location to take a potential error
 *
 * Opens a data connection for @conn by accepting an incoming connection on the
 * address it is listening on via g_vfs_ftp_connection_listen_data_connection(),
 * which must have been called prior to this function.
 * If this function succeeds, a data connection will have been opened, and calls
 * to g_vfs_ftp_connection_get_data_stream() will work.
 *
 * Returns: %TRUE if a connection was successfully acquired
 **/
gboolean
g_vfs_ftp_connection_accept_data_connection (GVfsFtpConnection *conn,
                                             GCancellable *     cancellable,
                                             GError **          error)
{
  GSocket *accepted;
  GCancellable *timer;
  gulong cancel_cb_id;
  GIOCondition condition;

  g_return_val_if_fail (conn != NULL, FALSE);
  g_return_val_if_fail (conn->data == NULL, FALSE);
  g_return_val_if_fail (G_IS_SOCKET (conn->listen_socket), FALSE);

  timer = g_cancellable_new ();
  cancel_cb_id = g_cancellable_connect (cancellable, 
                                        G_CALLBACK (cancel_timer_cb),
                                        timer,
                                        NULL);
  g_object_ref (timer);
  g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
                              G_VFS_FTP_TIMEOUT_IN_SECONDS,
                              cancel_cancellable,
                              timer,
                              g_object_unref);

  condition = g_socket_condition_wait (conn->listen_socket, G_IO_IN, timer, error);

  g_cancellable_disconnect (cancellable, cancel_cb_id);
  g_object_unref (timer);

  if ((condition & G_IO_IN) == 0)
    {
      if (g_cancellable_is_cancelled (timer) &&
          !g_cancellable_is_cancelled (cancellable))
        {
          g_clear_error (error);
          g_set_error_literal (error, 
                               G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
                               _("Failed to create active FTP connection. "
                                 "Maybe your router does not support this?"));
        }
      else if (error && *error == NULL)
        {
          g_set_error_literal (error, 
                               G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
                               _("Failed to create active FTP connection."));
        }
      return FALSE;
    }

  accepted = g_socket_accept (conn->listen_socket, cancellable, error);
  if (accepted == NULL)
    return FALSE;

  conn->data = G_IO_STREAM (g_socket_connection_factory_create_connection (accepted));
  g_object_unref (accepted);
  enable_nodelay (G_SOCKET_CONNECTION (conn->data));
  return TRUE;
}
コード例 #3
0
ファイル: main.c プロジェクト: PapaMarky/rpm-ostree
static gboolean
connect_to_peer (int fd)
{
  g_autoptr(GSocketConnection) stream = NULL;
  g_autoptr(GSocket) socket = NULL;
  GError *error = NULL;
  g_autofree gchar *guid = NULL;
  gboolean ret = FALSE;

  socket = g_socket_new_from_fd (fd, &error);
  if (error != NULL)
    {
      g_warning ("Couldn't create socket: %s", error->message);
      goto out;
    }

  stream = g_socket_connection_factory_create_connection (socket);
  if (!stream)
    {
      g_warning ("Couldn't create socket stream");
      goto out;
    }

  guid = g_dbus_generate_guid ();
  g_dbus_connection_new (G_IO_STREAM (stream), guid,
                         G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER |
                         G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
                         NULL, NULL, on_peer_acquired, NULL);
  ret = TRUE;

out:
  g_clear_error (&error);
  return ret;
}
コード例 #4
0
ファイル: cockpitstream.c プロジェクト: firebitsbr/cockpit
static void
on_address_next (GObject *object,
                 GAsyncResult *result,
                 gpointer user_data)
{
  CockpitStream *self = user_data;
  GSocketConnection *connection;
  GSocketAddress *address;
  GError *error = NULL;
  GSocket *sock;

  address = g_socket_address_enumerator_next_finish (G_SOCKET_ADDRESS_ENUMERATOR (object),
                                                     result, &error);

  if (error)
    {
      set_problem_from_error (self, "couldn't resolve", error);
      g_error_free (error);
      close_immediately (self, NULL);
    }
  else if (address)
    {
      sock = g_socket_new (g_socket_address_get_family (address), G_SOCKET_TYPE_STREAM, 0, &error);
      if (sock)
        {
          g_socket_set_blocking (sock, FALSE);

          connection = g_socket_connection_factory_create_connection (sock);
          g_object_unref (sock);

          g_socket_connection_connect_async (connection, address, NULL,
                                             on_socket_connect, g_object_ref (self));
        }

      if (error)
        {
          g_debug ("%s: couldn't open socket: %s", self->priv->name, error->message);
          g_clear_error (&self->priv->connect_error);
          self->priv->connect_error = error;
        }
      g_object_unref (address);
    }
  else
    {
      if (self->priv->connect_error)
        {
          set_problem_from_error (self, "couldn't connect", self->priv->connect_error);
          close_immediately (self, NULL);
        }
      else
        {
          g_message ("%s: no addresses found", self->priv->name);
          close_immediately (self, "not-found");
        }
    }

  g_object_unref (self);
}
コード例 #5
0
ファイル: soup-socket.c プロジェクト: DrGore/libsoup
static void
finish_socket_setup (SoupSocketPrivate *priv)
{
	if (!priv->gsock)
		return;

	if (!priv->conn)
		priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
	if (!priv->iostream)
		priv->iostream = soup_io_stream_new (priv->conn, FALSE);
	if (!priv->istream)
		priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
	if (!priv->ostream)
		priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->iostream));

	g_socket_set_timeout (priv->gsock, priv->timeout);
}
コード例 #6
0
ファイル: gsocketlistener.c プロジェクト: QuentinFiard/glib
/**
 * g_socket_listener_accept_finish:
 * @listener: a #GSocketListener
 * @result: a #GAsyncResult.
 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
 * @error: a #GError location to store the error occurring, or %NULL to
 * ignore.
 *
 * Finishes an async accept operation. See g_socket_listener_accept_async()
 *
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
 *
 * Since: 2.22
 */
GSocketConnection *
g_socket_listener_accept_finish (GSocketListener  *listener,
				 GAsyncResult     *result,
				 GObject         **source_object,
				 GError          **error)
{
  GSocket *socket;
  GSocketConnection *connection;

  socket = g_socket_listener_accept_socket_finish (listener,
						   result,
						   source_object,
						   error);
  if (socket == NULL)
    return NULL;

  connection = g_socket_connection_factory_create_connection (socket);
  g_object_unref (socket);
  return connection;
}
コード例 #7
0
ファイル: gsocketlistener.c プロジェクト: QuentinFiard/glib
/**
 * g_socket_listener_accept:
 * @listener: a #GSocketListener
 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Blocks waiting for a client to connect to any of the sockets added
 * to the listener. Returns a #GSocketConnection for the socket that was
 * accepted.
 *
 * If @source_object is not %NULL it will be filled out with the source
 * object specified when the corresponding socket or address was added
 * to the listener.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by
 * triggering the cancellable object from another thread. If the operation
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 *
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
 *
 * Since: 2.22
 */
GSocketConnection *
g_socket_listener_accept (GSocketListener  *listener,
			  GObject         **source_object,
			  GCancellable     *cancellable,
			  GError          **error)
{
  GSocketConnection *connection;
  GSocket *socket;

  socket = g_socket_listener_accept_socket (listener,
					    source_object,
					    cancellable,
					    error);
  if (socket == NULL)
    return NULL;

  connection = g_socket_connection_factory_create_connection (socket);
  g_object_unref (socket);

  return connection;
}
コード例 #8
0
static void
client_socket_connected (TpStreamTubeChannel *self)
{
  GSocketConnection *conn;

  conn = g_socket_connection_factory_create_connection (
      self->priv->client_socket);
  g_assert (conn);

  DEBUG ("Stream Tube socket connected");

#ifdef HAVE_GIO_UNIX
  if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_CREDENTIALS)
    {
      guchar byte;

      byte = g_value_get_uchar (self->priv->access_control_param);
      tp_unix_connection_send_credentials_with_byte_async (conn, byte, NULL,
          send_credentials_cb, self);
    }
#endif

  if (self->priv->local_conn_id_set)
    {
      new_local_connection_identified (self, conn, self->priv->local_conn_id);

      self->priv->local_conn_id_set = FALSE;
    }
  else
    {
      /* Wait for NewLocalConnection signal */

      /* This assume that we never connect more than once. Or at least that we
       * wait to have identify a connection before making a new connection. */
      g_assert (self->priv->local_conn_waiting_id == NULL);
      self->priv->local_conn_waiting_id = g_object_ref (conn);
    }

  g_object_unref (conn);
}
コード例 #9
0
ファイル: socket-server.c プロジェクト: asimonov-im/glib
int
main (int argc,
      char *argv[])
{
  GSocket *socket, *new_socket, *recv_socket;
  GSocketAddress *src_address;
  GSocketAddress *address;
  GSocketType socket_type;
  GSocketFamily socket_family;
  GError *error = NULL;
  GOptionContext *context;
  GCancellable *cancellable;
  char *display_addr;
  GTlsCertificate *tlscert = NULL;
  GIOStream *connection;
  GInputStream *istream;
  GOutputStream *ostream;

  g_type_init ();

  context = g_option_context_new (" - Test GSocket server stuff");
  g_option_context_add_main_entries (context, cmd_entries, NULL);
  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s\n", argv[0], error->message);
      return 1;
    }

  if (unix_socket && argc != 2)
    {
      g_printerr ("%s: %s\n", argv[0], "Need to specify unix socket name");
      return 1;
    }

  if (cancel_timeout)
    {
      GThread *thread;
      cancellable = g_cancellable_new ();
      thread = g_thread_new ("cancel", cancel_thread, cancellable);
      g_thread_unref (thread);
    }
  else
    {
      cancellable = NULL;
    }

  if (tls_cert_file)
    {
      if (use_udp)
	{
	  g_printerr ("DTLS (TLS over UDP) is not supported");
	  return 1;
	}

      tlscert = g_tls_certificate_new_from_file (tls_cert_file, &error);
      if (!tlscert)
	{
	  g_printerr ("Could not read server certificate '%s': %s\n",
		      tls_cert_file, error->message);
	  return 1;
	}
    }

  loop = g_main_loop_new (NULL, FALSE);

  if (use_udp)
    socket_type = G_SOCKET_TYPE_DATAGRAM;
  else
    socket_type = G_SOCKET_TYPE_STREAM;

  if (unix_socket)
    socket_family = G_SOCKET_FAMILY_UNIX;
  else
    socket_family = G_SOCKET_FAMILY_IPV4;

  socket = g_socket_new (socket_family, socket_type, 0, &error);

  if (socket == NULL)
    {
      g_printerr ("%s: %s\n", argv[0], error->message);
      return 1;
    }

  if (non_blocking)
    g_socket_set_blocking (socket, FALSE);

  if (unix_socket)
    {
      src_address = socket_address_from_string (argv[1]);
      if (src_address == NULL)
	{
	  g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]);
	  return 1;
	}
    }
  else
    {
      src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port);
    }

  if (!g_socket_bind (socket, src_address, !dont_reuse_address, &error))
    {
      g_printerr ("Can't bind socket: %s\n", error->message);
      return 1;
    }
  g_object_unref (src_address);

  if (!use_udp)
    {
      if (!g_socket_listen (socket, &error))
	{
	  g_printerr ("Can't listen on socket: %s\n", error->message);
	  return 1;
	}

      address = g_socket_get_local_address (socket, &error);
      if (!address)
	{
	  g_printerr ("Error getting local address: %s\n",
		      error->message);
	  return 1;
	}
      display_addr = socket_address_to_string (address);
      g_print ("listening on %s...\n", display_addr);
      g_free (display_addr);

      ensure_socket_condition (socket, G_IO_IN, cancellable);
      new_socket = g_socket_accept (socket, cancellable, &error);
      if (!new_socket)
	{
	  g_printerr ("Error accepting socket: %s\n",
		      error->message);
	  return 1;
	}

      if (non_blocking)
	g_socket_set_blocking (new_socket, FALSE);
      if (read_timeout)
	g_socket_set_timeout (new_socket, read_timeout);

      address = g_socket_get_remote_address (new_socket, &error);
      if (!address)
	{
	  g_printerr ("Error getting remote address: %s\n",
		      error->message);
	  return 1;
	}

      display_addr = socket_address_to_string (address);
      g_print ("got a new connection from %s\n", display_addr);
      g_free(display_addr);
      g_object_unref (address);

      recv_socket = new_socket;

      connection = G_IO_STREAM (g_socket_connection_factory_create_connection (recv_socket));
      g_object_unref (new_socket);
    }
  else
    {
      recv_socket = socket;
      connection = NULL;
    }

  if (tlscert)
    {
      GIOStream *tls_conn;

      tls_conn = g_tls_server_connection_new (connection, tlscert, &error);
      if (!tls_conn)
	{
	  g_printerr ("Could not create TLS connection: %s\n",
		      error->message);
	  return 1;
	}

      if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn),
				       cancellable, &error))
	{
	  g_printerr ("Error during TLS handshake: %s\n",
		      error->message);
	  return 1;
       }

      g_object_unref (connection);
      connection = tls_conn;
    }

  if (connection)
    {
      istream = g_io_stream_get_input_stream (connection);
      ostream = g_io_stream_get_output_stream (connection);
    }
  else
    {
      g_assert (use_udp);
      istream = NULL;
      ostream = NULL;
    }

  while (TRUE)
    {
      gchar buffer[4096];
      gssize size;
      gsize to_send;

      if (use_udp)
	{
	  ensure_socket_condition (recv_socket, G_IO_IN, cancellable);
	  size = g_socket_receive_from (recv_socket, &address,
					buffer, sizeof buffer,
					cancellable, &error);
	}
      else
	{
	  ensure_connection_condition (connection, G_IO_IN, cancellable);
	  size = g_input_stream_read (istream,
				      buffer, sizeof buffer,
				      cancellable, &error);
	}

      if (size < 0)
	{
	  g_printerr ("Error receiving from socket: %s\n",
		      error->message);
	  return 1;
	}

      if (size == 0)
	break;

      g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size);
      if (use_udp)
	g_print (" from %s", socket_address_to_string (address));
      g_print ("\n");

      if (verbose)
	g_print ("-------------------------\n"
		 "%.*s\n"
		 "-------------------------\n",
		 (int)size, buffer);

      to_send = size;

#ifdef __QNXNTO__
      if (delay_)
#else
      if (delay)
#endif
	{
#ifdef __QNXNTO__
	  if (verbose)
	    g_print ("delaying %d seconds before response\n", delay_);
	  g_usleep (1000 * 1000 * delay_);
#else
	  if (verbose)
	    g_print ("delaying %d seconds before response\n", delay);
	  g_usleep (1000 * 1000 * delay);
#endif
	}

      while (to_send > 0)
	{
	  if (use_udp)
	    {
	      ensure_socket_condition (recv_socket, G_IO_OUT, cancellable);
	      size = g_socket_send_to (recv_socket, address,
				       buffer, to_send, cancellable, &error);
	    }
	  else
	    {
	      ensure_connection_condition (connection, G_IO_OUT, cancellable);
	      size = g_output_stream_write (ostream,
					    buffer, to_send,
					    cancellable, &error);
	    }

	  if (size < 0)
	    {
	      if (g_error_matches (error,
				   G_IO_ERROR,
				   G_IO_ERROR_WOULD_BLOCK))
		{
		  g_print ("socket send would block, handling\n");
		  g_error_free (error);
		  error = NULL;
		  continue;
		}
	      else
		{
		  g_printerr ("Error sending to socket: %s\n",
			      error->message);
		  return 1;
		}
	    }

	  g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size);

	  if (size == 0)
	    {
	      g_printerr ("Unexpected short write\n");
	      return 1;
	    }

	  to_send -= size;
	}
    }

  g_print ("connection closed\n");

  if (connection)
    {
      if (!g_io_stream_close (connection, NULL, &error))
	{
	  g_printerr ("Error closing connection stream: %s\n",
		      error->message);
	  return 1;
	}
      g_object_unref (connection);
    }

  if (!g_socket_close (socket, &error))
    {
      g_printerr ("Error closing master socket: %s\n",
		  error->message);
      return 1;
    }
  g_object_unref (socket);

  return 0;
}
コード例 #10
0
static GDBusConnection*
get_connection_for_path (gchar *sysroot,
                         gboolean force_peer,
                         GPid *out_peer_pid,
                         GCancellable *cancellable,
                         GError **error)
{
  glnx_unref_object GDBusConnection *connection = NULL;
  glnx_unref_object GSocketConnection *stream = NULL;
  glnx_unref_object GSocket *socket = NULL;
  _cleanup_peer_ GPid peer_pid = 0;

  gchar buffer[16];

  int pair[2];

  const gchar *args[] = {
    "rpm-ostree",
    "start-daemon",
    "--sysroot", sysroot,
    "--dbus-peer", buffer,
    NULL
  };

  /* This is only intended for use by installed tests.
   * Note that it disregards the 'sysroot' and 'force_peer' options
   * and assumes the service activation command has been configured
   * to use the desired system root path. */
  if (g_getenv ("RPMOSTREE_USE_SESSION_BUS") != NULL)
    {
      if (sysroot != NULL)
        g_warning ("RPMOSTREE_USE_SESSION_BUS set, ignoring --sysroot=%s", sysroot);

      /* NB: as opposed to other early returns, this is _also_ a happy path */
      GDBusConnection *ret = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, error);
      if (!ret)
        return glnx_prefix_error_null (error, "Connecting to session bus");
      return ret;
    }

  if (sysroot == NULL)
    sysroot = "/";

  if (g_strcmp0 ("/", sysroot) == 0 && force_peer == FALSE)
    {
      /* NB: as opposed to other early returns, this is _also_ a happy path */
      GDBusConnection *ret = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
      if (!ret)
        return glnx_prefix_error_null (error, "Connecting to system bus");
      return ret;
    }

  g_print ("Running in single user mode. Be sure no other users are modifying the system\n");
  if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0)
    return glnx_null_throw_errno_prefix (error, "couldn't create socket pair");

  g_snprintf (buffer, sizeof (buffer), "%d", pair[1]);

  socket = g_socket_new_from_fd (pair[0], error);
  if (socket == NULL)
    {
      close (pair[0]);
      close (pair[1]);
      return NULL;
    }

  if (!g_spawn_async (NULL, (gchar **)args, NULL,
                      G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD,
                      NULL, NULL, &peer_pid, error))
    {
      close (pair[1]);
      return NULL;
    }

  stream = g_socket_connection_factory_create_connection (socket);
  connection = g_dbus_connection_new_sync (G_IO_STREAM (stream), NULL,
                                           G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                           NULL, cancellable, error);
  if (!connection)
    return NULL;

  *out_peer_pid = peer_pid; peer_pid = 0;
  return connection;
}
コード例 #11
0
ファイル: socket-client.c プロジェクト: endlessm/glib
static gboolean
make_connection (const char       *argument,
		 GTlsCertificate  *certificate,
		 GCancellable     *cancellable,
		 GSocket         **socket,
		 GSocketAddress  **address,
		 GIOStream       **connection,
		 GInputStream    **istream,
		 GOutputStream   **ostream,
		 GError          **error)
{
  GSocketType socket_type;
  GSocketFamily socket_family;
  GSocketAddressEnumerator *enumerator;
  GSocketConnectable *connectable;
  GSocketAddress *src_address;
  GTlsInteraction *interaction;
  GError *err = NULL;

  if (use_udp)
    socket_type = G_SOCKET_TYPE_DATAGRAM;
  else
    socket_type = G_SOCKET_TYPE_STREAM;

  if (unix_socket)
    socket_family = G_SOCKET_FAMILY_UNIX;
  else
    socket_family = G_SOCKET_FAMILY_IPV4;

  *socket = g_socket_new (socket_family, socket_type, 0, error);
  if (*socket == NULL)
    return FALSE;

  if (read_timeout)
    g_socket_set_timeout (*socket, read_timeout);

  if (unix_socket)
    {
      GSocketAddress *addr;

      addr = socket_address_from_string (argument);
      if (addr == NULL)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Could not parse '%s' as unix socket name", argument);
          return FALSE;
        }
      connectable = G_SOCKET_CONNECTABLE (addr);
    }
  else
    {
      connectable = g_network_address_parse (argument, 7777, error);
      if (connectable == NULL)
        return FALSE;
    }

  enumerator = g_socket_connectable_enumerate (connectable);
  while (TRUE)
    {
      *address = g_socket_address_enumerator_next (enumerator, cancellable, error);
      if (*address == NULL)
        {
          if (error != NULL && *error == NULL)
            g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                 "No more addresses to try");
          return FALSE;
        }

      if (g_socket_connect (*socket, *address, cancellable, &err))
        break;
      g_message ("Connection to %s failed: %s, trying next", socket_address_to_string (*address), err->message);
      g_clear_error (&err);

      g_object_unref (*address);
    }
  g_object_unref (enumerator);

  g_print ("Connected to %s\n",
           socket_address_to_string (*address));

  src_address = g_socket_get_local_address (*socket, error);
  if (!src_address)
    {
      g_prefix_error (error, "Error getting local address: ");
      return FALSE;
    }

  g_print ("local address: %s\n",
           socket_address_to_string (src_address));
  g_object_unref (src_address);

  if (use_udp)
    {
      *connection = NULL;
      *istream = NULL;
      *ostream = NULL;
    }
  else
    *connection = G_IO_STREAM (g_socket_connection_factory_create_connection (*socket));

  if (tls)
    {
      GIOStream *tls_conn;

      tls_conn = g_tls_client_connection_new (*connection, connectable, error);
      if (!tls_conn)
        {
          g_prefix_error (error, "Could not create TLS connection: ");
          return FALSE;
        }

      g_signal_connect (tls_conn, "accept-certificate",
                        G_CALLBACK (accept_certificate), NULL);

      interaction = g_tls_console_interaction_new ();
      g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn), interaction);
      g_object_unref (interaction);

      if (certificate)
        g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn), certificate);

      g_object_unref (*connection);
      *connection = G_IO_STREAM (tls_conn);

      if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn),
                                       cancellable, error))
        {
          g_prefix_error (error, "Error during TLS handshake: ");
          return FALSE;
        }
    }
  g_object_unref (connectable);

  if (*connection)
    {
      *istream = g_io_stream_get_input_stream (*connection);
      *ostream = g_io_stream_get_output_stream (*connection);
    }

  return TRUE;
}