Exemplo n.º 1
0
static gpointer
gst_switch_server_controller (GstSwitchServer *srv)
{
  GSocket *socket;
  GError *error;
  gint bound_port;

  srv->controller_socket = gst_switch_server_listen (srv,
      srv->controller_port, &bound_port);
  if (!srv->controller_socket) {
    return NULL;
  }

  while (srv->controller_thread && srv->controller_socket && srv->cancellable) {
    socket = g_socket_accept (srv->controller_socket, srv->cancellable, &error);
    if (!socket) {
      ERROR ("accept: %s", error->message);
      continue;
    }

    gst_switch_server_allow_tcp_control (srv, socket);
  }

  GST_SWITCH_SERVER_LOCK_CONTROLLER (srv);
  g_thread_unref (srv->controller_thread);
  srv->controller_thread = NULL;
  GST_SWITCH_SERVER_UNLOCK_CONTROLLER (srv);
  return NULL;
}
Exemplo n.º 2
0
/**
 * 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;
}
Exemplo n.º 3
0
static gpointer
gst_switch_server_audio_acceptor (GstSwitchServer *srv)
{
  GSocket *socket;
  GError *error;
  gint bound_port;

  srv->audio_acceptor_socket = gst_switch_server_listen (srv,
      srv->audio_acceptor_port, &bound_port);
  if (!srv->audio_acceptor_socket) {
    return NULL;
  }

  while (srv->audio_acceptor && srv->audio_acceptor_socket && srv->cancellable) {
    socket = g_socket_accept (srv->audio_acceptor_socket, srv->cancellable, &error);
    if (!socket) {
      ERROR ("accept: %s", error->message);
      continue;
    }

    gst_switch_server_serve (srv, socket, GST_SERVE_AUDIO_STREAM);
  }

  GST_SWITCH_SERVER_LOCK_AUDIO_ACCEPTOR (srv);
  g_thread_unref (srv->audio_acceptor);
  srv->audio_acceptor = NULL;
  GST_SWITCH_SERVER_UNLOCK_AUDIO_ACCEPTOR (srv);
  return NULL;
}
Exemplo n.º 4
0
static gboolean
accept_ready (GSocket      *accept_socket,
	      GIOCondition  condition,
	      gpointer      user_data)
{
  GTask *task = user_data;
  GError *error = NULL;
  GSocket *socket;
  GObject *source_object;

  socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
  if (socket)
    {
      source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
      if (source_object)
	g_object_set_qdata_full (G_OBJECT (task),
				 source_quark,
				 g_object_ref (source_object), g_object_unref);
      g_task_return_pointer (task, socket, g_object_unref);
    }
  else
    {
      g_task_return_error (task, error);
    }

  g_object_unref (task);
  return FALSE;
}
Exemplo n.º 5
0
KmsSCTPResult
kms_sctp_connection_accept (KmsSCTPConnection * conn,
    GCancellable * cancellable, KmsSCTPConnection ** client, GError ** err)
{
  KmsSCTPConnection *ccon;
  GSocket *socket;

  g_return_val_if_fail (conn != NULL, KMS_SCTP_ERROR);
  g_return_val_if_fail (conn->socket != NULL, KMS_SCTP_ERROR);

  socket = g_socket_accept (conn->socket, cancellable, err);
  if (socket == NULL)
    return KMS_SCTP_ERROR;

  ccon = g_slice_new0 (KmsSCTPConnection);

  gst_mini_object_init (GST_MINI_OBJECT_CAST (ccon), 0,
      _kms_sctp_connection_type, NULL, NULL,
      (GstMiniObjectFreeFunction) _kms_sctp_connection_free);

  ccon->socket = socket;

  if (!kms_sctp_connection_set_event_subscribe (ccon, KMS_SCTP_DATA_IO_EVENT,
          err)) {
    kms_sctp_connection_unref (ccon);
    return KMS_SCTP_ERROR;
  }

  if (G_UNLIKELY (GST_LEVEL_DEBUG <= _gst_debug_min))
#if defined (SCTP_INITMSG)
  {
    struct sctp_initmsg initmsg;
    socklen_t optlen;

    if (getsockopt (g_socket_get_fd (socket), IPPROTO_SCTP,
            SCTP_INITMSG, &initmsg, &optlen) < 0) {
      GST_WARNING ("Could not get SCTP configuration: %s (%d)",
          g_strerror (errno), errno);
    } else {
      GST_DEBUG ("SCTP client socket: ostreams %u, instreams %u",
          initmsg.sinit_num_ostreams, initmsg.sinit_num_ostreams);
    }
  }
#else
  {
    GST_WARNING ("don't know how to get the configuration of the "
        "SCTP initiation structure on this OS.");
  }
#endif

  *client = ccon;

  return KMS_SCTP_OK;
}
Exemplo n.º 6
0
/**
 * g_socket_listener_accept_socket:
 * @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 the #GSocket that was accepted.
 *
 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
 * which is often the case, then you should use g_socket_listener_accept()
 * instead.
 *
 * 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 #GSocket on success, %NULL on error.
 *
 * Since: 2.22
 */
