Пример #1
0
static ArvGvDiscoverSocketList *
arv_gv_discover_socket_list_new (void)
{
	ArvGvDiscoverSocketList *socket_list;
	GInetAddress *broadcast_address;
	GSList *iter;
	const char *envar;
	struct ifaddrs *ifap  = NULL;
	struct ifaddrs *ifap_iter;
	int i;

	socket_list = g_new0 (ArvGvDiscoverSocketList, 1);

	if (getifaddrs (&ifap) < 0)
		return socket_list;

	broadcast_address = g_inet_address_new_from_string ("255.255.255.255");

	for (ifap_iter = ifap; ifap_iter != NULL; ifap_iter = ifap_iter->ifa_next) {
		if ((ifap_iter->ifa_flags & IFF_UP) != 0 &&
		    (ifap_iter->ifa_flags & IFF_POINTOPOINT) == 0 &&
		    (ifap_iter->ifa_addr != NULL) &&
		    (ifap_iter->ifa_addr->sa_family == AF_INET)) {
			ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
			GSocketAddress *socket_address;
			GInetAddress *inet_address;
			char *inet_address_string;
			GError *error = NULL;

			socket_address = g_socket_address_new_from_native (ifap_iter->ifa_addr,
									   sizeof (struct sockaddr));
			inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
			inet_address_string = g_inet_address_to_string (inet_address);
			arv_debug_interface ("[GvDiscoverSocket::new] Add interface %s", inet_address_string);
			g_free (inet_address_string);
			discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0);
			g_object_unref (socket_address);

			discover_socket->target_address = g_inet_socket_address_new (broadcast_address, ARV_GVCP_PORT);

			discover_socket->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
								G_SOCKET_TYPE_DATAGRAM,
								G_SOCKET_PROTOCOL_UDP, NULL);
			g_socket_bind (discover_socket->socket, discover_socket->interface_address, TRUE, &error);

			socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket);
			socket_list->n_sockets++;
		}
	}

	g_object_unref (broadcast_address);
	freeifaddrs (ifap);

	if ((envar=g_getenv("ARV_IPS"))!=NULL) {
		gchar **ips_alloc, **ips, *addr;

		ips_alloc = ips = g_strsplit(envar, ":", -1);

		for (addr = *ips; addr; addr = *++ips) {
			ArvGvDiscoverSocket *discover_socket;
			GSocketAddress *target_addr = g_inet_socket_address_new_from_string(addr, ARV_GVCP_PORT);
			if(!target_addr)
				continue;

			discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
			discover_socket->target_address = target_addr;
			discover_socket->interface_address = g_inet_socket_address_new_from_string("0.0.0.0", ARV_GVCP_PORT); /* TODO, wrong */

			discover_socket->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
								G_SOCKET_TYPE_DATAGRAM,
								G_SOCKET_PROTOCOL_UDP, NULL);
			/* implict bind of wildcard w/ arbitrary port */

			arv_debug_interface("[GvDiscoverSocket::new] Add unicast destination %s", addr);

			socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket);
			socket_list->n_sockets++;
		}

		g_strfreev(ips_alloc);
	}

	socket_list->poll_fds = g_new (GPollFD, socket_list->n_sockets);
	for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) {
		ArvGvDiscoverSocket *discover_socket = iter->data;

		socket_list->poll_fds[i].fd = g_socket_get_fd (discover_socket->socket);
		socket_list->poll_fds[i].events =  G_IO_IN;
		socket_list->poll_fds[i].revents = 0;
	}

	return socket_list;
}
static gboolean
run_server (guint * http_port, guint * https_port)
{
  guint port = SOUP_ADDRESS_ANY_PORT;
  guint ssl_port = SOUP_ADDRESS_ANY_PORT;
  const char *ssl_cert_file = GST_TEST_FILES_PATH "/test-cert.pem";
  const char *ssl_key_file = GST_TEST_FILES_PATH "/test-key.pem";
  static int server_running = 0;
  GSocketAddress *address;
  GError *err = NULL;

  SoupAuthDomain *domain = NULL;

  if (server_running)
    return TRUE;

  server_running = 1;

  *http_port = *https_port = 0;

  server = soup_server_new (NULL, NULL);
  if (!server) {
    GST_DEBUG ("Unable to create server");
    return FALSE;
  }
  soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
  domain = soup_auth_domain_basic_new (SOUP_AUTH_DOMAIN_REALM, realm,
      SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, basic_auth_cb,
      SOUP_AUTH_DOMAIN_ADD_PATH, basic_auth_path, NULL);
  soup_server_add_auth_domain (server, domain);
  g_object_unref (domain);
  domain = soup_auth_domain_digest_new (SOUP_AUTH_DOMAIN_REALM, realm,
      SOUP_AUTH_DOMAIN_DIGEST_AUTH_CALLBACK, digest_auth_cb,
      SOUP_AUTH_DOMAIN_ADD_PATH, digest_auth_path, NULL);
  soup_server_add_auth_domain (server, domain);
  g_object_unref (domain);

  address = g_inet_socket_address_new_from_string ("0.0.0.0", port);
  soup_server_listen (server, address, 0, &err);
  g_object_unref (address);
  if (err) {
    stop_server ();
    g_clear_error (&err);
    return FALSE;
  }

  *http_port = get_port_from_server (server);
  GST_DEBUG ("HTTP server listening on port %u", *http_port);

  if (ssl_cert_file && ssl_key_file) {
    GTlsBackend *backend = g_tls_backend_get_default ();

    if (backend != NULL && g_tls_backend_supports_tls (backend)) {
      ssl_server = soup_server_new (SOUP_SERVER_SSL_CERT_FILE, ssl_cert_file,
          SOUP_SERVER_SSL_KEY_FILE, ssl_key_file, NULL);
    } else {
      GST_INFO ("No TLS support");
    }

    if (ssl_server) {
      GST_INFO ("HTTPS server listening on port %u", *https_port);
      soup_server_add_handler (ssl_server, NULL, server_callback, NULL, NULL);
      address = g_inet_socket_address_new_from_string ("0.0.0.0", ssl_port);
      soup_server_listen (ssl_server, address, SOUP_SERVER_LISTEN_HTTPS, &err);
      g_object_unref (address);

      if (err) {
        GST_ERROR ("Failed to start HTTPS server: %s", err->message);
        stop_server ();
        g_clear_error (&err);
        return FALSE;
      }

      *https_port = get_port_from_server (ssl_server);
      GST_DEBUG ("HTTPS server listening on port %u", *https_port);
    }
  }

  /* check if we can connect to our local http server */
  {
    GSocketConnection *conn;
    GSocketClient *client;

    client = g_socket_client_new ();
    g_socket_client_set_timeout (client, 2);
    conn = g_socket_client_connect_to_host (client, "127.0.0.1", *http_port,
        NULL, NULL);
    if (conn == NULL) {
      GST_INFO ("Couldn't connect to http server 127.0.0.1:%u", *http_port);
      g_object_unref (client);
      stop_server ();
      return FALSE;
    }
    g_object_unref (conn);

    if (ssl_server == NULL)
      goto skip_https_check;

    conn = g_socket_client_connect_to_host (client, "127.0.0.1", *https_port,
        NULL, NULL);
    if (conn == NULL) {
      GST_INFO ("Couldn't connect to https server 127.0.0.1:%u", *https_port);
      g_object_unref (client);
      stop_server ();
      return FALSE;
    }
    g_object_unref (conn);

  skip_https_check:

    g_object_unref (client);
  }

  return TRUE;
}