RemoteDisplayHost *
remote_display_host_new (GInetAddress *remote_address,
			 GInetAddress *local_address)
{
	g_return_val_if_fail (G_INET_ADDRESS (remote_address), NULL);
	g_return_val_if_fail (G_INET_ADDRESS (local_address), NULL);

	return g_object_new (REMOTE_DISPLAY_TYPE_HOST,
			     "remote-address", remote_address,
			     "local-address", local_address,
			     NULL);
}
Esempio n. 2
0
static gboolean
is_multicast_address (const gchar * host_name)
{
  GInetAddress *addr;
  GResolver *resolver = NULL;
  gboolean ret = FALSE;

  addr = g_inet_address_new_from_string (host_name);
  if (!addr) {
    GList *results;

    resolver = g_resolver_get_default ();
    results = g_resolver_lookup_by_name (resolver, host_name, NULL, NULL);
    if (!results)
      goto out;
    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
  }
  g_assert (addr != NULL);

  ret = g_inet_address_get_is_multicast (addr);

out:
  if (resolver)
    g_object_unref (resolver);
  if (addr)
    g_object_unref (addr);
  return ret;
}
Esempio n. 3
0
GCancellable *ekg_connection_starter_run(
		ekg_connection_starter_t cs,
		GSocketClient *sock,
		ekg_connection_callback_t callback,
		ekg_connection_failure_callback_t failure_callback,
		gpointer priv_data)
{
	cs->callback = callback;
	cs->failure_callback = failure_callback;
	cs->priv_data = priv_data;

	cs->cancellable = g_cancellable_new();
	cs->current_server = cs->servers;

	if (cs->bind_hostname) {
		GResolver *res = g_resolver_get_default();
		GList *addrs;
		GError *err = NULL;

		addrs = g_resolver_lookup_by_name(
				res,
				cs->bind_hostname,
				NULL,
				&err);

		if (!addrs) {
				/* XXX: delay calling that */
			failed_async_connect(sock, err, cs);
			g_error_free(err);
			return cs->cancellable;
		}

		g_socket_client_set_local_address(sock,
				g_inet_socket_address_new(
					G_INET_ADDRESS(g_list_nth_data(addrs, 0)), 0));

		g_resolver_free_addresses(addrs);
		g_object_unref(res);
	}

		/* if we have the domain name, try SRV lookup first */
	if (cs->domain) {
		g_assert(cs->service);

			/* fallback to domainname lookup if 'servers' not set */
		if (!cs->servers || !cs->servers[0])
			ekg_connection_starter_set_servers(cs, cs->domain);

		debug_function("ekg_connection_start(), trying _%s._tcp.%s\n",
				cs->service, cs->domain);
		g_socket_client_connect_to_service_async(
				sock, cs->domain, cs->service,
				cs->cancellable,
				done_async_connect,
				cs);
	} else /* otherwise, just begin with servers */
		g_assert(setup_async_connect(sock, cs));

	return cs->cancellable;
}
Esempio n. 4
0
static void
hbn_listen_cb(int fd, gpointer data) {
	StunHBNListenData *ld = (StunHBNListenData *)data;
	GInetAddress *address = NULL;
	GSocketAddress *socket_address = NULL;
	struct stun_conn *sc;
	static struct stun_header hdr_data;

	if(fd < 0) {
		nattype.status = PURPLE_STUN_STATUS_UNKNOWN;
		nattype.lookup_time = time(NULL);
		do_callbacks();
		return;
	}

	sc = g_new0(struct stun_conn, 1);
	sc->fd = fd;

	sc->addr.sin_family = AF_INET;
	sc->addr.sin_port = htons(purple_network_get_port_from_fd(fd));
	sc->addr.sin_addr.s_addr = INADDR_ANY;

	sc->incb = purple_input_add(fd, PURPLE_INPUT_READ, reply_cb, sc);

	address = G_INET_ADDRESS(ld->addresses->data);
	socket_address = g_inet_socket_address_new(address, ld->port);

	g_socket_address_to_native(socket_address, &(sc->addr), g_socket_address_get_native_size(socket_address), NULL);

	g_object_unref(G_OBJECT(address));
	g_object_unref(G_OBJECT(socket_address));
	g_resolver_free_addresses(ld->addresses);
	g_free(ld);

	hdr_data.type = htons(MSGTYPE_BINDINGREQUEST);
	hdr_data.len = 0;
	hdr_data.transid[0] = rand();
	hdr_data.transid[1] = ntohl(((int)'g' << 24) + ((int)'a' << 16) + ((int)'i' << 8) + (int)'m');
	hdr_data.transid[2] = rand();
	hdr_data.transid[3] = rand();

	if(sendto(sc->fd, &hdr_data, sizeof(struct stun_header), 0,
			(struct sockaddr *)&(sc->addr),
			sizeof(struct sockaddr_in)) < (gssize)sizeof(struct stun_header)) {
		nattype.status = PURPLE_STUN_STATUS_UNKNOWN;
		nattype.lookup_time = time(NULL);
		do_callbacks();
		close_stun_conn(sc);
		return;
	}
	sc->test = 1;
	sc->packet = &hdr_data;
	sc->packetsize = sizeof(struct stun_header);
	sc->timeout = purple_timeout_add(500, (GSourceFunc) timeoutfunc, sc);
}
Esempio n. 5
0
static gboolean
kms_sctp_connection_create_socket (KmsSCTPConnection * conn, gchar * host,
    gint port, GCancellable * cancellable, GError ** err)
{
  GInetAddress *addr;

  /* look up name if we need to */
  addr = g_inet_address_new_from_string (host);
  if (addr == NULL) {
    GResolver *resolver;
    GList *results;

    resolver = g_resolver_get_default ();
    results = g_resolver_lookup_by_name (resolver, host, cancellable, err);

    if (results == NULL) {
      g_object_unref (resolver);
      return FALSE;
    }

    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }

  if (G_UNLIKELY (GST_LEVEL_DEBUG <= _gst_debug_min)) {
    gchar *ip = g_inet_address_to_string (addr);

    GST_DEBUG ("IP address for host %s is %s", host, ip);
    g_free (ip);
  }

  conn->saddr = g_inet_socket_address_new (addr, port);
  g_object_unref (addr);

  conn->socket = g_socket_new (g_socket_address_get_family (conn->saddr),
      G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_SCTP, err);

  if (conn->socket == NULL) {
    g_clear_object (&conn->saddr);
    return FALSE;
  }

  /* create socket */
  GST_DEBUG ("created SCTP socket for %s", host);

  return TRUE;
}
Esempio n. 6
0
int setRTPConnectionToServer(GstRTSPsink *sink)
{

	GError *error;

//	gchar *host = sink->host; // "www.ynet.co.il";// "192.168.2.108"; 
//	gint port = sink->server_rtp_port;
//

	if (!sink->socket)  {
		sink->socket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL);

		gchar *s;
		GInetAddress *ia;
		ia = g_inet_address_new_from_string(sink->host);


		// Try to get hostby name 
		if (!ia) {
			GResolver *resolver;
			resolver = g_resolver_get_default();
			GList *results;
			results = g_resolver_lookup_by_name(resolver, sink->host, FALSE, &error);
			if (results){
				ia = G_INET_ADDRESS(g_object_ref(results->data));
			}

			gchar *ip = g_inet_address_to_string(ia);

			g_print("IP address for host %s is %s", sink->host, ip);
			g_free(ip);

			g_resolver_free_addresses(results);
			g_object_unref(resolver);
		}


		s = g_inet_address_to_string(ia);
		sink->sa = g_inet_socket_address_new(ia, sink->server_rtp_port);
	}


	if (sink->socket != NULL && sink->sa != NULL)
		return GST_RTSP_OK;

	return GST_RTSP_ERROR;

}
Esempio n. 7
0
static GstUDPClient *
create_client (GstMultiUDPSink * sink, const gchar * host, gint port)
{
  GstUDPClient *client;
  GInetAddress *addr;
  GResolver *resolver;
  GError *err = NULL;

  addr = g_inet_address_new_from_string (host);
  if (!addr) {
    GList *results;

    resolver = g_resolver_get_default ();
    results =
        g_resolver_lookup_by_name (resolver, host, sink->cancellable, &err);
    if (!results)
      goto name_resolve;
    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }
#ifndef GST_DISABLE_GST_DEBUG
  {
    gchar *ip = g_inet_address_to_string (addr);

    GST_DEBUG_OBJECT (sink, "IP address for host %s is %s", host, ip);
    g_free (ip);
  }
#endif

  client = g_slice_new0 (GstUDPClient);
  client->refcount = 1;
  client->host = g_strdup (host);
  client->port = port;
  client->addr = g_inet_socket_address_new (addr, port);
  g_object_unref (addr);

  return client;

name_resolve:
  {
    g_object_unref (resolver);

    return NULL;
  }
}
Esempio n. 8
0
static GInetAddress *
gst_udpsrc_resolve (GstUDPSrc * src, const gchar * address)
{
  GInetAddress *addr;
  GError *err = NULL;
  GResolver *resolver;

  addr = g_inet_address_new_from_string (address);
  if (!addr) {
    GList *results;

    GST_DEBUG_OBJECT (src, "resolving IP address for host %s", address);
    resolver = g_resolver_get_default ();
    results =
        g_resolver_lookup_by_name (resolver, address, src->cancellable, &err);
    if (!results)
      goto name_resolve;
    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }
#ifndef GST_DISABLE_GST_DEBUG
  {
    gchar *ip = g_inet_address_to_string (addr);

    GST_DEBUG_OBJECT (src, "IP address for host %s is %s", address, ip);
    g_free (ip);
  }
#endif

  return addr;

name_resolve:
  {
    GST_WARNING_OBJECT (src, "Failed to resolve %s: %s", address, err->message);
    g_clear_error (&err);
    g_object_unref (resolver);
    return NULL;
  }
}
Esempio n. 9
0
/* note that address_entry has already been validated =>
 *  both host and port (guaranteed to be a number in [0, 65535]) are set (family is optional)
 */