GSocket *
g_socket_listener_accept_socket (GSocketListener  *listener,
				 GObject         **source_object,
				 GCancellable     *cancellable,
				 GError          **error)
{
  GSocket *accept_socket, *socket;

  g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);

  if (!check_listener (listener, error))
    return NULL;

  if (listener->priv->sockets->len == 1)
    {
      accept_socket = listener->priv->sockets->pdata[0];
      if (!g_socket_condition_wait (accept_socket, G_IO_IN,
				    cancellable, error))
	return NULL;
    }
  else
    {
      GList *sources;
      struct AcceptData data;
      GMainLoop *loop;

      if (listener->priv->main_context == NULL)
	listener->priv->main_context = g_main_context_new ();

      loop = g_main_loop_new (listener->priv->main_context, FALSE);
      data.loop = loop;
      sources = add_sources (listener,
			     accept_callback,
			     &data,
			     cancellable,
			     listener->priv->main_context);
      g_main_loop_run (loop);
      accept_socket = data.socket;
      free_sources (sources);
      g_main_loop_unref (loop);
    }

  if (!(socket = g_socket_accept (accept_socket, cancellable, error)))
    return NULL;

  if (source_object)
    *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);

  return socket;
}
Exemplo n.º 7
0
NiceSocket *
nice_tcp_passive_socket_accept (NiceSocket *sock)
{
  union {
    struct sockaddr_storage storage;
    struct sockaddr addr;
  } name;
  TcpPassivePriv *priv = sock->priv;
  GSocket *gsock = NULL;
  GSocketAddress *gaddr;
  NiceAddress remote_addr;
  NiceSocket *new_socket = NULL;

  gsock = g_socket_accept (sock->fileno, NULL, NULL);

  if (gsock == NULL) {
    return NULL;
  }

  /* GSocket: All socket file descriptors are set to be close-on-exec. */
  g_socket_set_blocking (gsock, false);

  gaddr = g_socket_get_remote_address (gsock, NULL);
  if (gaddr == NULL ||
      !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) {
    g_socket_close (gsock, NULL);
    g_object_unref (gsock);
    return NULL;
  }
  g_object_unref (gaddr);

  nice_address_set_from_sockaddr (&remote_addr, &name.addr);

  new_socket = nice_tcp_bsd_socket_new_from_gsock (priv->context, gsock,
      &sock->addr, &remote_addr, TRUE);
  g_object_unref (gsock);

  if (new_socket) {
    NiceAddress *key = nice_address_dup (&remote_addr);

    nice_socket_set_writable_callback (new_socket, _child_writable_cb, sock);
    g_hash_table_insert (priv->connections, key, new_socket);
  }
  return new_socket;
}
Exemplo n.º 8
0
int main(int argc, char *argv[])
{
    GError *err = NULL;
    GSocket *serv_gsock;
    GSocketAddress *gaddr;
    struct sockaddr_in addr;

    /* Create socket */
    serv_gsock = g_socket_new(G_SOCKET_FAMILY_IPV4,
                          G_SOCKET_TYPE_STREAM,
                          0,
                          &err);
    if (!serv_gsock) {
        printf("GSocket creation failure: %s\n", err->message);
        g_clear_error(&err);
    }

    /* Bind to 127.0.0.1 */
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(10086);
    inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
    gaddr = g_socket_address_new_from_native(&addr, sizeof(addr));
    if (!g_socket_bind(serv_gsock, gaddr, TRUE, &err)) {
        printf("GSocket bind failure: %s\n", err->message);
        g_clear_error(&err);
    }

    /* Listen */
    if (!g_socket_listen(serv_gsock, &err)) {
        printf("GSocket listen failure: %s\n", err->message);
        g_clear_error(&err);
    }

    /* Accept */
    gchar buffer[256];
    gsize bytes_read;
    GSocket *clnt_gsock;
    clnt_gsock = g_socket_accept(serv_gsock, NULL, &err);
    bytes_read = g_socket_receive(clnt_gsock, buffer, 256, NULL, &err);
    printf("%u read: <%s>\n", (unsigned int)bytes_read, buffer);
    return 0;
}
Exemplo n.º 9
0
static gpointer
gst_tcp_mix_src_acceptor_thread (GstTCPMixSrc * src)
{
  GSocket *socket;
  GError *err;

  while (src->server_socket && src->cancellable) {
    socket = g_socket_accept (src->server_socket, src->cancellable, &err);
    if (!socket) {
      GST_WARNING_OBJECT (src, "Failed to accept: %s", err->message);
      continue;
    }

    gst_tcp_mix_src_add_client (src, socket);
  }

  g_mutex_lock (&src->acceptor_mutex);
  g_thread_unref (src->acceptor);
  src->acceptor = NULL;
  g_mutex_unlock (&src->acceptor_mutex);
  return NULL;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
Arquivo: main.c Projeto: dram/configs
int main(void)
{
	GSocket *sock;

	sock = create_socket();
	committed = g_string_new("");

	puts("Emacs-fcitx is ready.");

	while (TRUE) {
		GSource *source;
		GSocket *connection;
		GMainLoop *main_loop;

		if ((connection = g_socket_accept(sock, NULL, NULL)) == NULL) {
			perror("g_socket_accept");
			exit(1);
		}

		puts("Opening connection.");

		client = fcitx_client_new();

		g_signal_connect(client, "connected",
				 G_CALLBACK(connect_cb), NULL);
		g_signal_connect(client, "disconnected",
				 G_CALLBACK(destroy_cb), NULL);
		g_signal_connect(client, "enable-im",
				 G_CALLBACK(enable_im_cb), NULL);
		g_signal_connect(client, "close-im",
				 G_CALLBACK(close_im_cb), NULL);
		g_signal_connect(client, "forward-key",
				 G_CALLBACK(forward_key_cb), NULL);
		g_signal_connect(client, "commit-string",
				 G_CALLBACK(commit_string_cb), NULL);
		g_signal_connect(client,
				 "update-client-side-ui",
				 G_CALLBACK(update_client_side_ui_cb),
				 connection);

		main_loop = g_main_loop_new(NULL, FALSE);

		source = g_socket_create_source(
			connection,
			(GIOCondition)(G_IO_IN | G_IO_HUP | G_IO_ERR), NULL);

		g_source_set_callback(
			source, (GSourceFunc)source_cb, main_loop, NULL);

		g_source_attach(source, NULL);

		g_main_loop_run(main_loop);

		puts("main loop finished.");

		g_socket_close(connection, NULL);

		g_object_unref(client);
		g_source_unref(source);
		g_object_unref(connection);
		g_main_loop_unref(main_loop);
	}

	g_object_unref(sock);
	g_string_free(committed, TRUE);

	return 0;
}
Exemplo n.º 12
0
		async_context = priv->async_context;

	g_source_attach (watch, async_context);
	g_source_unref (watch);

	return watch;
}

