gboolean _g_inet_socket_address_is_equal (GInetSocketAddress *a, GInetSocketAddress *b) { GInetAddress *a_addr; GInetAddress *b_addr; char *a_str; char *b_str; gboolean result; if (!G_IS_INET_SOCKET_ADDRESS (a) || !G_IS_INET_SOCKET_ADDRESS (b)) return FALSE; if (g_inet_socket_address_get_port (a) != g_inet_socket_address_get_port (b)) return FALSE; a_addr = g_inet_socket_address_get_address (a); b_addr = g_inet_socket_address_get_address (b); a_str = g_inet_address_to_string (a_addr); b_str = g_inet_address_to_string (b_addr); /* TODO: find a better way to do inet address comparison */ result = g_strcmp0 (a_str, b_str) == 0; g_free (a_str); g_free (b_str); return result; }
static void print_connectable_sockaddr (GSocketAddress *sockaddr, GError *error) { char *phys; if (error) { printf ("Error: %s\n", error->message); g_error_free (error); } else if (!G_IS_INET_SOCKET_ADDRESS (sockaddr)) { printf ("Error: Unexpected sockaddr type '%s'\n", g_type_name_from_instance ((GTypeInstance *)sockaddr)); g_object_unref (sockaddr); } else { GInetSocketAddress *isa = G_INET_SOCKET_ADDRESS (sockaddr); phys = g_inet_address_to_string (g_inet_socket_address_get_address (isa)); printf ("Address: %s%s%s:%d\n", strchr (phys, ':') ? "[" : "", phys, strchr (phys, ':') ? "]" : "", g_inet_socket_address_get_port (isa)); g_free (phys); g_object_unref (sockaddr); } }
static char * socket_address_to_string (GSocketAddress *address) { char *res = NULL; if (G_IS_INET_SOCKET_ADDRESS (address)) { GInetAddress *inet_address; char *str; int port; inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)); str = g_inet_address_to_string (inet_address); port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); res = g_strdup_printf ("%s:%d", str, port); g_free (str); } #ifdef G_OS_UNIX else if (G_IS_UNIX_SOCKET_ADDRESS (address)) { GUnixSocketAddress *uaddr = G_UNIX_SOCKET_ADDRESS (address); res = g_strdup_printf ("%s:%s", unix_socket_address_types[g_unix_socket_address_get_address_type (uaddr)], g_unix_socket_address_get_path (uaddr)); } #endif return res; }
/** * replay_network_server_load_file: * @self: A #ReplayNetworkServer * @conn: The #GSocketConnection to load events from * */ void replay_network_server_load_events(ReplayNetworkServer *self, GSocketConnection *conn) { GError *error = NULL; GSocketAddress *address; GInetAddress *inet; guint16 port; gchar *inet_str; gchar *description; g_return_if_fail(REPLAY_IS_NETWORK_SERVER(self)); REPLAY_NETWORK_SERVER_GET_CLASS(self)->load_events(self, conn); /* set description to the remote address and port */ address = g_socket_connection_get_remote_address(conn, &error); if (address) { inet = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(address)); port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(address)); inet_str = g_inet_address_to_string(inet); description = g_strdup_printf("Remote client %s, port %d", inet_str, port); replay_event_source_set_description(REPLAY_EVENT_SOURCE(self), description); g_free(description); g_free(inet_str); g_object_unref(address); } else { g_assert(error); replay_event_source_set_description(REPLAY_EVENT_SOURCE(self), error->message); g_clear_error(&error); } }
gboolean __g_socket_address_equal (GSocketAddress * a, GSocketAddress * b) { GInetSocketAddress *ia, *ib; GInetAddress *iaa, *iab; ia = G_INET_SOCKET_ADDRESS (a); ib = G_INET_SOCKET_ADDRESS (b); if (g_inet_socket_address_get_port (ia) != g_inet_socket_address_get_port (ib)) return FALSE; iaa = g_inet_socket_address_get_address (ia); iab = g_inet_socket_address_get_address (ib); return g_inet_address_equal (iaa, iab); }
GStrv _client_create_exec_args (GSocket *socket, const gchar *contact_id, const gchar *username, gchar **ssh_opts) { GPtrArray *args; GSocketAddress *socket_address; GInetAddress *inet_address; guint16 port; gchar *host; gchar *str; gchar **opt; /* Get the local host and port on which sshd is running */ socket_address = g_socket_get_local_address (socket, NULL); inet_address = g_inet_socket_address_get_address ( G_INET_SOCKET_ADDRESS (socket_address)); port = g_inet_socket_address_get_port ( G_INET_SOCKET_ADDRESS (socket_address)); host = g_inet_address_to_string (inet_address); /* Create ssh client args */ args = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (args, g_strdup ("ssh")); g_ptr_array_add (args, host); g_ptr_array_add (args, g_strdup ("-p")); str = g_strdup_printf ("%d", port); g_ptr_array_add (args, str); if (contact_id != NULL) { str = g_strdup_printf ("-oHostKeyAlias=%s", contact_id); g_ptr_array_add (args, str); } if (!tp_str_empty (username)) { g_ptr_array_add (args, g_strdup ("-l")); g_ptr_array_add (args, g_strdup (username)); } if (ssh_opts != NULL) { for (opt = ssh_opts; *opt != NULL; opt++) { g_ptr_array_add (args, g_strdup (*opt)); } } g_ptr_array_add (args, NULL); return (gchar **) g_ptr_array_free (args, FALSE); }
static void process_one_address (NewConnectionData *data) { GInetSocketAddress *addr; gchar *host; if (g_cancellable_is_cancelled (data->cancellable)) { g_simple_async_result_set_error (data->simple, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Operation cancelled"); g_simple_async_result_complete (data->simple); free_new_connection_data (data); return; } addr = g_queue_pop_head (data->addresses); /* check we haven't gotten to the end of the list */ if (addr == NULL) { g_simple_async_result_set_error (data->simple, WOCKY_LL_CONNECTION_FACTORY_ERROR, WOCKY_LL_CONNECTION_FACTORY_ERROR_NO_CONTACT_ADDRESS_CAN_BE_CONNECTED_TO, "Failed to connect to any of the contact's addresses"); g_simple_async_result_complete (data->simple); free_new_connection_data (data); return; } host = g_inet_address_to_string (g_inet_socket_address_get_address (addr)); DEBUG ("connecting to %s (port %" G_GUINT16_FORMAT ")", host, g_inet_socket_address_get_port (addr)); g_socket_client_connect_to_host_async (data->self->priv->client, host, g_inet_socket_address_get_port (addr), data->cancellable, connect_to_host_cb, data); g_free (host); g_object_unref (addr); }
static gboolean sig_match_conn (TpStreamTubeChannel *self, SigWaitingConn *sig, ConnWaitingSig *c) { if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_PORT) { /* Use the port to identify the connection */ guint port; GSocketAddress *address; GError *error = NULL; address = g_socket_connection_get_remote_address (c->conn, &error); if (address == NULL) { DEBUG ("Failed to get connection address: %s", error->message); g_error_free (error); return FALSE; } dbus_g_type_struct_get (sig->param, 1, &port, G_MAXINT); if (port == g_inet_socket_address_get_port ( G_INET_SOCKET_ADDRESS (address))) { DEBUG ("Identified connection %u using port %u", port, sig->connection_id); g_object_unref (address); return TRUE; } g_object_unref (address); } else if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_CREDENTIALS) { guchar byte; byte = g_value_get_uchar (sig->param); return byte == c->byte; } else { DEBUG ("Can't properly identify connection as we are using " "access control %u. Assume it's the head of the list", self->priv->access_control); return TRUE; } return FALSE; }
guint16 arv_gv_stream_get_port (ArvGvStream *gv_stream) { GInetSocketAddress *local_address; guint16 port; g_return_val_if_fail (ARV_IS_GV_STREAM (gv_stream), 0); local_address = G_INET_SOCKET_ADDRESS (g_socket_get_local_address (gv_stream->socket, NULL)); port = g_inet_socket_address_get_port (local_address); g_object_unref (local_address); return port; }
static char * socket_address_to_string (GSocketAddress *address) { GInetAddress *inet_address; char *str, *res; int port; inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)); str = g_inet_address_to_string (inet_address); port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); res = g_strdup_printf ("%s:%d", str, port); g_free (str); return res; }
gchar * __g_socket_address_to_string (GSocketAddress * addr) { GInetSocketAddress *ia; gchar *ret, *tmp; ia = G_INET_SOCKET_ADDRESS (addr); tmp = g_inet_address_to_string (g_inet_socket_address_get_address (ia)); ret = g_strdup_printf ("%s:%u", tmp, g_inet_socket_address_get_port (ia)); g_free (tmp); return ret; }
static gboolean on_new_connection (GSocketService * service, GSocketConnection * connection, GObject * source_object, gpointer user_data) { Client *client = g_slice_new0 (Client); GSocketAddress *addr; GInetAddress *iaddr; gchar *ip; guint16 port; addr = g_socket_connection_get_remote_address (connection, NULL); iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr)); port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)); ip = g_inet_address_to_string (iaddr); client->name = g_strdup_printf ("%s:%u", ip, port); g_free (ip); g_object_unref (addr); g_print ("New connection %s\n", client->name); client->connection = (GSocketConnection *) g_object_ref (connection); client->socket = g_socket_connection_get_socket (connection); client->istream = g_io_stream_get_input_stream (G_IO_STREAM (client->connection)); client->ostream = g_io_stream_get_output_stream (G_IO_STREAM (client->connection)); client->current_message = g_byte_array_sized_new (1024); client->tosource = g_timeout_source_new_seconds (5); g_source_set_callback (client->tosource, (GSourceFunc) on_timeout, client, NULL); g_source_attach (client->tosource, NULL); client->isource = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (client->istream), NULL); g_source_set_callback (client->isource, (GSourceFunc) on_read_bytes, client, NULL); g_source_attach (client->isource, NULL); G_LOCK (clients); clients = g_list_prepend (clients, client); G_UNLOCK (clients); return TRUE; }
int kms_sctp_connection_get_bound_port (KmsSCTPConnection * conn) { GSocketAddress *addr; gint bound_port = -1; g_return_val_if_fail (conn != NULL, bound_port); addr = g_socket_get_local_address (conn->socket, NULL); if (addr != NULL) { bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) addr); g_object_unref (addr); } return bound_port; }
static void g_tls_client_connection_gnutls_constructed (GObject *object) { GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (object); GSocketConnection *base_conn; GSocketAddress *remote_addr; GInetAddress *iaddr; guint port; /* Create a TLS session ID. We base it on the IP address since * different hosts serving the same hostname/service will probably * not share the same session cache. We base it on the * server-identity because at least some servers will fail (rather * than just failing to resume the session) if we don't. * (https://bugs.launchpad.net/bugs/823325) */ g_object_get (G_OBJECT (gnutls), "base-io-stream", &base_conn, NULL); if (G_IS_SOCKET_CONNECTION (base_conn)) { remote_addr = g_socket_connection_get_remote_address (base_conn, NULL); if (G_IS_INET_SOCKET_ADDRESS (remote_addr)) { GInetSocketAddress *isaddr = G_INET_SOCKET_ADDRESS (remote_addr); const gchar *server_hostname; gchar *addrstr, *session_id; iaddr = g_inet_socket_address_get_address (isaddr); port = g_inet_socket_address_get_port (isaddr); addrstr = g_inet_address_to_string (iaddr); server_hostname = get_server_identity (gnutls); session_id = g_strdup_printf ("%s/%s/%d", addrstr, server_hostname ? server_hostname : "", port); gnutls->priv->session_id = g_bytes_new_take (session_id, strlen (session_id)); g_free (addrstr); } g_object_unref (remote_addr); } g_object_unref (base_conn); if (G_OBJECT_CLASS (g_tls_client_connection_gnutls_parent_class)->constructed) G_OBJECT_CLASS (g_tls_client_connection_gnutls_parent_class)->constructed (object); }
static gboolean BP_TCPService_IncomingConnection (GSocketService *service, GSocketConnection *incomingConnection, GObject *source_object, gpointer user_data) { BPTCPService *filter = BP_TCPSERVICE (user_data); GSocket *socket = g_socket_connection_get_socket(incomingConnection); GSocketAddress *sockaddr = g_socket_connection_get_remote_address(incomingConnection, NULL); GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr)); gchar* remoteHost = g_inet_address_to_string(addr); gint fd = g_socket_get_fd(socket); GIOChannel *channel = g_io_channel_unix_new(fd); if (filter->mode == BP_MODE_SINK_ONLY) { GST_ERROR ("Attempt to accept connection but in sink-only mode"); return FALSE; } // Ref connection g_object_ref (incomingConnection); // Get remote host & port filter->remotePort = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(sockaddr)); g_string_assign(filter->remoteAddress, remoteHost); g_free (remoteHost); g_message ("New connection from %s:%d", filter->remoteAddress->str, (int) filter->remotePort); g_message ("Attaching IO channel watch ..."); // Add IO watch with pointer to connection handle as user data for callback g_io_add_watch(channel, G_IO_IN, (GIOFunc) BP_TCPService_IncomingConnectionReceive, filter); g_io_channel_unref (channel); g_message ("Registering connection"); BP_TCPService_UpdateUID (filter); ServerPool_AddInstance (filter->uid, filter->service, incomingConnection); return FALSE; }
//New tcp conection gboolean new_connection(GSocketService *service, GSocketConnection *connection, GObject *source_object, gpointer user_data) { //New client connected GSocketAddress *sockaddr = g_socket_connection_get_remote_address(connection, NULL); GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr)); guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(sockaddr)); if (verbose) { printf("App Server: New Connection from %s:%d\n", g_inet_address_to_string(addr), port); fflush(stdout); } //Record client (if new) add_client(g_inet_address_to_string(addr), connection); g_object_ref (connection); GSocket *socket = g_socket_connection_get_socket(connection); gint fd = g_socket_get_fd(socket); GIOChannel *channel = g_io_channel_unix_new(fd); g_io_add_watch(channel, G_IO_IN, (GIOFunc) network_read, connection); return TRUE; }
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; } }
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; } }
static gboolean run (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; const char *dirpath; OtTrivialHttpd appstruct = { 0, }; OtTrivialHttpd *app = &appstruct; glnx_unref_object SoupServer *server = NULL; g_autoptr(GFileMonitor) dirmon = NULL; context = g_option_context_new ("[DIR] - Simple webserver"); g_option_context_add_main_entries (context, options, NULL); app->root_dfd = -1; if (!g_option_context_parse (context, &argc, &argv, error)) goto out; if (argc > 1) dirpath = argv[1]; else dirpath = "."; if (!glnx_opendirat (AT_FDCWD, dirpath, TRUE, &app->root_dfd, error)) goto out; if (!(opt_random_500s_percentage >= 0 && opt_random_500s_percentage <= 99)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid --random-500s=%u", opt_random_500s_percentage); goto out; } if (opt_log) { GOutputStream *stream = NULL; if (g_strcmp0 (opt_log, "-") == 0) { if (opt_daemonize) { ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error); goto out; } stream = G_OUTPUT_STREAM (g_unix_output_stream_new (STDOUT_FILENO, FALSE)); } else { g_autoptr(GFile) log_file = NULL; GFileOutputStream* log_stream; log_file = g_file_new_for_path (opt_log); log_stream = g_file_create (log_file, G_FILE_CREATE_PRIVATE, cancellable, error); if (!log_stream) goto out; stream = G_OUTPUT_STREAM (log_stream); } app->log = stream; } #if SOUP_CHECK_VERSION(2, 48, 0) server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); if (!soup_server_listen_all (server, opt_port, 0, error)) goto out; #else server = soup_server_new (SOUP_SERVER_PORT, opt_port, SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); #endif soup_server_add_handler (server, NULL, httpd_callback, app, NULL); if (opt_port_file) { g_autofree char *portstr = NULL; #if SOUP_CHECK_VERSION(2, 48, 0) GSList *listeners = soup_server_get_listeners (server); g_autoptr(GSocket) listener = NULL; g_autoptr(GSocketAddress) addr = NULL; g_assert (listeners); listener = g_object_ref (listeners->data); g_slist_free (listeners); listeners = NULL; addr = g_socket_get_local_address (listener, error); if (!addr) goto out; g_assert (G_IS_INET_SOCKET_ADDRESS (addr)); portstr = g_strdup_printf ("%u\n", g_inet_socket_address_get_port ((GInetSocketAddress*)addr)); #else portstr = g_strdup_printf ("%u\n", soup_server_get_port (server)); #endif if (g_strcmp0 ("-", opt_port_file) == 0) { fputs (portstr, stdout); // not g_print - this must go to stdout, not a handler fflush (stdout); } else if (!g_file_set_contents (opt_port_file, portstr, strlen (portstr), error)) goto out; } #if !SOUP_CHECK_VERSION(2, 48, 0) soup_server_run_async (server); #endif if (opt_daemonize) { pid_t pid = fork(); if (pid == -1) { int errsv = errno; g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), g_strerror (errsv)); goto out; } else if (pid > 0) { ret = TRUE; goto out; } /* Child, continue */ if (setsid () < 0) err (1, "setsid"); /* Daemonising: close stdout/stderr so $() et al work on us */ if (freopen("/dev/null", "r", stdin) == NULL) err (1, "freopen"); if (freopen("/dev/null", "w", stdout) == NULL) err (1, "freopen"); if (freopen("/dev/null", "w", stderr) == NULL) err (1, "freopen"); } else { /* Since we're used for testing purposes, let's just do this by * default. This ensures we exit when our parent does. */ if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0) { if (errno != ENOSYS) { glnx_set_error_from_errno (error); goto out; } } } app->running = TRUE; if (opt_autoexit) { gboolean is_symlink = FALSE; g_autoptr(GFile) root = NULL; g_autoptr(GFileInfo) info = NULL; root = g_file_new_for_path (dirpath); info = g_file_query_info (root, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!info) goto out; is_symlink = g_file_info_get_is_symlink (info); if (is_symlink) dirmon = g_file_monitor_file (root, 0, cancellable, error); else dirmon = g_file_monitor_directory (root, 0, cancellable, error); if (!dirmon) goto out; g_signal_connect (dirmon, "changed", G_CALLBACK (on_dir_changed), app); } httpd_log (app, "serving at root %s\n", dirpath); while (app->running) g_main_context_iteration (NULL, TRUE); ret = TRUE; out: if (app->root_dfd != -1) (void) close (app->root_dfd); g_clear_object (&app->log); return ret; }
void * _thread (void *user_data) { ArvGvFakeCamera *gv_fake_camera = user_data; ArvBuffer *image_buffer = NULL; GError *error = NULL; GSocketAddress *stream_address = NULL; void *packet_buffer; size_t packet_size; size_t payload = 0; guint16 block_id; ptrdiff_t offset; guint32 gv_packet_size; GInputVector input_vector; int n_events; gboolean is_streaming = FALSE; input_vector.buffer = g_malloc0 (ARV_GV_FAKE_CAMERA_BUFFER_SIZE); input_vector.size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; packet_buffer = g_malloc (ARV_GV_FAKE_CAMERA_BUFFER_SIZE); do { guint64 next_timestamp_us; guint64 sleep_time_us; if (is_streaming) { sleep_time_us = arv_fake_camera_get_sleep_time_for_next_frame (gv_fake_camera->priv->camera, &next_timestamp_us); } else { sleep_time_us = 100000; next_timestamp_us = g_get_real_time () + sleep_time_us; } do { gint timeout_ms; timeout_ms = MIN (100, (next_timestamp_us - g_get_real_time ()) / 1000LL); if (timeout_ms < 0) timeout_ms = 0; n_events = g_poll (gv_fake_camera->priv->gvcp_fds, 2, timeout_ms); if (n_events > 0) { GSocketAddress *remote_address = NULL; int count; count = g_socket_receive_message (gv_fake_camera->priv->gvcp_socket, &remote_address, &input_vector, 1, NULL, NULL, NULL, NULL, NULL); if (count > 0) { if (handle_control_packet (gv_fake_camera, gv_fake_camera->priv->gvcp_socket, remote_address, input_vector.buffer, count)) arv_debug_device ("[GvFakeCamera::thread] Control packet received"); } g_clear_object (&remote_address); if (gv_fake_camera->priv->discovery_socket != NULL) { count = g_socket_receive_message (gv_fake_camera->priv->discovery_socket, &remote_address, &input_vector, 1, NULL, NULL, NULL, NULL, NULL); if (count > 0) { if (handle_control_packet (gv_fake_camera, gv_fake_camera->priv->discovery_socket, remote_address, input_vector.buffer, count)) arv_debug_device ("[GvFakeCamera::thread]" " Control packet received on discovery socket\n"); } g_clear_object (&remote_address); } if (arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) == 0 || arv_fake_camera_get_acquisition_status (gv_fake_camera->priv->camera) == 0) { if (stream_address != NULL) { g_object_unref (stream_address); stream_address = NULL; g_object_unref (image_buffer); image_buffer = NULL; arv_debug_stream_thread ("[GvFakeCamera::thread] Stop stream"); } is_streaming = FALSE; } } } while (!g_atomic_int_get (&gv_fake_camera->priv->cancel) && g_get_real_time () < next_timestamp_us); if (arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) != 0 && arv_fake_camera_get_acquisition_status (gv_fake_camera->priv->camera) != 0) { if (stream_address == NULL) { GInetAddress *inet_address; char *inet_address_string; stream_address = arv_fake_camera_get_stream_address (gv_fake_camera->priv->camera); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (stream_address)); inet_address_string = g_inet_address_to_string (inet_address); arv_debug_stream_thread ("[GvFakeCamera::thread] Start stream to %s (%d)", inet_address_string, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (stream_address))); g_free (inet_address_string); payload = arv_fake_camera_get_payload (gv_fake_camera->priv->camera); image_buffer = arv_buffer_new (payload, NULL); } arv_fake_camera_fill_buffer (gv_fake_camera->priv->camera, image_buffer, &gv_packet_size); arv_debug_stream_thread ("[GvFakeCamera::thread] Send frame %d", image_buffer->priv->frame_id); block_id = 0; packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_leader (image_buffer->priv->frame_id, block_id, image_buffer->priv->timestamp_ns, image_buffer->priv->pixel_format, image_buffer->priv->width, image_buffer->priv->height, image_buffer->priv->x_offset, image_buffer->priv->y_offset, packet_buffer, &packet_size); g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, &error); if (error != NULL) { arv_warning_stream_thread ("[GvFakeCamera::thread] Failed to send leader for frame %d: %s", image_buffer->priv->frame_id, error->message); g_clear_error (&error); } block_id++; offset = 0; while (offset < payload) { size_t data_size; data_size = MIN (gv_packet_size - ARV_GVSP_PACKET_PROTOCOL_OVERHEAD, payload - offset); packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_block (image_buffer->priv->frame_id, block_id, data_size, ((char *) image_buffer->priv->data) + offset, packet_buffer, &packet_size); g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, &error); if (error != NULL) { arv_debug_stream_thread ("[GvFakeCamera::thread] Failed to send frame block %d for frame: %s", block_id, image_buffer->priv->frame_id, error->message); g_clear_error (&error); } offset += data_size; block_id++; } packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_trailer (image_buffer->priv->frame_id, block_id, packet_buffer, &packet_size); g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, &error); if (error != NULL) { arv_debug_stream_thread ("[GvFakeCamera::thread] Failed to send trailer for frame %d: %s", image_buffer->priv->frame_id, error->message); g_clear_error (&error); } is_streaming = TRUE; } } while (!g_atomic_int_get (&gv_fake_camera->priv->cancel)); if (stream_address != NULL) g_object_unref (stream_address); if (image_buffer != NULL) g_object_unref (image_buffer); g_free (packet_buffer); g_free (input_vector.buffer); return NULL; }
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; } }
static gboolean cockpit_web_server_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { CockpitWebServer *server = COCKPIT_WEB_SERVER (initable); GSocketAddress *socket_address = NULL; GSocketAddress *result_address = NULL; gboolean ret = FALSE; gboolean failed = FALSE; int n, fd; server->socket_service = g_socket_service_new (); n = sd_listen_fds (0); if (n > 0) { /* We got file descriptors passed in, use those. */ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) { GSocket *s = NULL; gboolean b; int type; socklen_t l = sizeof (type); /* * HACK: Workaround g_error() happy code in GSocket * https://bugzilla.gnome.org/show_bug.cgi?id=746339 */ if (getsockopt (fd, SOL_SOCKET, SO_TYPE, &type, &l) < 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "invalid socket passed via systemd activation: %d: %s", fd, g_strerror (errno)); goto out; } s = g_socket_new_from_fd (fd, error); if (s == NULL) { g_prefix_error (error, "Failed to acquire passed socket %i: ", fd); goto out; } b = cockpit_web_server_add_socket (server, s, error); g_object_unref (s); if (!b) { g_prefix_error (error, "Failed to add listener for socket %i: ", fd); goto out; } } server->socket_activated = TRUE; } else { if (server->address) { socket_address = g_inet_socket_address_new (server->address, server->port); if (socket_address) { failed = !g_socket_listener_add_address (G_SOCKET_LISTENER (server->socket_service), socket_address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, NULL, &result_address, error); if (!failed) { server->port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (result_address)); g_object_unref (result_address); } g_object_unref (socket_address); } } /* No fds passed in, let's listen on our own. */ else if (server->port == 0) { server->port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (server->socket_service), NULL, error); failed = (server->port == 0); } else if (server->port > 0) { failed = !g_socket_listener_add_inet_port (G_SOCKET_LISTENER (server->socket_service), server->port, NULL, error); } if (failed) { g_prefix_error (error, "Failed to bind to port %d: ", server->port); goto out; } } g_signal_connect (server->socket_service, "incoming", G_CALLBACK (on_incoming), server); ret = TRUE; out: return ret; }
static gboolean do_one_attempt (gpointer user_data) { GError *local_error = NULL; MinCloudAgentApp *self = user_data; gs_free char *uri_str = NULL; gs_unref_object SoupRequest *request = NULL; gs_unref_object GInputStream *instream = NULL; gs_unref_object GFileOutputStream *outstream = NULL; gs_unref_object GFile *authorized_keys_path = NULL; gs_unref_object SoupMessage *msg = NULL; SoupURI *uri = NULL; const int max_request_failures = 5; const char *state_description = NULL; /* Skip over already completed states */ again: switch (self->state) { case MCA_STATE_USER_DATA: if (g_file_query_exists (self->userdata_done_stamp, NULL)) { self->state++; goto again; } break; case MCA_STATE_OPENSSH_KEY: if (g_file_query_exists (self->authorized_keys_path, NULL)) { self->state++; goto again; } break; case MCA_STATE_DONE: goto out; } uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, "http"); { gs_free char *addr_str = g_inet_address_to_string (self->addr); soup_uri_set_host (uri, addr_str); } soup_uri_set_port (uri, g_inet_socket_address_get_port (self->addr_port)); switch (self->state) { case MCA_STATE_USER_DATA: soup_uri_set_path (uri, "/2009-04-04/user-data"); state_description = "user-data"; break; case MCA_STATE_OPENSSH_KEY: soup_uri_set_path (uri, "/2009-04-04/meta-data/public-keys/0/openssh-key"); state_description = "openssh-key"; break; case MCA_STATE_DONE: g_assert_not_reached (); } uri_str = soup_uri_to_string (uri, FALSE); g_print ("Requesting '%s'...\n", uri_str); request = soup_session_request_uri (self->session, uri, &local_error); soup_uri_free (uri); if (!request) goto out; instream = soup_request_send (request, NULL, &local_error); if (!instream) goto out; msg = soup_request_http_get_message ((SoupRequestHTTP*) request); if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { switch (msg->status_code) { case 404: case 410: { gs_log_structured_print_id_v (MCA_NOT_FOUND_ID, "No %s found", state_description); g_clear_error (&local_error); /* Note fallthrough to out, where we'll advance to the next state */ goto out; } default: /* Don't actually set the error, we will just continue to * the next phase. */ gs_log_structured_print_id_v (MCA_TIMEOUT_ID, "Error fetching %s: %u %s", uri_str, msg->status_code, soup_status_get_phrase (msg->status_code)); goto out; } } switch (self->state) { case MCA_STATE_USER_DATA: if (!handle_userdata_script (self, instream, self->cancellable, &local_error)) goto out; break; case MCA_STATE_OPENSSH_KEY: if (!handle_install_authorized_keys (self, instream, self->cancellable, &local_error)) goto out; break; default: g_assert_not_reached (); } g_assert (self->state != MCA_STATE_DONE); self->state++; self->request_failure_count = 0; out: if (local_error) { self->request_failure_count++; if (self->request_failure_count >= max_request_failures) { g_error_free (local_error); gs_log_structured_print_id_v (MCA_TIMEOUT_ID, "Reached maximum failed attempts (%u) to fetch metadata", self->request_failure_count); self->do_one_attempt_id = 0; self->running = FALSE; } else { gs_log_structured_print_id_v (MCA_REQUEST_FAILED_ID, "Request failed (count: %u): %s", self->request_failure_count, local_error->message); g_error_free (local_error); self->do_one_attempt_id = g_timeout_add_seconds (self->request_failure_count, do_one_attempt, self); } } else { /* If we advanced in state, schedule the next callback in an * idle so we're consistently scheduled out of an idle. */ if (self->state != MCA_STATE_DONE) self->do_one_attempt_id = g_idle_add (do_one_attempt, self); else { self->do_one_attempt_id = 0; self->running = FALSE; } } return FALSE; }
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; }
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); }
void * arv_fake_gv_camera_thread (void *user_data) { ArvFakeGvCamera *gv_camera = user_data; ArvBuffer *image_buffer = NULL; GError *error = NULL; GSocketAddress *stream_address = NULL; void *packet_buffer; size_t packet_size; size_t payload = 0; guint16 block_id; ptrdiff_t offset; guint32 gv_packet_size; packet_buffer = g_malloc (ARV_FAKE_GV_CAMERA_BUFFER_SIZE); do { if (arv_fake_camera_get_control_channel_privilege (gv_camera->camera) == 0 || arv_fake_camera_get_acquisition_status (gv_camera->camera) == 0) { if (stream_address != NULL) { g_object_unref (stream_address); stream_address = NULL; g_object_unref (image_buffer); image_buffer = NULL; arv_debug_stream_thread ("[FakeGvCamera::stream_thread] Stop stream"); } g_usleep (100000); } else { if (stream_address == NULL) { GInetAddress *inet_address; char *inet_address_string; stream_address = arv_fake_camera_get_stream_address (gv_camera->camera); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (stream_address)); inet_address_string = g_inet_address_to_string (inet_address); arv_debug_stream_thread ("[FakeGvCamera::stream_thread] Start stream to %s (%d)", inet_address_string, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (stream_address))); g_free (inet_address_string); payload = arv_fake_camera_get_payload (gv_camera->camera); image_buffer = arv_buffer_new (payload, NULL); } arv_fake_camera_wait_for_next_frame (gv_camera->camera); arv_fake_camera_fill_buffer (gv_camera->camera, image_buffer, &gv_packet_size); block_id = 0; packet_size = ARV_FAKE_GV_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_leader (image_buffer->frame_id, block_id, image_buffer->timestamp_ns, image_buffer->pixel_format, image_buffer->width, image_buffer->height, image_buffer->x_offset, image_buffer->y_offset, packet_buffer, &packet_size); g_socket_send_to (gv_camera->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, &error); if (error != NULL) { arv_warning_stream_thread ("[ArvFakeGvCamera::stream_thread] Socket send error [%s]", error->message); g_error_free (error); error = NULL; } block_id++; offset = 0; while (offset < payload) { size_t data_size; data_size = MIN (gv_packet_size - ARV_GVSP_PACKET_PROTOCOL_OVERHEAD, payload - offset); packet_size = ARV_FAKE_GV_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_block (image_buffer->frame_id, block_id, data_size, ((char *) image_buffer->data) + offset, packet_buffer, &packet_size); g_socket_send_to (gv_camera->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, NULL); offset += data_size; block_id++; } packet_size = ARV_FAKE_GV_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_trailer (image_buffer->frame_id, block_id, packet_buffer, &packet_size); g_socket_send_to (gv_camera->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, NULL); } } while (!cancel); if (stream_address != NULL) g_object_unref (stream_address); if (image_buffer != NULL) g_object_unref (image_buffer); g_free (packet_buffer); return NULL; }
/* 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; } }
static gboolean gst_net_client_clock_start (GstNetClientClock * self) { GSocketAddress *servaddr; GSocketAddress *myaddr; GInetAddress *inetaddr; GSocket *socket; GError *error = NULL; g_return_val_if_fail (self->priv->address != NULL, FALSE); g_return_val_if_fail (self->priv->servaddr == NULL, FALSE); socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error); if (socket == NULL) goto no_socket; /* 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 %hd", g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (myaddr))); g_object_unref (myaddr); /* create target address */ inetaddr = g_inet_address_new_from_string (self->priv->address); if (inetaddr == NULL) goto bad_address; servaddr = g_inet_socket_address_new (inetaddr, self->priv->port); g_object_unref (inetaddr); g_assert (servaddr != NULL); GST_DEBUG_OBJECT (self, "will communicate with %s:%d", self->priv->address, self->priv->port); self->priv->cancel = g_cancellable_new (); self->priv->socket = socket; self->priv->servaddr = G_SOCKET_ADDRESS (servaddr); self->priv->thread = g_thread_try_new ("GstNetClientClock", gst_net_client_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; } getsockname_error: { GST_ERROR_OBJECT (self, "get_local_address() failed: %s", error->message); g_error_free (error); g_object_unref (socket); return FALSE; } bad_address: { GST_ERROR_OBJECT (self, "inet_address_new_from_string('%s') failed", self->priv->address); g_object_unref (socket); return FALSE; } no_thread: { GST_ERROR_OBJECT (self, "could not create thread: %s", error->message); g_object_unref (self->priv->servaddr); self->priv->servaddr = NULL; g_object_unref (self->priv->socket); self->priv->socket = NULL; g_error_free (error); return FALSE; } }
/* 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; }
/** * g_socket_listener_add_any_inet_port: * @listener: a #GSocketListener * @source_object: (allow-none): Optional #GObject identifying this source * @error: a #GError location to store the error occurring, or %NULL to * ignore. * * Listens for TCP connections on any available port number for both * IPv6 and IPv4 (if each is available). * * This is useful if you need to have a socket for incoming connections * but don't care about the specific port number. * * @source_object will be passed out in the various calls * to accept to identify this particular source, which is * useful if you're listening on multiple addresses and do * different things depending on what address is connected to. * * Returns: the port number, or 0 in case of failure. * * Since: 2.24 **/ guint16 g_socket_listener_add_any_inet_port (GSocketListener *listener, GObject *source_object, GError **error) { GSList *sockets_to_close = NULL; guint16 candidate_port = 0; GSocket *socket6 = NULL; GSocket *socket4 = NULL; gint attempts = 37; /* * multi-step process: * - first, create an IPv6 socket. * - if that fails, create an IPv4 socket and bind it to port 0 and * that's it. no retries if that fails (why would it?). * - if our IPv6 socket also speaks IPv4 then we are done. * - if not, then we need to create a IPv4 socket with the same port * number. this might fail, of course. so we try this a bunch of * times -- leaving the old IPv6 sockets open so that we get a * different port number to try each time. * - if all that fails then just give up. */ while (attempts--) { GInetAddress *inet_address; GSocketAddress *address; gboolean result; g_assert (socket6 == NULL); socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, NULL); if (socket6 != NULL) { inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6); address = g_inet_socket_address_new (inet_address, 0); g_object_unref (inet_address); result = g_socket_bind (socket6, address, TRUE, error); g_object_unref (address); if (!result || !(address = g_socket_get_local_address (socket6, error))) { g_object_unref (socket6); socket6 = NULL; break; } g_assert (G_IS_INET_SOCKET_ADDRESS (address)); candidate_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); g_assert (candidate_port != 0); g_object_unref (address); if (g_socket_speaks_ipv4 (socket6)) break; } g_assert (socket4 == NULL); socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, socket6 ? NULL : error); if (socket4 == NULL) /* IPv4 not supported. * if IPv6 is supported then candidate_port will be non-zero * (and the error parameter above will have been NULL) * if IPv6 is unsupported then candidate_port will be zero * (and error will have been set by the above call) */ break; inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); address = g_inet_socket_address_new (inet_address, candidate_port); g_object_unref (inet_address); /* a note on the 'error' clause below: * * if candidate_port is 0 then we report the error right away * since it is strange that this binding would fail at all. * otherwise, we ignore the error message (ie: NULL). * * the exception to this rule is the last time through the loop * (ie: attempts == 0) in which case we want to set the error * because failure here means that the entire call will fail and * we need something to show to the user. * * an english summary of the situation: "if we gave a candidate * port number AND we have more attempts to try, then ignore the * error for now". */ result = g_socket_bind (socket4, address, TRUE, (candidate_port && attempts) ? NULL : error); g_object_unref (address); if (candidate_port) { g_assert (socket6 != NULL); if (result) /* got our candidate port successfully */ break; else /* we failed to bind to the specified port. try again. */ { g_object_unref (socket4); socket4 = NULL; /* keep this open so we get a different port number */ sockets_to_close = g_slist_prepend (sockets_to_close, socket6); candidate_port = 0; socket6 = NULL; } } else /* we didn't tell it a port. this means two things. * - if we failed, then something really bad happened. * - if we succeeded, then we need to find out the port number. */ { g_assert (socket6 == NULL); if (!result || !(address = g_socket_get_local_address (socket4, error))) { g_object_unref (socket4); socket4 = NULL; break; } g_assert (G_IS_INET_SOCKET_ADDRESS (address)); candidate_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); g_assert (candidate_port != 0); g_object_unref (address); break; } } /* should only be non-zero if we have a socket */ g_assert ((candidate_port != 0) == (socket4 || socket6)); while (sockets_to_close) { g_object_unref (sockets_to_close->data); sockets_to_close = g_slist_delete_link (sockets_to_close, sockets_to_close); } /* now we actually listen() the sockets and add them to the listener */ if (socket6 != NULL) { g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog); if (!g_socket_listen (socket6, error)) { g_object_unref (socket6); if (socket4) g_object_unref (socket4); return 0; } if (source_object) g_object_set_qdata_full (G_OBJECT (socket6), source_quark, g_object_ref (source_object), g_object_unref); g_ptr_array_add (listener->priv->sockets, socket6); } if (socket4 != NULL) { g_socket_set_listen_backlog (socket4, listener->priv->listen_backlog); if (!g_socket_listen (socket4, error)) { g_object_unref (socket4); if (socket6) g_object_unref (socket6); return 0; } if (source_object) g_object_set_qdata_full (G_OBJECT (socket4), source_quark, g_object_ref (source_object), g_object_unref); g_ptr_array_add (listener->priv->sockets, socket4); } if ((socket4 != NULL || socket6 != NULL) && G_SOCKET_LISTENER_GET_CLASS (listener)->changed) G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener); return candidate_port; }