static gboolean
try_tcp (GDBusServer  *server,
         const gchar  *address_entry,
         GHashTable   *key_value_pairs,
         gboolean      do_nonce,
         GError      **error)
{
  gboolean ret;
  const gchar *host;
  const gchar *port;
  gint port_num;
  GResolver *resolver;
  GList *resolved_addresses;
  GList *l;

  ret = FALSE;
  resolver = NULL;
  resolved_addresses = NULL;

  host = g_hash_table_lookup (key_value_pairs, "host");
  port = g_hash_table_lookup (key_value_pairs, "port");
  /* family = g_hash_table_lookup (key_value_pairs, "family"); */
  if (g_hash_table_lookup (key_value_pairs, "noncefile") != NULL)
    {
      g_set_error_literal (error,
                           G_IO_ERROR,
                           G_IO_ERROR_INVALID_ARGUMENT,
                           _("Cannot specify nonce file when creating a server"));
      goto out;
    }

  if (host == NULL)
    host = "localhost";
  if (port == NULL)
    port = "0";
  port_num = strtol (port, NULL, 10);

  resolver = g_resolver_get_default ();
  resolved_addresses = g_resolver_lookup_by_name (resolver,
                                                  host,
                                                  NULL,
                                                  error);
  if (resolved_addresses == NULL)
    goto out;

  /* TODO: handle family */
  for (l = resolved_addresses; l != NULL; l = l->next)
    {
      GInetAddress *address = G_INET_ADDRESS (l->data);
      GSocketAddress *socket_address;
      GSocketAddress *effective_address;

      socket_address = g_inet_socket_address_new (address, port_num);
      if (!g_socket_listener_add_address (server->listener,
                                          socket_address,
                                          G_SOCKET_TYPE_STREAM,
                                          G_SOCKET_PROTOCOL_TCP,
                                          NULL, /* GObject *source_object */
                                          &effective_address,
                                          error))
        {
          g_object_unref (socket_address);
          goto out;
        }
      if (port_num == 0)
        /* make sure we allocate the same port number for other listeners */
        port_num = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (effective_address));

      g_object_unref (effective_address);
      g_object_unref (socket_address);
    }

  if (do_nonce)
    {
      gint fd;
      guint n;
      gsize bytes_written;
      gsize bytes_remaining;
      char *file_escaped;

      server->nonce = g_new0 (guchar, 16);
      for (n = 0; n < 16; n++)
        server->nonce[n] = g_random_int_range (0, 256);
      fd = g_file_open_tmp ("gdbus-nonce-file-XXXXXX",
                            &server->nonce_file,
                            error);
      if (fd == -1)
        {
          g_socket_listener_close (server->listener);
          goto out;
        }
    again:
      bytes_written = 0;
      bytes_remaining = 16;
      while (bytes_remaining > 0)
        {
          gssize ret;
          ret = write (fd, server->nonce + bytes_written, bytes_remaining);
          if (ret == -1)
            {
              if (errno == EINTR)
                goto again;
              g_set_error (error,
                           G_IO_ERROR,
                           g_io_error_from_errno (errno),
                           _("Error writing nonce file at '%s': %s"),
                           server->nonce_file,
                           strerror (errno));
              goto out;
            }
          bytes_written += ret;
          bytes_remaining -= ret;
        }
      if (!g_close (fd, error))
        goto out;
      file_escaped = g_uri_escape_string (server->nonce_file, "/\\", FALSE);
      server->client_address = g_strdup_printf ("nonce-tcp:host=%s,port=%d,noncefile=%s",
                                                host,
                                                port_num,
                                                file_escaped);
      g_free (file_escaped);
    }
  else
    {
      server->client_address = g_strdup_printf ("tcp:host=%s,port=%d", host, port_num);
    }
  server->is_using_listener = TRUE;
  ret = TRUE;

 out:
  g_list_free_full (resolved_addresses, g_object_unref);
  g_object_unref (resolver);
  return ret;
}
Esempio n. 10
0
static GSocket *
gst_switch_server_listen (GstSwitchServer *srv, gint port,
    gint *bound_port)
{
  GError *err = NULL;
  GInetAddress *addr;
  GSocket *socket = NULL;
  GSocketAddress *saddr;
  GResolver *resolver;
  gchar *ip;

  *bound_port = 0;

  /* look up name if we need to */
  addr = g_inet_address_new_from_string (srv->host);
  if (!addr) {
    GList *results;

    resolver = g_resolver_get_default ();
    results = g_resolver_lookup_by_name (resolver, srv->host,
        srv->cancellable, &err);
    if (!results)
      goto resolve_no_name;

    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }

  ip = g_inet_address_to_string (addr);
  saddr = g_inet_socket_address_new (addr, port);
  g_object_unref (addr);

  /* create the server listener socket */
  socket = g_socket_new (g_socket_address_get_family (saddr),
      G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &err);
  if (!socket)
    goto socket_new_failed;
  
  /* bind it */
  if (!g_socket_bind (socket, saddr, TRUE, &err))
    goto socket_bind_failed;

  g_object_unref (saddr);

  /* listen on the socket */
  g_socket_set_listen_backlog (socket, GST_SWITCH_SERVER_LISTEN_BACKLOG);
  if (!g_socket_listen (socket, &err))
    goto socket_listen_failed;

  if (port == 0) {
    saddr = g_socket_get_local_address (socket, NULL);
    *bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr);
    g_object_unref (saddr);
  } else {
    *bound_port = port;
  }

  INFO ("Listening on %s (%s:%d)", srv->host, ip, *bound_port);

  g_free (ip);

  //g_atomic_int_set (&srv->bound_port, bound_port);
  //g_object_notify (G_OBJECT (src), "bound-port");
  return socket;

  /* Errors Handling */

 resolve_no_name:
  {
    ERROR ("resolve: %s", err->message);
    g_object_unref (resolver);
    g_object_unref (addr);
    return NULL;
  }

 socket_new_failed:
  {
    ERROR ("new socket: %s", err->message);
    g_clear_error (&err);
    g_object_unref (saddr);
    g_free (ip);
    return NULL;
  }

 socket_bind_failed:
  {
    ERROR ("bind socket: %s", err->message);
    g_clear_error (&err);
    g_object_unref (saddr);
    g_free (ip);
    return NULL;
  }

 socket_listen_failed:
  {
    ERROR ("listen socket: %s", err->message);
    g_clear_error (&err);
    g_object_unref (saddr);
    g_free (ip);
    return NULL;
  }
}
/* create a socket for sending to remote machine */
static void
gst_sctp_base_sink_create_socket (GstSCTPBaseSink * self)
{
  GSocketAddress *saddr;
  GResolver *resolver;
  GInetAddress *addr;
  GError *err = NULL;

  if (GST_OBJECT_FLAG_IS_SET (self, GST_SCTP_BASE_SINK_OPEN))
    return;

  /* look up name if we need to */
  addr = g_inet_address_new_from_string (self->priv->host);
  if (addr == NULL) {
    GList *results;

    resolver = g_resolver_get_default ();
    results = g_resolver_lookup_by_name (resolver, self->priv->host,
        self->priv->cancellable, &err);

    if (results == NULL)
      goto name_resolve;

    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }

  if (G_UNLIKELY (GST_LEVEL_DEBUG <= _gst_debug_min)) {
    gchar *ip = g_inet_address_to_string (addr);

    GST_DEBUG_OBJECT (self, "IP address for host %s is %s", self->priv->host,
        ip);
    g_free (ip);
  }

  saddr = g_inet_socket_address_new (addr, self->priv->port);
  g_object_unref (addr);

  /* create sending client socket */
  GST_DEBUG_OBJECT (self, "opening sending client socket to %s:%d",
      self->priv->host, self->priv->port);

  self->priv->socket = g_socket_new (g_socket_address_get_family (saddr),
      G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_SCTP, &err);
  if (self->priv->socket == NULL)
    goto no_socket;

#if defined (SCTP_INITMSG)
  {
    struct sctp_initmsg initmsg;

    memset (&initmsg, 0, sizeof (initmsg));
    initmsg.sinit_num_ostreams = self->priv->num_ostreams;
    initmsg.sinit_max_instreams = self->priv->max_istreams;

    if (setsockopt (g_socket_get_fd (self->priv->socket), IPPROTO_SCTP,
            SCTP_INITMSG, &initmsg, sizeof (initmsg)) < 0)
      GST_ELEMENT_WARNING (self, RESOURCE, SETTINGS, (NULL),
          ("Could not configure SCTP socket: %s (%d)", g_strerror (errno),
              errno));
  }
#else
  GST_WARNING_OBJECT (self, "don't know how to configure the SCTP initiation "
      "parameters on this OS.");
#endif

  GST_DEBUG_OBJECT (self, "opened sending client socket");

  /* connect to server */
  if (!g_socket_connect (self->priv->socket, saddr, self->priv->cancellable,
          &err))
    goto connect_failed;

  g_object_unref (saddr);

  GST_OBJECT_FLAG_SET (self, GST_SCTP_BASE_SINK_OPEN);
  GST_DEBUG ("Created sctp socket");

  return;

no_socket:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL),
        ("Failed to create socket: %s", err->message));
    g_clear_error (&err);
    g_object_unref (saddr);
    return;
  }