static gboolean
listen_watch (GObject *pollable, gpointer data)
{
	SoupSocket *sock = data, *new;
	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
	GSocket *new_gsock;

	new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
	if (!new_gsock)
		return FALSE;

	new = g_object_new (SOUP_TYPE_SOCKET, NULL);
	new_priv = SOUP_SOCKET_GET_PRIVATE (new);
	new_priv->gsock = new_gsock;
	if (priv->async_context)
		new_priv->async_context = g_main_context_ref (priv->async_context);
	new_priv->use_thread_context = priv->use_thread_context;
	new_priv->non_blocking = priv->non_blocking;
	new_priv->is_server = TRUE;
	new_priv->ssl = priv->ssl;
	if (priv->ssl_creds)
		new_priv->ssl_creds = priv->ssl_creds;
	finish_socket_setup (new_priv);
Exemplo n.º 13
0
static GstFlowReturn
gst_tcp_server_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
{
  GstTCPServerSrc *src;
  GstFlowReturn ret = GST_FLOW_OK;
  gssize rret, avail;
  gsize read;
  GError *err = NULL;
  GstMapInfo map;

  src = GST_TCP_SERVER_SRC (psrc);

  if (!GST_OBJECT_FLAG_IS_SET (src, GST_TCP_SERVER_SRC_OPEN))
    goto wrong_state;

  if (!src->client_socket) {
    /* wait on server socket for connections */
    src->client_socket =
        g_socket_accept (src->server_socket, src->cancellable, &err);
    if (!src->client_socket)
      goto accept_error;
    /* now read from the socket. */
  }

  /* if we have a client, wait for read */
  GST_LOG_OBJECT (src, "asked for a buffer");

  /* read the buffer header */
  avail = g_socket_get_available_bytes (src->client_socket);
  if (avail < 0) {
    goto get_available_error;
  } else if (avail == 0) {
    GIOCondition condition;

    if (!g_socket_condition_wait (src->client_socket,
            G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, src->cancellable, &err))
      goto select_error;

    condition =
        g_socket_condition_check (src->client_socket,
        G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP);

    if ((condition & G_IO_ERR)) {
      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
          ("Socket in error state"));
      *outbuf = NULL;
      ret = GST_FLOW_ERROR;
      goto done;
    } else if ((condition & G_IO_HUP)) {
      GST_DEBUG_OBJECT (src, "Connection closed");
      *outbuf = NULL;
      ret = GST_FLOW_EOS;
      goto done;
    }
    avail = g_socket_get_available_bytes (src->client_socket);
    if (avail < 0)
      goto get_available_error;
  }

  if (avail > 0) {
    read = MIN (avail, MAX_READ_SIZE);
    *outbuf = gst_buffer_new_and_alloc (read);
    gst_buffer_map (*outbuf, &map, GST_MAP_READWRITE);
    rret =
        g_socket_receive (src->client_socket, (gchar *) map.data, read,
        src->cancellable, &err);
  } else {
    /* Connection closed */
    rret = 0;
    *outbuf = NULL;
    read = 0;
  }

  if (rret == 0) {
    GST_DEBUG_OBJECT (src, "Connection closed");
    ret = GST_FLOW_EOS;
    if (*outbuf) {
      gst_buffer_unmap (*outbuf, &map);
      gst_buffer_unref (*outbuf);
    }
    *outbuf = NULL;
  } else if (rret < 0) {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      ret = GST_FLOW_FLUSHING;
      GST_DEBUG_OBJECT (src, "Cancelled reading from socket");
    } else {
      ret = GST_FLOW_ERROR;
      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
          ("Failed to read from socket: %s", err->message));
    }
    gst_buffer_unmap (*outbuf, &map);
    gst_buffer_unref (*outbuf);
    *outbuf = NULL;
  } else {
    ret = GST_FLOW_OK;
    gst_buffer_unmap (*outbuf, &map);
    gst_buffer_resize (*outbuf, 0, rret);

    GST_LOG_OBJECT (src,
        "Returning buffer from _get of size %" G_GSIZE_FORMAT ", ts %"
        GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT
        ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
        gst_buffer_get_size (*outbuf),
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*outbuf)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (*outbuf)),
        GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf));
  }
  g_clear_error (&err);