name_resolve:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (self, "Cancelled name resolval");
    } else {
      GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL),
          ("Failed to resolve host '%s': %s", self->priv->host, err->message));
    }
    g_clear_error (&err);
    g_object_unref (resolver);
    return;
  }
connect_failed:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (self, "Cancelled connecting");
    } else {
      GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL),
          ("Failed to connect to host '%s:%d': %s", self->priv->host,
              self->priv->port, err->message));
    }
    g_clear_error (&err);
    g_object_unref (saddr);
    /* pretend we opened ok for proper cleanup to happen */
    GST_OBJECT_FLAG_SET (self, GST_SCTP_BASE_SINK_OPEN);
    gst_sctp_base_sink_destroy_socket (self);
    return;
  }
}
/* create a socket for sending to remote machine */
static gboolean
gst_udpsrc_open (GstUDPSrc * src)
{
  GInetAddress *addr, *bind_addr;
  GSocketAddress *bind_saddr;
  GError *err = NULL;

  if (src->socket == NULL) {
    /* need to allocate a socket */
    GST_DEBUG_OBJECT (src, "allocating socket for %s:%d", src->address,
        src->port);

    addr = gst_udpsrc_resolve (src, src->address);
    if (!addr)
      goto name_resolve;

    if ((src->used_socket =
            g_socket_new (g_inet_address_get_family (addr),
                G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL)
      goto no_socket;

    src->external_socket = FALSE;

    GST_DEBUG_OBJECT (src, "got socket %p", src->used_socket);

    if (src->addr)
      g_object_unref (src->addr);
    src->addr =
        G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, src->port));

    GST_DEBUG_OBJECT (src, "binding on port %d", src->port);

    /* On Windows it's not possible to bind to a multicast address
     * but the OS will make sure to filter out all packets that
     * arrive not for the multicast address the socket joined.
     *
     * On Linux and others it is necessary to bind to a multicast
     * address to let the OS filter out all packets that are received
     * on the same port but for different addresses than the multicast
     * address
     */
#ifdef G_OS_WIN32
    if (g_inet_address_get_is_multicast (addr))
      bind_addr = g_inet_address_new_any (g_inet_address_get_family (addr));
    else
#endif
      bind_addr = G_INET_ADDRESS (g_object_ref (addr));

    g_object_unref (addr);

    bind_saddr = g_inet_socket_address_new (bind_addr, src->port);
    g_object_unref (bind_addr);
    if (!g_socket_bind (src->used_socket, bind_saddr, src->reuse, &err))
      goto bind_error;

    g_object_unref (bind_saddr);
  } else {
    GST_DEBUG_OBJECT (src, "using provided socket %p", src->socket);
    /* we use the configured socket, try to get some info about it */
    src->used_socket = G_SOCKET (g_object_ref (src->socket));
    src->external_socket = TRUE;

    if (src->addr)
      g_object_unref (src->addr);
    src->addr =
        G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket,
            &err));
    if (!src->addr)
      goto getsockname_error;
  }

#if GLIB_CHECK_VERSION (2, 35, 7)
  {
    gint val = 0;

    if (src->buffer_size != 0) {
      GError *opt_err = NULL;

      GST_INFO_OBJECT (src, "setting udp buffer of %d bytes", src->buffer_size);
      /* set buffer size, Note that on Linux this is typically limited to a
       * maximum of around 100K. Also a minimum of 128 bytes is required on
       * Linux. */
      if (!g_socket_set_option (src->used_socket, SOL_SOCKET, SO_RCVBUF,
              src->buffer_size, &opt_err)) {
        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
            ("Could not create a buffer of requested %d bytes: %s",
                src->buffer_size, opt_err->message));
        g_error_free (opt_err);
        opt_err = NULL;
      }
    }

    /* read the value of the receive buffer. Note that on linux this returns
     * 2x the value we set because the kernel allocates extra memory for
     * metadata. The default on Linux is about 100K (which is about 50K
     * without metadata) */
    if (g_socket_get_option (src->used_socket, SOL_SOCKET, SO_RCVBUF, &val,
            NULL)) {
      GST_INFO_OBJECT (src, "have udp buffer of %d bytes", val);
    } else {
      GST_DEBUG_OBJECT (src, "could not get udp buffer size");
    }
  }
#elif defined (SO_RCVBUF)
  {
    gint rcvsize, ret;
    socklen_t len;

    len = sizeof (rcvsize);
    if (src->buffer_size != 0) {
      rcvsize = src->buffer_size;

      GST_DEBUG_OBJECT (src, "setting udp buffer of %d bytes", rcvsize);
      /* set buffer size, Note that on Linux this is typically limited to a
       * maximum of around 100K. Also a minimum of 128 bytes is required on
       * Linux. */
      ret =
          setsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF,
          (void *) &rcvsize, len);
      if (ret != 0) {
        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
            ("Could not create a buffer of requested %d bytes, %d: %s (%d)",
                rcvsize, ret, g_strerror (errno), errno));
      }
    }

    /* read the value of the receive buffer. Note that on linux this returns 2x the
     * value we set because the kernel allocates extra memory for metadata.
     * The default on Linux is about 100K (which is about 50K without metadata) */
    ret =
        getsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF,
        (void *) &rcvsize, &len);
    if (ret == 0)
      GST_DEBUG_OBJECT (src, "have udp buffer of %d bytes", rcvsize);
    else
      GST_DEBUG_OBJECT (src, "could not get udp buffer size");
  }
#else
  if (src->buffer_size != 0) {
    GST_WARNING_OBJECT (src, "don't know how to set udp buffer size on this "
        "OS. Consider upgrading your GLib to >= 2.35.7 and re-compiling the "
        "GStreamer udp plugin");
  }
#endif

  g_socket_set_broadcast (src->used_socket, TRUE);

  if (src->auto_multicast
      &&
      g_inet_address_get_is_multicast (g_inet_socket_address_get_address
          (src->addr))) {
    GST_DEBUG_OBJECT (src, "joining multicast group %s", src->address);
    if (!g_socket_join_multicast_group (src->used_socket,
            g_inet_socket_address_get_address (src->addr),
            FALSE, src->multi_iface, &err))
      goto membership;
  }

  /* NOTE: sockaddr_in.sin_port works for ipv4 and ipv6 because sin_port
   * follows ss_family on both */
  {
    GInetSocketAddress *addr;
    guint16 port;

    addr =
        G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket,
            &err));
    if (!addr)
      goto getsockname_error;

    port = g_inet_socket_address_get_port (addr);
    GST_DEBUG_OBJECT (src, "bound, on port %d", port);
    if (port != src->port) {
      src->port = port;
      GST_DEBUG_OBJECT (src, "notifying port %d", port);
      g_object_notify (G_OBJECT (src), "port");
    }
    g_object_unref (addr);
  }

  src->allocator = NULL;
  gst_allocation_params_init (&src->params);

  src->max_size = 0;

  return TRUE;

  /* ERRORS */
name_resolve:
  {
    return FALSE;
  }
no_socket:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("no socket error: %s", err->message));
    g_clear_error (&err);
    g_object_unref (addr);
    return FALSE;
  }
bind_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("bind failed: %s", err->message));
    g_clear_error (&err);
    g_object_unref (bind_saddr);
    gst_udpsrc_close (src);
    return FALSE;
  }
membership:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("could add membership: %s", err->message));
    g_clear_error (&err);
    gst_udpsrc_close (src);
    return FALSE;
  }
getsockname_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("getsockname failed: %s", err->message));
    g_clear_error (&err);
    gst_udpsrc_close (src);
    return FALSE;
  }
}
Esempio n. 13
0
static gboolean
gst_tcp_mix_src_listen (GstTCPMixSrc * src, GstTCPMixSrcPad * pad)
{
  GError *err = NULL;
  GInetAddress *addr;
  GSocketAddress *saddr;
  GResolver *resolver;
  gint bound_port = 0;
  gchar *ip;

  /* look up name if we need to */
  addr = g_inet_address_new_from_string (src->host);
  if (!addr) {
    GList *results;

    resolver = g_resolver_get_default ();
    results = g_resolver_lookup_by_name (resolver, src->host,
        src->cancellable, &err);
    if (!results)
      goto resolve_no_name;

    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }

  /* get IP address */
  ip = g_inet_address_to_string (addr);

  saddr = g_inet_socket_address_new (addr, src->server_port);
  g_object_unref (addr);

  /* create the server listener socket */
  src->server_socket = g_socket_new (g_socket_address_get_family (saddr),
      G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &err);
  if (!src->server_socket)
    goto socket_new_failed;

  /* bind it */
  if (!g_socket_bind (src->server_socket, saddr, TRUE, &err))
    goto socket_bind_failed;

  g_object_unref (saddr);

  g_socket_set_listen_backlog (src->server_socket, TCP_BACKLOG);
  if (!g_socket_listen (src->server_socket, &err))
    goto socket_listen_failed;

  GST_OBJECT_FLAG_SET (src, GST_TCP_MIX_SRC_OPEN);

  if (src->server_port == 0) {
    saddr = g_socket_get_local_address (src->server_socket, NULL);
    bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr);
    g_object_unref (saddr);
  } else {
    bound_port = src->server_port;
  }

  GST_DEBUG_OBJECT (src, "Listening on %s (%s:%d)", src->host, ip, bound_port);

  g_free (ip);

  g_atomic_int_set (&src->bound_port, bound_port);
  g_object_notify (G_OBJECT (src), "bound-port");

  return TRUE;

  /* Handling Errors */
resolve_no_name:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled name resolval");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to resolve host '%s': %s", src->host, err->message));
    }
    g_clear_error (&err);
    g_object_unref (resolver);
    return FALSE;
  }

socket_new_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Failed to create socket: %s", err->message));
    g_clear_error (&err);
    g_object_unref (saddr);
    return FALSE;
  }

socket_bind_failed:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled binding");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to bind on host '%s:%d': %s", src->host, src->server_port,
              err->message));
    }
    g_clear_error (&err);
    g_object_unref (saddr);
    gst_tcp_mix_src_stop (src, pad);
    return FALSE;
  }

socket_listen_failed:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled listening");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to listen on host '%s:%d': %s", src->host,
              src->server_port, err->message));
    }
    g_clear_error (&err);
    gst_tcp_mix_src_stop (src, pad);
    return FALSE;
  }
}
Esempio n. 14
0
/* set up server */
static gboolean
gst_tcp_server_src_start (GstBaseSrc * bsrc)
{
  GstTCPServerSrc *src = GST_TCP_SERVER_SRC (bsrc);
  GError *err = NULL;
  GInetAddress *addr;
  GSocketAddress *saddr;
  GResolver *resolver;

  /* look up name if we need to */
  addr = g_inet_address_new_from_string (src->host);
  if (!addr) {
    GList *results;

    resolver = g_resolver_get_default ();

    results =
        g_resolver_lookup_by_name (resolver, src->host, src->cancellable, &err);
    if (!results)
      goto name_resolve;
    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }
#ifndef GST_DISABLE_GST_DEBUG
  {
    gchar *ip = g_inet_address_to_string (addr);

    GST_DEBUG_OBJECT (src, "IP address for host %s is %s", src->host, ip);
    g_free (ip);
  }
#endif

  saddr = g_inet_socket_address_new (addr, src->server_port);
  g_object_unref (addr);

  /* create the server listener socket */
  src->server_socket =
      g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM,
      G_SOCKET_PROTOCOL_TCP, &err);
  if (!src->server_socket)
    goto no_socket;

  GST_DEBUG_OBJECT (src, "opened receiving server socket");

  /* bind it */
  GST_DEBUG_OBJECT (src, "binding server socket to address");
  if (!g_socket_bind (src->server_socket, saddr, TRUE, &err))
    goto bind_failed;

  g_object_unref (saddr);

  GST_DEBUG_OBJECT (src, "listening on server socket");

  g_socket_set_listen_backlog (src->server_socket, TCP_BACKLOG);

  if (!g_socket_listen (src->server_socket, &err))
    goto listen_failed;

  GST_OBJECT_FLAG_SET (src, GST_TCP_SERVER_SRC_OPEN);

  return TRUE;

  /* ERRORS */