done:
  return ret;

wrong_state:
  {
    GST_DEBUG_OBJECT (src, "connection to closed, cannot read data");
    return GST_FLOW_FLUSHING;
  }
accept_error:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled accepting of client");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to accept client: %s", err->message));
    }
    g_clear_error (&err);
    return GST_FLOW_ERROR;
  }
select_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Select failed: %s", err->message));
    g_clear_error (&err);
    return GST_FLOW_ERROR;
  }
get_available_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Failed to get available bytes from socket"));
    return GST_FLOW_ERROR;
  }
}
Exemplo n.º 14
0
Arquivo: server.c Projeto: GNOME/gnio
int
main (int argc,
      char *argv[])
{
  GSocket *socket, *new_socket, *recv_socket;
  GSocketAddress *src_address;
  GSocketAddress *address;
  GSocketType socket_type;
  GError *error = NULL;
  GOptionContext *context;
  GCancellable *cancellable;

  g_thread_init (NULL);

  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 (cancel_timeout)
    {
      cancellable = g_cancellable_new ();
      g_thread_create (cancel_thread, cancellable, FALSE, NULL);
    }
  else
    {
      cancellable = NULL;
    }

  loop = g_main_loop_new (NULL, FALSE);

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

  socket = g_socket_new (G_SOCKET_FAMILY_IPV4, 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);

  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;
    }

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

      g_print ("listening on port %d...\n", port);

      ensure_condition (socket, "accept", cancellable, G_IO_IN);
      new_socket = g_socket_accept (socket, &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);

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

      g_print ("got a new connection from %s (blocking: %d)\n",
	       socket_address_to_string (address),
	       g_socket_get_blocking (new_socket));

      recv_socket = new_socket;
    }
  else
    {
      recv_socket = socket;
      new_socket = NULL;
    }


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

      ensure_condition (recv_socket, "receive", cancellable, G_IO_IN);
      if (use_udp)
	size = g_socket_receive_from (recv_socket, &address,
				      buffer, sizeof buffer, &error);
      else
	size = g_socket_receive (recv_socket, buffer, sizeof buffer, &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;

      while (to_send > 0)
	{
	  ensure_condition (recv_socket, "send", cancellable, G_IO_OUT);
	  if (use_udp)
	    size = g_socket_send_to (recv_socket, address,
				     buffer, to_send, &error);
	  else
	    size = g_socket_send (recv_socket, buffer, to_send, &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 (new_socket)
    {
      if (!g_socket_close (new_socket, &error))
	{
	  g_printerr ("Error closing connection socket: %s\n",
		      error->message);
	  return 1;
	}

      g_object_unref (G_OBJECT (new_socket));
    }

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

  g_object_unref (G_OBJECT (socket));

  return 0;
}