no_socket:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Failed to create socket: %s", err->message));
    g_clear_error (&err);
    g_object_unref (saddr);
    return FALSE;
  }
name_resolve:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled name resolval");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to resolve host '%s': %s", src->host, err->message));
    }
    g_clear_error (&err);
    g_object_unref (resolver);
    return FALSE;
  }
bind_failed:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled binding");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to bind on host '%s:%d': %s", src->host, src->server_port,
              err->message));
    }
    g_clear_error (&err);
    g_object_unref (saddr);
    gst_tcp_server_src_stop (GST_BASE_SRC (src));
    return FALSE;
  }
listen_failed:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled listening");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to listen on host '%s:%d': %s", src->host, src->server_port,
              err->message));
    }
    g_clear_error (&err);
    gst_tcp_server_src_stop (GST_BASE_SRC (src));
    return FALSE;
  }
}
Esempio n. 15
0
/* create a socket for sending to remote machine */
static gboolean
gst_udpsrc_start (GstBaseSrc * bsrc)
{
  GstUDPSrc *src;
  GInetAddress *addr, *bind_addr;
  GSocketAddress *bind_saddr;
  GResolver *resolver;
  GError *err = NULL;

  src = GST_UDPSRC (bsrc);

  if (src->socket == NULL) {
    /* need to allocate a socket */
    GST_DEBUG_OBJECT (src, "allocating socket for %s:%d", src->host, src->port);

    addr = g_inet_address_new_from_string (src->host);
    if (!addr) {
      GList *results;

      GST_DEBUG_OBJECT (src, "resolving IP address for host %s", src->host);
      resolver = g_resolver_get_default ();
      results =
          g_resolver_lookup_by_name (resolver, src->host, src->cancellable,
          &err);
      if (!results)
        goto name_resolve;
      addr = G_INET_ADDRESS (g_object_ref (results->data));

      g_resolver_free_addresses (results);
      g_object_unref (resolver);
    }
#ifndef GST_DISABLE_GST_DEBUG
    {
      gchar *ip = g_inet_address_to_string (addr);

      GST_DEBUG_OBJECT (src, "IP address for host %s is %s", src->host, ip);
      g_free (ip);
    }
#endif

    if ((src->used_socket =
            g_socket_new (g_inet_address_get_family (addr),
                G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL)
      goto no_socket;

    src->external_socket = FALSE;

    GST_DEBUG_OBJECT (src, "got socket %p", src->used_socket);

    if (src->addr)
      g_object_unref (src->addr);
    src->addr =
        G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, src->port));

    GST_DEBUG_OBJECT (src, "binding on port %d", src->port);

    if (g_inet_address_get_is_multicast (addr))
      bind_addr = g_inet_address_new_any (g_inet_address_get_family (addr));
    else
      bind_addr = G_INET_ADDRESS (g_object_ref (addr));

    g_object_unref (addr);

    bind_saddr = g_inet_socket_address_new (bind_addr, src->port);
    g_object_unref (bind_addr);
    if (!g_socket_bind (src->used_socket, bind_saddr, src->reuse, &err))
      goto bind_error;

    g_object_unref (bind_saddr);
  } else {
    GST_DEBUG_OBJECT (src, "using provided socket %p", src->socket);
    /* we use the configured socket, try to get some info about it */
    src->used_socket = G_SOCKET (g_object_ref (src->socket));
    src->external_socket = TRUE;

    if (src->addr)
      g_object_unref (src->addr);
    src->addr =
        G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket,
            &err));
    if (!src->addr)
      goto getsockname_error;
  }

#if GLIB_CHECK_VERSION (2, 35, 7)
  {
    gint val = 0;

    if (src->buffer_size != 0) {
      GError *opt_err = NULL;

      GST_INFO_OBJECT (src, "setting udp buffer of %d bytes", src->buffer_size);
      /* set buffer size, Note that on Linux this is typically limited to a
       * maximum of around 100K. Also a minimum of 128 bytes is required on
       * Linux. */
      if (!g_socket_set_option (src->used_socket, SOL_SOCKET, SO_RCVBUF,
              src->buffer_size, &opt_err)) {
        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
            ("Could not create a buffer of requested %d bytes: %s",
                src->buffer_size, opt_err->message));
        g_error_free (opt_err);
        opt_err = NULL;
      }
    }

    /* read the value of the receive buffer. Note that on linux this returns
     * 2x the value we set because the kernel allocates extra memory for
     * metadata. The default on Linux is about 100K (which is about 50K
     * without metadata) */
    if (g_socket_get_option (src->used_socket, SOL_SOCKET, SO_RCVBUF, &val,
            NULL)) {
      GST_INFO_OBJECT (src, "have udp buffer of %d bytes", val);
    } else {
      GST_DEBUG_OBJECT (src, "could not get udp buffer size");
    }
  }
#elif defined (SO_RCVBUF)
  {
    gint rcvsize, ret;
    socklen_t len;

    len = sizeof (rcvsize);
    if (src->buffer_size != 0) {
      rcvsize = src->buffer_size;

      GST_DEBUG_OBJECT (src, "setting udp buffer of %d bytes", rcvsize);
      /* set buffer size, Note that on Linux this is typically limited to a
       * maximum of around 100K. Also a minimum of 128 bytes is required on
       * Linux. */
      ret =
          setsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF,
          (void *) &rcvsize, len);
      if (ret != 0) {
        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
            ("Could not create a buffer of requested %d bytes, %d: %s (%d)",
                rcvsize, ret, g_strerror (errno), errno));
      }
    }

    /* read the value of the receive buffer. Note that on linux this returns 2x the
     * value we set because the kernel allocates extra memory for metadata.
     * The default on Linux is about 100K (which is about 50K without metadata) */
    ret =
        getsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF,
        (void *) &rcvsize, &len);
    if (ret == 0)
      GST_DEBUG_OBJECT (src, "have udp buffer of %d bytes", rcvsize);
    else
      GST_DEBUG_OBJECT (src, "could not get udp buffer size");
  }
#else
  if (src->buffer_size != 0) {
    GST_WARNING_OBJECT (src, "don't know how to set udp buffer size on this "
        "OS. Consider upgrading your GLib to >= 2.35.7 and re-compiling the "
        "GStreamer udp plugin");
  }
#endif

  g_socket_set_broadcast (src->used_socket, TRUE);

  if (src->auto_multicast
      &&
      g_inet_address_get_is_multicast (g_inet_socket_address_get_address
          (src->addr))) {
    GST_DEBUG_OBJECT (src, "joining multicast group %s", src->host);
    if (!g_socket_join_multicast_group (src->used_socket,
            g_inet_socket_address_get_address (src->addr),
            FALSE, src->multi_iface, &err))
      goto membership;
  }

  /* NOTE: sockaddr_in.sin_port works for ipv4 and ipv6 because sin_port
   * follows ss_family on both */
  {
    GInetSocketAddress *addr;
    guint16 port;

    addr =
        G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket,
            &err));
    if (!addr)
      goto getsockname_error;

    port = g_inet_socket_address_get_port (addr);
    GST_DEBUG_OBJECT (src, "bound, on port %d", port);
    if (port != src->port) {
      src->port = port;
      GST_DEBUG_OBJECT (src, "notifying port %d", port);
      g_object_notify (G_OBJECT (src), "port");
    }
    g_object_unref (addr);
  }

  return TRUE;

  /* ERRORS */
name_resolve:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Name resolval failed: %s", err->message));
    g_clear_error (&err);
    g_object_unref (resolver);
    return FALSE;
  }
no_socket:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("no socket error: %s", err->message));
    g_clear_error (&err);
    g_object_unref (addr);
    return FALSE;
  }
bind_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("bind failed: %s", err->message));
    g_clear_error (&err);
    g_object_unref (bind_saddr);
    gst_udpsrc_stop (GST_BASE_SRC (src));
    return FALSE;
  }
membership:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("could add membership: %s", err->message));
    g_clear_error (&err);
    gst_udpsrc_stop (GST_BASE_SRC (src));
    return FALSE;
  }
getsockname_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("getsockname failed: %s", err->message));
    g_clear_error (&err);
    gst_udpsrc_stop (GST_BASE_SRC (src));
    return FALSE;
  }
}
Esempio n. 16
0
/* create a socket for sending to remote machine */
static gboolean
gst_multiudpsink_start (GstBaseSink * bsink)
{
  GstMultiUDPSink *sink;
  GList *clients;
  GstUDPClient *client;
  GError *err = NULL;

  sink = GST_MULTIUDPSINK (bsink);

  sink->external_socket = FALSE;

  if (sink->socket) {
    GST_DEBUG_OBJECT (sink, "using configured socket");
    if (g_socket_get_family (sink->socket) == G_SOCKET_FAMILY_IPV6) {
      sink->used_socket_v6 = G_SOCKET (g_object_ref (sink->socket));
      sink->external_socket = TRUE;
    } else {
      sink->used_socket = G_SOCKET (g_object_ref (sink->socket));
      sink->external_socket = TRUE;
    }
  }

  if (sink->socket_v6) {
    GST_DEBUG_OBJECT (sink, "using configured IPv6 socket");
    g_return_val_if_fail (g_socket_get_family (sink->socket) !=
        G_SOCKET_FAMILY_IPV6, FALSE);

    if (sink->used_socket_v6 && sink->used_socket_v6 != sink->socket_v6) {
      GST_ERROR_OBJECT (sink,
          "Provided different IPv6 sockets in socket and socket-v6 properties");
      return FALSE;
    }

    sink->used_socket_v6 = G_SOCKET (g_object_ref (sink->socket_v6));
    sink->external_socket = TRUE;
  }

  if (!sink->used_socket && !sink->used_socket_v6) {
    GSocketAddress *bind_addr;
    GInetAddress *bind_iaddr;

    if (sink->bind_address) {
      GSocketFamily family;

      bind_iaddr = g_inet_address_new_from_string (sink->bind_address);
      if (!bind_iaddr) {
        GList *results;
        GResolver *resolver;

        resolver = g_resolver_get_default ();
        results =
            g_resolver_lookup_by_name (resolver, sink->bind_address,
            sink->cancellable, &err);
        if (!results) {
          g_object_unref (resolver);
          goto name_resolve;
        }
        bind_iaddr = G_INET_ADDRESS (g_object_ref (results->data));
        g_resolver_free_addresses (results);
        g_object_unref (resolver);
      }

      bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port);
      g_object_unref (bind_iaddr);
      family = g_socket_address_get_family (G_SOCKET_ADDRESS (bind_addr));

      if ((sink->used_socket =
              g_socket_new (family, G_SOCKET_TYPE_DATAGRAM,
                  G_SOCKET_PROTOCOL_UDP, &err)) == NULL) {
        g_object_unref (bind_addr);
        goto no_socket;
      }

      g_socket_bind (sink->used_socket, bind_addr, TRUE, &err);
      if (err != NULL)
        goto bind_error;
    } else {
      /* create sender sockets if none available */
      if ((sink->used_socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
                  G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL)
        goto no_socket;

      bind_iaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
      bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port);
      g_socket_bind (sink->used_socket, bind_addr, TRUE, &err);
      g_object_unref (bind_addr);
      g_object_unref (bind_iaddr);
      if (err != NULL)
        goto bind_error;

      if ((sink->used_socket_v6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
                  G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP,
                  &err)) == NULL) {
        GST_INFO_OBJECT (sink, "Failed to create IPv6 socket: %s",
            err->message);
        g_clear_error (&err);
      } else {
        bind_iaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
        bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port);
        g_socket_bind (sink->used_socket_v6, bind_addr, TRUE, &err);
        g_object_unref (bind_addr);
        g_object_unref (bind_iaddr);
        if (err != NULL)
          goto bind_error;
      }
    }
  }
#ifdef SO_SNDBUF
  {
    socklen_t len;
    gint sndsize, ret;

    len = sizeof (sndsize);
    if (sink->buffer_size != 0) {
      sndsize = sink->buffer_size;

      GST_DEBUG_OBJECT (sink, "setting udp buffer of %d bytes", sndsize);
      /* set buffer size, Note that on Linux this is typically limited to a
       * maximum of around 100K. Also a minimum of 128 bytes is required on
       * Linux. */

      if (sink->used_socket) {
        ret =
            setsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET,
            SO_SNDBUF, (void *) &sndsize, len);
        if (ret != 0) {
          GST_ELEMENT_WARNING (sink, RESOURCE, SETTINGS, (NULL),
              ("Could not create a buffer of requested %d bytes, %d: %s",
                  sndsize, ret, g_strerror (errno)));
        }
      }

      if (sink->used_socket_v6) {
        ret =
            setsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET,
            SO_SNDBUF, (void *) &sndsize, len);
        if (ret != 0) {
          GST_ELEMENT_WARNING (sink, RESOURCE, SETTINGS, (NULL),
              ("Could not create a buffer of requested %d bytes, %d: %s",
                  sndsize, ret, g_strerror (errno)));
        }
      }
    }

    /* read the value of the receive buffer. Note that on linux this returns 2x the
     * value we set because the kernel allocates extra memory for metadata.
     * The default on Linux is about 100K (which is about 50K without metadata) */
    if (sink->used_socket) {
      ret =
          getsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET,
          SO_SNDBUF, (void *) &sndsize, &len);
      if (ret == 0)
        GST_DEBUG_OBJECT (sink, "have UDP buffer of %d bytes", sndsize);
      else
        GST_DEBUG_OBJECT (sink, "could not get UDP buffer size");
    }

    if (sink->used_socket_v6) {
      ret =
          getsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET,
          SO_SNDBUF, (void *) &sndsize, &len);
      if (ret == 0)
        GST_DEBUG_OBJECT (sink, "have UDPv6 buffer of %d bytes", sndsize);
      else
        GST_DEBUG_OBJECT (sink, "could not get UDPv6 buffer size");
    }
  }
#endif

#ifdef SO_BINDTODEVICE
  if (sink->multi_iface) {
    if (sink->used_socket) {
      setsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET,
          SO_BINDTODEVICE, sink->multi_iface, strlen (sink->multi_iface));
    }
    if (sink->used_socket_v6) {
      setsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET,
          SO_BINDTODEVICE, sink->multi_iface, strlen (sink->multi_iface));
    }
  }
#endif

  if (sink->used_socket)
    g_socket_set_broadcast (sink->used_socket, TRUE);
  if (sink->used_socket_v6)
    g_socket_set_broadcast (sink->used_socket_v6, TRUE);

  sink->bytes_to_serve = 0;
  sink->bytes_served = 0;

  gst_multiudpsink_setup_qos_dscp (sink, sink->used_socket);
  gst_multiudpsink_setup_qos_dscp (sink, sink->used_socket_v6);

  /* look for multicast clients and join multicast groups appropriately
     set also ttl and multicast loopback delivery appropriately  */
  for (clients = sink->clients; clients; clients = g_list_next (clients)) {
    client = (GstUDPClient *) clients->data;

    if (!gst_multiudpsink_configure_client (sink, client))
      return FALSE;
  }
  return TRUE;

  /* ERRORS */
no_socket:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL),
        ("Could not create socket: %s", err->message));
    g_clear_error (&err);
    return FALSE;
  }
bind_error:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL),
        ("Failed to bind socket: %s", err->message));
    g_clear_error (&err);
    return FALSE;
  }
name_resolve:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL),
        ("Failed to resolve bind address %s: %s", sink->bind_address,
            err->message));
    g_clear_error (&err);
    return FALSE;
  }
}
static gboolean
gst_net_client_internal_clock_start (GstNetClientInternalClock * self)
{
  GSocketAddress *servaddr;
  GSocketAddress *myaddr;
  GSocketAddress *anyaddr;
  GInetAddress *inetaddr;
  GSocket *socket;
  GError *error = NULL;
  GSocketFamily family;
  GPollFD dummy_pollfd;
  GResolver *resolver = NULL;
  GError *err = NULL;

  g_return_val_if_fail (self->address != NULL, FALSE);
  g_return_val_if_fail (self->servaddr == NULL, FALSE);

  /* create target address */
  inetaddr = g_inet_address_new_from_string (self->address);
  if (inetaddr == NULL) {
    GList *results;

    resolver = g_resolver_get_default ();

    results = g_resolver_lookup_by_name (resolver, self->address, NULL, &err);
    if (!results)
      goto failed_to_resolve;

    inetaddr = G_INET_ADDRESS (g_object_ref (results->data));
    g_resolver_free_addresses (results);
    g_object_unref (resolver);
  }

  family = g_inet_address_get_family (inetaddr);

  servaddr = g_inet_socket_address_new (inetaddr, self->port);
  g_object_unref (inetaddr);

  g_assert (servaddr != NULL);

  GST_DEBUG_OBJECT (self, "will communicate with %s:%d", self->address,
      self->port);

  socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM,
      G_SOCKET_PROTOCOL_UDP, &error);

  if (socket == NULL)
    goto no_socket;

  GST_DEBUG_OBJECT (self, "binding socket");
  inetaddr = g_inet_address_new_any (family);
  anyaddr = g_inet_socket_address_new (inetaddr, 0);
  g_socket_bind (socket, anyaddr, TRUE, &error);
  g_object_unref (anyaddr);
  g_object_unref (inetaddr);

  if (error != NULL)
    goto bind_error;

  /* check address we're bound to, mostly for debugging purposes */
  myaddr = g_socket_get_local_address (socket, &error);

  if (myaddr == NULL)
    goto getsockname_error;

  GST_DEBUG_OBJECT (self, "socket opened on UDP port %d",
      g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (myaddr)));

  g_object_unref (myaddr);

  self->cancel = g_cancellable_new ();
  self->made_cancel_fd =
      g_cancellable_make_pollfd (self->cancel, &dummy_pollfd);

  self->socket = socket;
  self->servaddr = G_SOCKET_ADDRESS (servaddr);

  self->thread = g_thread_try_new ("GstNetClientInternalClock",
      gst_net_client_internal_clock_thread, self, &error);

  if (error != NULL)
    goto no_thread;

  return TRUE;

  /* ERRORS */
no_socket:
  {
    GST_ERROR_OBJECT (self, "socket_new() failed: %s", error->message);
    g_error_free (error);
    return FALSE;
  }
bind_error:
  {
    GST_ERROR_OBJECT (self, "bind failed: %s", error->message);
    g_error_free (error);
    g_object_unref (socket);
    return FALSE;
  }
getsockname_error:
  {
    GST_ERROR_OBJECT (self, "get_local_address() failed: %s", error->message);
    g_error_free (error);
    g_object_unref (socket);
    return FALSE;
  }
failed_to_resolve:
  {
    GST_ERROR_OBJECT (self, "resolving '%s' failed: %s",
        self->address, err->message);
    g_clear_error (&err);
    g_object_unref (resolver);
    return FALSE;
  }
no_thread:
  {
    GST_ERROR_OBJECT (self, "could not create thread: %s", error->message);
    g_object_unref (self->servaddr);
    self->servaddr = NULL;
    g_object_unref (self->socket);
    self->socket = NULL;
    g_error_free (error);
    return FALSE;
  }
}
Esempio n. 18
0
/* create a socket for sending to remote machine */
static gboolean
gst_udpsrc_open (GstUDPSrc * src)
{
  GInetAddress *addr, *bind_addr;
  GSocketAddress *bind_saddr;
  GError *err = NULL;

  gst_udpsrc_create_cancellable (src);

  if (src->socket == NULL) {
    /* need to allocate a socket */
    GST_DEBUG_OBJECT (src, "allocating socket for %s:%d", src->address,
        src->port);

    addr = gst_udpsrc_resolve (src, src->address);
    if (!addr)
      goto name_resolve;

    if ((src->used_socket =
            g_socket_new (g_inet_address_get_family (addr),
                G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL)
      goto no_socket;

    src->external_socket = FALSE;

    GST_DEBUG_OBJECT (src, "got socket %p", src->used_socket);

    if (src->addr)
      g_object_unref (src->addr);
    src->addr =
        G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, src->port));

    GST_DEBUG_OBJECT (src, "binding on port %d", src->port);

    /* On Windows it's not possible to bind to a multicast address
     * but the OS will make sure to filter out all packets that
     * arrive not for the multicast address the socket joined.
     *
     * On Linux and others it is necessary to bind to a multicast
     * address to let the OS filter out all packets that are received
     * on the same port but for different addresses than the multicast
     * address
     */
#ifdef G_OS_WIN32
    if (g_inet_address_get_is_multicast (addr))
      bind_addr = g_inet_address_new_any (g_inet_address_get_family (addr));
    else
#endif
      bind_addr = G_INET_ADDRESS (g_object_ref (addr));

    g_object_unref (addr);

    bind_saddr = g_inet_socket_address_new (bind_addr, src->port);
    g_object_unref (bind_addr);
    if (!g_socket_bind (src->used_socket, bind_saddr, src->reuse, &err))
      goto bind_error;

    g_object_unref (bind_saddr);
    g_socket_set_multicast_loopback (src->used_socket, src->loop);
  } else {
    GInetSocketAddress *local_addr;

    GST_DEBUG_OBJECT (src, "using provided socket %p", src->socket);
    /* we use the configured socket, try to get some info about it */
    src->used_socket = G_SOCKET (g_object_ref (src->socket));
    src->external_socket = TRUE;

    local_addr =
        G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket,
            &err));
    if (!local_addr)
      goto getsockname_error;

    /* See above for the reasons. Without this we would behave different on
     * Windows and Linux, joining multicast groups below for provided sockets
     * on Linux but not on Windows
     */
#ifdef G_OS_WIN32
    addr = gst_udpsrc_resolve (src, src->address);
    if (!addr)
      goto name_resolve;

    if (!src->auto_multicast ||
        !g_inet_address_get_is_any (g_inet_socket_address_get_address
            (local_addr))
        || !g_inet_address_get_is_multicast (addr)) {
      g_object_unref (addr);
#endif
      if (src->addr)
        g_object_unref (src->addr);
      src->addr = local_addr;
#ifdef G_OS_WIN32
    } else {
      g_object_unref (local_addr);
      if (src->addr)
        g_object_unref (src->addr);
      src->addr =
          G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, src->port));
      g_object_unref (addr);
    }
#endif
  }

  {
    gint val = 0;

    if (src->buffer_size != 0) {
      GError *opt_err = NULL;

      GST_INFO_OBJECT (src, "setting udp buffer of %d bytes", src->buffer_size);
      /* set buffer size, Note that on Linux this is typically limited to a
       * maximum of around 100K. Also a minimum of 128 bytes is required on
       * Linux. */
      if (!g_socket_set_option (src->used_socket, SOL_SOCKET, SO_RCVBUF,
              src->buffer_size, &opt_err)) {
        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
            ("Could not create a buffer of requested %d bytes: %s",
                src->buffer_size, opt_err->message));
        g_error_free (opt_err);
        opt_err = NULL;
      }
    }

    /* read the value of the receive buffer. Note that on linux this returns
     * 2x the value we set because the kernel allocates extra memory for
     * metadata. The default on Linux is about 100K (which is about 50K
     * without metadata) */
    if (g_socket_get_option (src->used_socket, SOL_SOCKET, SO_RCVBUF, &val,
            NULL)) {
      GST_INFO_OBJECT (src, "have udp buffer of %d bytes", val);
    } else {
      GST_DEBUG_OBJECT (src, "could not get udp buffer size");
    }
  }

  g_socket_set_broadcast (src->used_socket, TRUE);

  if (src->auto_multicast
      &&
      g_inet_address_get_is_multicast (g_inet_socket_address_get_address
          (src->addr))) {
    GST_DEBUG_OBJECT (src, "joining multicast group %s", src->address);
    if (!g_socket_join_multicast_group (src->used_socket,
            g_inet_socket_address_get_address (src->addr),
            FALSE, src->multi_iface, &err))
      goto membership;
  }

  /* NOTE: sockaddr_in.sin_port works for ipv4 and ipv6 because sin_port
   * follows ss_family on both */
  {
    GInetSocketAddress *addr;
    guint16 port;

    addr =
        G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket,
            &err));
    if (!addr)
      goto getsockname_error;

    port = g_inet_socket_address_get_port (addr);
    GST_DEBUG_OBJECT (src, "bound, on port %d", port);
    if (port != src->port) {
      src->port = port;
      GST_DEBUG_OBJECT (src, "notifying port %d", port);
      g_object_notify (G_OBJECT (src), "port");
    }
    g_object_unref (addr);
  }

  src->allocator = NULL;
  gst_allocation_params_init (&src->params);

  src->max_size = 0;

  return TRUE;

  /* ERRORS */
name_resolve:
  {
    return FALSE;
  }
no_socket:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("no socket error: %s", err->message));
    g_clear_error (&err);
    g_object_unref (addr);
    return FALSE;
  }
bind_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("bind failed: %s", err->message));
    g_clear_error (&err);
    g_object_unref (bind_saddr);
    gst_udpsrc_close (src);
    return FALSE;
  }
membership:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("could add membership: %s", err->message));
    g_clear_error (&err);
    gst_udpsrc_close (src);
    return FALSE;
  }
getsockname_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("getsockname failed: %s", err->message));
    g_clear_error (&err);
    gst_udpsrc_close (src);
    return FALSE;
  }
}
Esempio n. 19
0
static void
return_result (GTask *task)
{
  GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
  GSocketAddress *result;

  if (strcmp ("direct", priv->proxy_type) == 0)
    {
      result = priv->proxy_address;
      priv->proxy_address = NULL;
    }
  else
    {
      gchar *dest_hostname, *dest_protocol;
      GInetSocketAddress *inetsaddr;
      GInetAddress *inetaddr;
      guint16 port;

      if (!priv->supports_hostname)
	{
	  GInetAddress *dest_ip;

	  if (!priv->next_dest_ip)
	    priv->next_dest_ip = priv->dest_ips;

	  dest_ip = G_INET_ADDRESS (priv->next_dest_ip->data);
	  dest_hostname = g_inet_address_to_string (dest_ip);

	  priv->next_dest_ip = g_list_next (priv->next_dest_ip);
	}
      else
	{
	  dest_hostname = g_strdup (priv->dest_hostname);
	}
      dest_protocol = g_uri_parse_scheme (priv->dest_uri);

      g_return_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address));

      inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
      inetaddr = g_inet_socket_address_get_address (inetsaddr);
      port = g_inet_socket_address_get_port (inetsaddr);

      result = g_object_new (G_TYPE_PROXY_ADDRESS,
			     "address", inetaddr,
			     "port", port,
			     "protocol", priv->proxy_type,
			     "destination-protocol", dest_protocol,
			     "destination-hostname", dest_hostname,
			     "destination-port", priv->dest_port,
			     "username", priv->proxy_username,
			     "password", priv->proxy_password,
			     "uri", priv->proxy_uri,
			     NULL);
      g_free (dest_hostname);
      g_free (dest_protocol);

      if (priv->supports_hostname || priv->next_dest_ip == NULL)
	{
	  g_object_unref (priv->proxy_address);
	  priv->proxy_address = NULL;
	}
    }

  g_task_return_pointer (task, result, g_object_unref);
  g_object_unref (task);
}
Esempio n. 20
0
static GSocketAddress *
g_proxy_address_enumerator_next (GSocketAddressEnumerator  *enumerator,
				 GCancellable              *cancellable,
				 GError                   **error)
{
  GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator);
  GSocketAddress *result = NULL;
  GError *first_error = NULL;

  if (priv->proxies == NULL)
    {
      GProxyResolver *resolver = g_proxy_resolver_get_default ();
      priv->proxies = g_proxy_resolver_lookup (resolver,
					       priv->dest_uri,
					       cancellable,
					       error);
      priv->next_proxy = priv->proxies;

      if (priv->proxies == NULL)
	return NULL;
    }

  while (result == NULL && (*priv->next_proxy || priv->addr_enum))
    {
      gchar *dest_hostname;
      gchar *dest_protocol;
      GInetSocketAddress *inetsaddr;
      GInetAddress *inetaddr;
      guint16 port;

      next_enumerator (priv);

      if (!priv->addr_enum)
	continue;

      if (priv->proxy_address == NULL)
	{
	  priv->proxy_address = g_socket_address_enumerator_next (
				    priv->addr_enum,
				    cancellable,
				    first_error ? NULL : &first_error);
	}

      if (priv->proxy_address == NULL)
	{
	  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;
	    }

	  continue;
	}

      if (strcmp ("direct", priv->proxy_type) == 0)
	{
	  result = priv->proxy_address;
	  priv->proxy_address = NULL;
	  continue;
	}

      if (!priv->supports_hostname)
	{
	  GInetAddress *dest_ip;

	  if (!priv->dest_ips)
	    {
	      GResolver *resolver;

	      resolver = g_resolver_get_default();
	      priv->dest_ips = g_resolver_lookup_by_name (resolver,
							  priv->dest_hostname,
							  cancellable,
							  first_error ? NULL : &first_error);
	      g_object_unref (resolver);

	      if (!priv->dest_ips)
		{
		  g_object_unref (priv->proxy_address);
		  priv->proxy_address = NULL;
		  continue;
		}
	    }

	  if (!priv->next_dest_ip)
	    priv->next_dest_ip = priv->dest_ips;
	
	  dest_ip = G_INET_ADDRESS (priv->next_dest_ip->data);
	  dest_hostname = g_inet_address_to_string (dest_ip);

	  priv->next_dest_ip = g_list_next (priv->next_dest_ip);
	}
      else
	{
	  dest_hostname = g_strdup (priv->dest_hostname);
	}
      dest_protocol = g_uri_parse_scheme (priv->dest_uri);
		 		  
      g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address),
			    NULL);

      inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
      inetaddr = g_inet_socket_address_get_address (inetsaddr);
      port = g_inet_socket_address_get_port (inetsaddr);

      result = g_object_new (G_TYPE_PROXY_ADDRESS,
			     "address", inetaddr,
			     "port", port,
			     "protocol", priv->proxy_type,
			     "destination-protocol", dest_protocol,
			     "destination-hostname", dest_hostname,
			     "destination-port", priv->dest_port,
			     "username", priv->proxy_username,
			     "password", priv->proxy_password,
			     "uri", priv->proxy_uri,
			     NULL);
      g_free (dest_hostname);
      g_free (dest_protocol);

      if (priv->supports_hostname || priv->next_dest_ip == NULL)
	{
	  g_object_unref (priv->proxy_address);
	  priv->proxy_address = NULL;
	}
    }

  if (result == NULL && first_error)
    g_propagate_error (error, first_error);
  else if (first_error)
    g_error_free (first_error);

  return result;
}