/** * gst_net_time_packet_send: * @packet: the #GstNetTimePacket to send * @socket: socket to send the time packet on * @dest_address: address to send the time packet to * @error: return address for a #GError, or NULL * * Sends a #GstNetTimePacket over a socket. * * MT safe. * * Returns: TRUE if successful, FALSE in case an error occurred. */ gboolean gst_net_time_packet_send (const GstNetTimePacket * packet, GSocket * socket, GSocketAddress * dest_address, GError ** error) { gboolean was_blocking; guint8 *buffer; gssize res; g_return_val_if_fail (packet != NULL, FALSE); g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); g_return_val_if_fail (G_IS_SOCKET_ADDRESS (dest_address), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); was_blocking = g_socket_get_blocking (socket); if (was_blocking) g_socket_set_blocking (socket, FALSE); /* FIXME: avoid pointless alloc/free, serialise into stack-allocated buffer */ buffer = gst_net_time_packet_serialize (packet); res = g_socket_send_to (socket, dest_address, (const gchar *) buffer, GST_NET_TIME_PACKET_SIZE, NULL, error); /* datagram packets should be sent as a whole or not at all */ g_assert (res < 0 || res == GST_NET_TIME_PACKET_SIZE); g_free (buffer); if (was_blocking) g_socket_set_blocking (socket, TRUE); return (res == GST_NET_TIME_PACKET_SIZE); }
static int remote_connect(const char* host, unsigned port, void** connectiondata) { g_message("connecting to remote: %s on port %u", host, port); GSocket* sock = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); GSocketConnectable* addr = g_network_address_new(host, port); GSocketAddressEnumerator* enumerator = g_socket_connectable_enumerate(addr); int ret = EMCUETITI_PORT_REMOTE_TRYAGAIN; GSocketAddress* sockaddr; while ((sockaddr = g_socket_address_enumerator_next(enumerator, NULL, NULL))) { g_message("connecting..."); GError* error = NULL; if (g_socket_connect(sock, sockaddr, NULL, &error)) { g_message("connected"); g_socket_set_blocking(sock, FALSE); remote_wireupsocketcallback(sock); *connectiondata = sock; ret = EMCUETITI_PORT_REMOTE_OK; break; } else { g_message("failed to connect %d:%s", error->code, error->message); } } if (ret != EMCUETITI_PORT_REMOTE_OK) g_object_unref(sock); g_object_unref(addr); g_object_unref(enumerator); return ret; }
gint main (void) { gboolean ret; GSocket *socket = NULL; GSocketAddress *address = NULL; GError *error = NULL; gsize wrote; const gchar *buffer = "ping\n"; const gchar *socket_filename = "/tmp/pk-self-test.socket"; GSource *source; GMainLoop *loop; g_type_init (); loop = g_main_loop_new (NULL, FALSE); /* create socket */ socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error); if (socket == NULL) { g_warning ("failed to create socket: %s", error->message); g_error_free (error); goto out; } g_socket_set_blocking (socket, FALSE); g_socket_set_keepalive (socket, TRUE); /* connect to it */ address = g_unix_socket_address_new (socket_filename); ret = g_socket_connect (socket, address, NULL, &error); if (!ret) { g_warning ("failed to connect to socket: %s", error->message); g_error_free (error); goto out; } /* socket has data */ source = g_socket_create_source (socket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL); g_source_set_callback (source, (GSourceFunc) pk_socket_example_accept_connection_cb, loop, NULL); g_source_attach (source, NULL); /* send some data */ wrote = g_socket_send (socket, buffer, 5, NULL, &error); if (wrote != 5) { g_warning ("failed to write 5 bytes"); goto out; } /* run main loop */ g_debug ("running main loop"); g_main_loop_run (loop); out: if (loop != NULL) g_main_loop_unref (loop); if (socket != NULL) g_object_unref (socket); if (address != NULL) g_object_unref (address); return 0; }
static void on_address_next (GObject *object, GAsyncResult *result, gpointer user_data) { CockpitStream *self = user_data; GSocketConnection *connection; GSocketAddress *address; GError *error = NULL; GSocket *sock; address = g_socket_address_enumerator_next_finish (G_SOCKET_ADDRESS_ENUMERATOR (object), result, &error); if (error) { set_problem_from_error (self, "couldn't resolve", error); g_error_free (error); close_immediately (self, NULL); } else if (address) { sock = g_socket_new (g_socket_address_get_family (address), G_SOCKET_TYPE_STREAM, 0, &error); if (sock) { g_socket_set_blocking (sock, FALSE); connection = g_socket_connection_factory_create_connection (sock); g_object_unref (sock); g_socket_connection_connect_async (connection, address, NULL, on_socket_connect, g_object_ref (self)); } if (error) { g_debug ("%s: couldn't open socket: %s", self->priv->name, error->message); g_clear_error (&self->priv->connect_error); self->priv->connect_error = error; } g_object_unref (address); } else { if (self->priv->connect_error) { set_problem_from_error (self, "couldn't connect", self->priv->connect_error); close_immediately (self, NULL); } else { g_message ("%s: no addresses found", self->priv->name); close_immediately (self, "not-found"); } } g_object_unref (self); }
/* Create a netlink socket, bind to it and wrap it in a GSocket */ static gboolean create_netlink_socket (GUPnPLinuxContextManager *self, GError **error) { struct sockaddr_nl sa; int fd, status; GSocket *sock; GError *inner_error; inner_error = NULL; fd = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); if (fd == -1) { g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), "Failed to bind to netlink socket"); return FALSE; } memset (&sa, 0, sizeof (sa)); sa.nl_family = AF_NETLINK; /* Listen for interface changes and IP address changes */ sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR; status = bind (fd, (struct sockaddr *) &sa, sizeof (sa)); if (status == -1) { g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), "Failed to bind to netlink socket"); close (fd); return FALSE; } sock = g_socket_new_from_fd (fd, &inner_error); if (sock == NULL) { close (fd); g_propagate_prefixed_error (error, inner_error, "Failed to create GSocket from " "netlink socket"); return FALSE; } g_socket_set_blocking (sock, FALSE); self->priv->netlink_socket = sock; return TRUE; }
static void cockpit_request_start (CockpitWebServer *self, GIOStream *io, gboolean first) { GSocketConnection *connection; CockpitRequest *request; gboolean input = TRUE; GSocket *socket; request = g_new0 (CockpitRequest, 1); request->web_server = self; request->io = g_object_ref (io); request->buffer = g_byte_array_new (); /* Right before a successive request, EOF is not unexpected */ request->eof_okay = !first; request->timeout = g_timeout_source_new_seconds (cockpit_webserver_request_timeout); g_source_set_callback (request->timeout, on_request_timeout, request, NULL); g_source_attach (request->timeout, self->main_context); if (first) { connection = G_SOCKET_CONNECTION (io); socket = g_socket_connection_get_socket (connection); g_socket_set_blocking (socket, FALSE); if (self->certificate) { request->source = g_socket_create_source (g_socket_connection_get_socket (connection), G_IO_IN, NULL); g_source_set_callback (request->source, (GSourceFunc)on_socket_input, request, NULL); g_source_attach (request->source, self->main_context); /* Wait on reading input */ input = FALSE; } } /* Owns the request */ g_hash_table_add (self->requests, request); if (input) start_request_input (request); }
NiceSocket * nice_tcp_passive_socket_accept (NiceSocket *sock) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; TcpPassivePriv *priv = sock->priv; GSocket *gsock = NULL; GSocketAddress *gaddr; NiceAddress remote_addr; NiceSocket *new_socket = NULL; gsock = g_socket_accept (sock->fileno, NULL, NULL); if (gsock == NULL) { return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); gaddr = g_socket_get_remote_address (gsock, NULL); if (gaddr == NULL || !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_object_unref (gaddr); nice_address_set_from_sockaddr (&remote_addr, &name.addr); new_socket = nice_tcp_bsd_socket_new_from_gsock (priv->context, gsock, &sock->addr, &remote_addr, TRUE); g_object_unref (gsock); if (new_socket) { NiceAddress *key = nice_address_dup (&remote_addr); nice_socket_set_writable_callback (new_socket, _child_writable_cb, sock); g_hash_table_insert (priv->connections, key, new_socket); } return new_socket; }
NiceSocket * nice_tcp_bsd_socket_new (GMainContext *ctx, NiceAddress *local_addr, NiceAddress *remote_addr, gboolean reliable) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; NiceSocket *sock; GSocket *gsock = NULL; GError *gerr = NULL; gboolean gret = FALSE; GSocketAddress *gaddr; if (remote_addr == NULL) { /* We can't connect a tcp socket with no destination address */ return NULL; } nice_address_copy_to_sockaddr (remote_addr, &name.addr); if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in); #endif } else if (name.storage.ss_family == AF_INET6) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in6); #endif } if (gsock == NULL) { return NULL; } gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_object_unref (gsock); return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); gret = g_socket_connect (gsock, gaddr, NULL, &gerr); g_object_unref (gaddr); if (gret == FALSE) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) { g_error_free (gerr); g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_error_free (gerr); } nice_address_copy_to_sockaddr (local_addr, &name.addr); gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_socket_bind (gsock, gaddr, FALSE, NULL); g_object_unref (gaddr); sock = nice_tcp_bsd_socket_new_from_gsock (ctx, gsock, local_addr, remote_addr, reliable); g_object_unref (gsock); return sock; }
static void _channel_accepted (TpChannel *channel, const GValue *addressv, const GError *in_error, gpointer user_data, GObject *obj) { TpStreamTubeChannel *self = (TpStreamTubeChannel *) obj; GSocketAddress *remote_address; GError *error = NULL; if (in_error != NULL) { DEBUG ("Failed to Accept Stream Tube: %s", in_error->message); operation_failed (self, in_error); return; } tp_cli_channel_type_stream_tube_connect_to_new_local_connection ( TP_CHANNEL (self), new_local_connection_cb, NULL, NULL, G_OBJECT (self), &error); if (error != NULL) { DEBUG ("Failed to connect to NewLocalConnection signal"); operation_failed (self, error); g_error_free (error); return; } remote_address = tp_g_socket_address_from_variant (self->priv->socket_type, addressv, &error); if (error != NULL) { DEBUG ("Failed to convert address: %s", error->message); operation_failed (self, error); g_error_free (error); return; } /* Connect to CM */ g_socket_set_blocking (self->priv->client_socket, FALSE); g_socket_connect (self->priv->client_socket, remote_address, NULL, &error); if (error == NULL) { /* Socket is connected */ client_socket_connected (self); goto out; } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING)) { /* We have to wait that the socket is connected */ GSource *source; source = g_socket_create_source (self->priv->client_socket, G_IO_OUT, NULL); g_source_attach (source, g_main_context_get_thread_default ()); g_source_set_callback (source, (GSourceFunc) client_socket_cb, self, NULL); g_error_free (error); g_source_unref (source); } else { DEBUG ("Failed to connect to CM: %s", error->message); operation_failed (self, error); g_error_free (error); } out: g_object_unref (remote_address); }
static gpointer gst_net_client_clock_thread (gpointer data) { GstNetClientClock *self = data; GstNetTimePacket *packet; GSocket *socket = self->priv->socket; GError *err = NULL; GstClock *clock = data; GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket); g_socket_set_blocking (socket, TRUE); g_socket_set_timeout (socket, 0); while (!g_cancellable_is_cancelled (self->priv->cancel)) { GstClockTime expiration_time = self->priv->timeout_expiration; GstClockTime now = gst_util_get_timestamp (); gint64 socket_timeout; if (now >= expiration_time || (expiration_time - now) <= GST_MSECOND) { socket_timeout = 0; } else { socket_timeout = (expiration_time - now) / GST_USECOND; } GST_TRACE_OBJECT (self, "timeout: %" G_GINT64_FORMAT "us", socket_timeout); if (!g_socket_condition_timed_wait (socket, G_IO_IN, socket_timeout, self->priv->cancel, &err)) { /* cancelled, timeout or error */ if (err->code == G_IO_ERROR_CANCELLED) { GST_INFO_OBJECT (self, "cancelled"); g_clear_error (&err); break; } else if (err->code == G_IO_ERROR_TIMED_OUT) { /* timed out, let's send another packet */ GST_DEBUG_OBJECT (self, "timed out"); packet = gst_net_time_packet_new (NULL); packet->local_time = gst_clock_get_internal_time (GST_CLOCK (self)); GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); gst_net_time_packet_send (packet, self->priv->socket, self->priv->servaddr, NULL); g_free (packet); /* reset timeout (but are expecting a response sooner anyway) */ self->priv->timeout_expiration = gst_util_get_timestamp () + gst_clock_get_timeout (clock); } else { GST_DEBUG_OBJECT (self, "socket error: %s", err->message); g_usleep (G_USEC_PER_SEC / 10); /* throttle */ } g_clear_error (&err); } else { GstClockTime new_local; /* got packet */ new_local = gst_clock_get_internal_time (GST_CLOCK (self)); packet = gst_net_time_packet_receive (socket, NULL, &err); if (packet != NULL) { GST_LOG_OBJECT (self, "got packet back"); GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->remote_time)); GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (new_local)); /* observe_times will reset the timeout */ gst_net_client_clock_observe_times (self, packet->local_time, packet->remote_time, new_local); g_free (packet); } else if (err != NULL) { GST_WARNING_OBJECT (self, "receive error: %s", err->message); g_clear_error (&err); } } } GST_INFO_OBJECT (self, "shutting down net client clock thread"); return NULL; }
static void arv_gv_interface_receive_hello_packet (ArvGvInterface *gv_interface) { GPollFD *poll_fd; GSList *iter; char buffer[ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE] __attribute__((may_alias)); int count; int i; if (gv_interface->priv->n_discover_infos ==0) return; poll_fd = g_new (GPollFD, gv_interface->priv->n_discover_infos); for (i = 0, iter = gv_interface->priv->discover_infos_list; iter != NULL; i++, iter = iter->next) { ArvGvInterfaceDiscoverInfos *infos = iter->data; poll_fd[i].fd = g_socket_get_fd (infos->socket); poll_fd[i].events = G_IO_IN; poll_fd[i].revents = 0; } do { if (g_poll (poll_fd, gv_interface->priv->n_discover_infos, ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0) { g_free (poll_fd); return; } for (i = 0, iter = gv_interface->priv->discover_infos_list; iter != NULL; i++, iter = iter->next) { ArvGvInterfaceDiscoverInfos *infos = iter->data; do { g_socket_set_blocking (infos->socket, FALSE); count = g_socket_receive (infos->socket, buffer, ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE, NULL, NULL); g_socket_set_blocking (infos->socket, TRUE); if (count > 0) { ArvGvcpPacket *packet = (ArvGvcpPacket *) buffer; if (g_ntohs (packet->header.command) == ARV_GVCP_COMMAND_DISCOVERY_ACK && g_ntohs (packet->header.id) == 0xffff) { ArvGvInterfaceDeviceInfos *device_infos; GInetAddress *interface_address; char *address_string; char *data = buffer + sizeof (ArvGvcpHeader); char *serial_number; char *manufacturer; char *key; arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); manufacturer = g_strndup (&data[ARV_GVBS_MANUFACTURER_NAME_OFFSET], ARV_GVBS_MANUFACTURER_NAME_SIZE); serial_number = g_strndup (&data[ARV_GVBS_SERIAL_NUMBER_OFFSET], ARV_GVBS_SERIAL_NUMBER_SIZE); key = g_strdup_printf ("%s-%s", manufacturer, serial_number); g_free (manufacturer); g_free (serial_number); interface_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (infos->interface_address)); device_infos = arv_gv_interface_device_infos_new (interface_address, data); address_string = g_inet_address_to_string (interface_address); arv_debug_interface ("[GvInterface::discovery] Device '%s' found " "(interface %s)", key, address_string); g_free (address_string); g_hash_table_insert (gv_interface->priv->devices, key, device_infos); g_hash_table_insert (gv_interface->priv->devices_by_mac, device_infos->mac_string, device_infos); } } } while (count > 0); } } while (1); }
ArvFakeGvCamera * arv_fake_gv_camera_new (const char *interface_name) { ArvFakeGvCamera *gv_camera; struct ifaddrs *ifap = NULL; struct ifaddrs *ifap_iter; int return_value; gboolean interface_found = FALSE; gboolean binding_error = FALSE; g_return_val_if_fail (interface_name != NULL, NULL); gv_camera = g_new0 (ArvFakeGvCamera, 1); gv_camera->camera = arv_fake_camera_new ("GV01"); return_value = getifaddrs (&ifap); if (return_value < 0) { g_warning ("[FakeGvCamera::new] No network interface found"); return NULL; } for (ifap_iter = ifap ;ifap_iter != NULL && !interface_found; 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->sa_family == AF_INET) && g_strcmp0 (ifap_iter->ifa_name, interface_name) == 0) { GSocketAddress *socket_address; GSocketAddress *inet_socket_address; GInetAddress *inet_address; char *gvcp_address_string; char *discovery_address_string; 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)); gvcp_address_string = g_inet_address_to_string (inet_address); arv_debug_device ("[FakeGvCamera::new] Interface address = %s", gvcp_address_string); inet_socket_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT); gv_camera->gvcp_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); if (!g_socket_bind (gv_camera->gvcp_socket, inet_socket_address, FALSE, NULL)) binding_error = TRUE; g_socket_set_blocking (gv_camera->gvcp_socket, FALSE); arv_fake_camera_set_inet_address (gv_camera->camera, inet_address); g_object_unref (inet_socket_address); inet_socket_address = g_inet_socket_address_new (inet_address, 0); gv_camera->gvsp_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); if (!g_socket_bind (gv_camera->gvsp_socket, inet_socket_address, FALSE, NULL)) binding_error = TRUE; g_object_unref (inet_socket_address); g_object_unref (socket_address); socket_address = g_socket_address_new_from_native (ifap_iter->ifa_broadaddr, sizeof (struct sockaddr)); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address)); discovery_address_string = g_inet_address_to_string (inet_address); arv_debug_device ("[FakeGvCamera::new] Discovery address = %s", discovery_address_string); inet_socket_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT); if (g_strcmp0 (gvcp_address_string, discovery_address_string) == 0) gv_camera->discovery_socket = NULL; else { gv_camera->discovery_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); if (!g_socket_bind (gv_camera->discovery_socket, inet_socket_address, FALSE, NULL)) binding_error = TRUE; g_socket_set_blocking (gv_camera->discovery_socket, FALSE); } g_object_unref (inet_socket_address); g_object_unref (socket_address); g_free (gvcp_address_string); g_free (discovery_address_string); gv_camera->gvcp_fds[0].fd = g_socket_get_fd (gv_camera->gvcp_socket); gv_camera->gvcp_fds[0].events = G_IO_IN; gv_camera->gvcp_fds[0].revents = 0; if (gv_camera->discovery_socket != NULL) { gv_camera->gvcp_fds[1].fd = g_socket_get_fd (gv_camera->discovery_socket); gv_camera->gvcp_fds[1].events = G_IO_IN; gv_camera->gvcp_fds[1].revents = 0; gv_camera->n_gvcp_fds = 2; } else gv_camera->n_gvcp_fds = 1; interface_found = TRUE; } } freeifaddrs (ifap); if (binding_error) goto BINDING_ERROR; if (!interface_found) goto INTERFACE_ERROR; gv_camera->cancel = FALSE; gv_camera->gvsp_thread = arv_g_thread_new ("arv_fake_gv_camera", arv_fake_gv_camera_thread, gv_camera); return gv_camera; BINDING_ERROR: g_object_unref (gv_camera->gvcp_socket); if (gv_camera->discovery_socket != NULL) g_object_unref (gv_camera->discovery_socket); g_object_unref (gv_camera->gvsp_socket); INTERFACE_ERROR: g_object_unref (gv_camera->camera); g_free (gv_camera); return NULL; }
int main (int argc, char *argv[]) { GSocket *socket; GSocketAddress *address; GError *error = NULL; GOptionContext *context; GCancellable *cancellable; GIOStream *connection; GInputStream *istream; GOutputStream *ostream; GSocketAddress *src_address; GTlsCertificate *certificate = NULL; gint i; address = NULL; connection = NULL; context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff"); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (argc != 2) { g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name"); return 1; } if (use_udp && tls) { g_printerr ("DTLS (TLS over UDP) is not supported"); return 1; } if (cancel_timeout) { GThread *thread; cancellable = g_cancellable_new (); thread = g_thread_new ("cancel", cancel_thread, cancellable); g_thread_unref (thread); } else { cancellable = NULL; } loop = g_main_loop_new (NULL, FALSE); for (i = 0; i < 2; i++) { if (make_connection (argv[1], certificate, cancellable, &socket, &address, &connection, &istream, &ostream, &error)) break; if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED)) { g_clear_error (&error); certificate = lookup_client_certificate (G_TLS_CLIENT_CONNECTION (connection), &error); if (certificate != NULL) continue; } g_printerr ("%s: %s", argv[0], error->message); return 1; } /* TODO: Test non-blocking connect/handshake */ if (non_blocking) g_socket_set_blocking (socket, FALSE); while (TRUE) { gchar buffer[4096]; gssize size; gsize to_send; if (fgets (buffer, sizeof buffer, stdin) == NULL) break; to_send = strlen (buffer); while (to_send > 0) { if (use_udp) { ensure_socket_condition (socket, G_IO_OUT, cancellable); size = g_socket_send_to (socket, address, buffer, to_send, cancellable, &error); } else { ensure_connection_condition (connection, G_IO_OUT, cancellable); size = g_output_stream_write (ostream, buffer, to_send, cancellable, &error); } if (size < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_print ("socket send would block, handling\n"); g_error_free (error); error = NULL; continue; } else { g_printerr ("Error sending to socket: %s\n", error->message); return 1; } } g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); if (size == 0) { g_printerr ("Unexpected short write\n"); return 1; } to_send -= size; } if (use_udp) { ensure_socket_condition (socket, G_IO_IN, cancellable); size = g_socket_receive_from (socket, &src_address, buffer, sizeof buffer, cancellable, &error); } else { ensure_connection_condition (connection, G_IO_IN, cancellable); size = g_input_stream_read (istream, buffer, sizeof buffer, cancellable, &error); } if (size < 0) { g_printerr ("Error receiving from socket: %s\n", error->message); return 1; } if (size == 0) break; g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); if (use_udp) g_print (" from %s", socket_address_to_string (src_address)); g_print ("\n"); if (verbose) g_print ("-------------------------\n" "%.*s" "-------------------------\n", (int)size, buffer); } g_print ("closing socket\n"); if (connection) { if (!g_io_stream_close (connection, cancellable, &error)) { g_printerr ("Error closing connection: %s\n", error->message); return 1; } g_object_unref (connection); } else { if (!g_socket_close (socket, &error)) { g_printerr ("Error closing master socket: %s\n", error->message); return 1; } } g_object_unref (socket); g_object_unref (address); return 0; }
static gboolean g_network_monitor_netlink_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (initable); gint sockfd, val; struct sockaddr_nl snl; /* We create the socket the old-school way because sockaddr_netlink * can't be represented as a GSocketAddress */ sockfd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sockfd == -1) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Could not create network monitor: %s"), g_strerror (errno)); return FALSE; } snl.nl_family = AF_NETLINK; snl.nl_pid = snl.nl_pad = 0; snl.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE; if (bind (sockfd, (struct sockaddr *)&snl, sizeof (snl)) != 0) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Could not create network monitor: %s"), g_strerror (errno)); close (sockfd); return FALSE; } val = 1; if (setsockopt (sockfd, SOL_SOCKET, SO_PASSCRED, &val, sizeof (val)) != 0) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Could not create network monitor: %s"), g_strerror (errno)); close (sockfd); return FALSE; } nl->priv->sock = g_socket_new_from_fd (sockfd, error); if (error) { g_prefix_error (error, "%s", _("Could not create network monitor: ")); close (sockfd); return FALSE; } /* Request the current state */ if (!request_dump (nl, error)) return FALSE; /* And read responses; since we haven't yet marked the socket * non-blocking, each call will block until a message is received. */ while (nl->priv->dump_networks) { if (!read_netlink_messages (NULL, G_IO_IN, nl)) break; } g_socket_set_blocking (nl->priv->sock, FALSE); nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL); g_source_set_callback (nl->priv->source, (GSourceFunc) read_netlink_messages, nl, NULL); g_source_attach (nl->priv->source, g_main_context_get_thread_default ()); return TRUE; }
gboolean arv_gv_fake_camera_start (ArvGvFakeCamera *gv_fake_camera) { struct ifaddrs *ifap = NULL; struct ifaddrs *ifap_iter; int return_value; gboolean interface_found = FALSE; gboolean binding_error = FALSE; g_return_val_if_fail (ARV_IS_GV_FAKE_CAMERA (gv_fake_camera), FALSE); return_value = getifaddrs (&ifap); if (return_value < 0) { arv_warning_device ("[GvFakeCamera::start] No network interface found"); return FALSE; } for (ifap_iter = ifap ;ifap_iter != NULL && !interface_found; 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->sa_family == AF_INET) && g_strcmp0 (ifap_iter->ifa_name, gv_fake_camera->priv->interface_name) == 0) { GSocketAddress *socket_address; GSocketAddress *inet_socket_address; GInetAddress *inet_address; char *gvcp_address_string; char *discovery_address_string; 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)); gvcp_address_string = g_inet_address_to_string (inet_address); arv_debug_device ("[GvFakeCamera::start] Interface address = %s", gvcp_address_string); inet_socket_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT); gv_fake_camera->priv->gvcp_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); if (!g_socket_bind (gv_fake_camera->priv->gvcp_socket, inet_socket_address, FALSE, NULL)) binding_error = TRUE; g_socket_set_blocking (gv_fake_camera->priv->gvcp_socket, FALSE); arv_fake_camera_set_inet_address (gv_fake_camera->priv->camera, inet_address); g_object_unref (inet_socket_address); inet_socket_address = g_inet_socket_address_new (inet_address, 0); gv_fake_camera->priv->gvsp_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); if (!g_socket_bind (gv_fake_camera->priv->gvsp_socket, inet_socket_address, FALSE, NULL)) binding_error = TRUE; g_clear_object (&inet_socket_address); g_clear_object (&socket_address); inet_address = g_inet_address_new_from_string ("255.255.255.255"); discovery_address_string = g_inet_address_to_string (inet_address); arv_debug_device ("[GvFakeCamera::start] Discovery address = %s", discovery_address_string); inet_socket_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT); if (g_strcmp0 (gvcp_address_string, discovery_address_string) == 0) gv_fake_camera->priv->discovery_socket = NULL; else { gv_fake_camera->priv->discovery_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); if (!g_socket_bind (gv_fake_camera->priv->discovery_socket, inet_socket_address, FALSE, NULL)) binding_error = TRUE; g_socket_set_blocking (gv_fake_camera->priv->discovery_socket, FALSE); } g_clear_object (&inet_socket_address); g_clear_object (&inet_address); g_free (gvcp_address_string); g_free (discovery_address_string); gv_fake_camera->priv->gvcp_fds[0].fd = g_socket_get_fd (gv_fake_camera->priv->gvcp_socket); gv_fake_camera->priv->gvcp_fds[0].events = G_IO_IN; gv_fake_camera->priv->gvcp_fds[0].revents = 0; if (gv_fake_camera->priv->discovery_socket != NULL) { gv_fake_camera->priv->gvcp_fds[1].fd = g_socket_get_fd (gv_fake_camera->priv->discovery_socket); gv_fake_camera->priv->gvcp_fds[1].events = G_IO_IN; gv_fake_camera->priv->gvcp_fds[1].revents = 0; gv_fake_camera->priv->n_gvcp_fds = 2; } else gv_fake_camera->priv->n_gvcp_fds = 1; interface_found = TRUE; } } freeifaddrs (ifap); if (binding_error) { g_clear_object (&gv_fake_camera->priv->gvcp_socket); g_clear_object (&gv_fake_camera->priv->gvsp_socket); g_clear_object (&gv_fake_camera->priv->discovery_socket); return FALSE; } if (!interface_found) { return FALSE; } gv_fake_camera->priv->cancel = FALSE; gv_fake_camera->priv->thread = g_thread_new ("arv_fake_gv_fake_camera", _thread, gv_fake_camera); return TRUE; }
int main (int argc, char *argv[]) { GSocket *socket; GSocketAddress *src_address; GSocketAddress *address; GSocketType socket_type; GSocketFamily socket_family; GError *error = NULL; GOptionContext *context; GCancellable *cancellable; GSocketAddressEnumerator *enumerator; GSocketConnectable *connectable; g_thread_init (NULL); g_type_init (); context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff"); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (argc != 2) { g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name"); return 1; } if (cancel_timeout) { cancellable = g_cancellable_new (); g_thread_create (cancel_thread, cancellable, FALSE, NULL); } else { cancellable = NULL; } loop = g_main_loop_new (NULL, FALSE); if (use_udp) socket_type = G_SOCKET_TYPE_DATAGRAM; else socket_type = G_SOCKET_TYPE_STREAM; if (unix_socket) socket_family = G_SOCKET_FAMILY_UNIX; else socket_family = G_SOCKET_FAMILY_IPV4; socket = g_socket_new (socket_family, socket_type, 0, &error); if (socket == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (read_timeout) g_socket_set_timeout (socket, read_timeout); if (unix_socket) { GSocketAddress *addr; addr = socket_address_from_string (argv[1]); if (addr == NULL) { g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]); return 1; } connectable = G_SOCKET_CONNECTABLE (addr); } else { connectable = g_network_address_parse (argv[1], 7777, &error); if (connectable == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } } enumerator = g_socket_connectable_enumerate (connectable); while (TRUE) { address = g_socket_address_enumerator_next (enumerator, cancellable, &error); if (address == NULL) { if (error == NULL) g_printerr ("%s: No more addresses to try\n", argv[0]); else g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (g_socket_connect (socket, address, cancellable, &error)) break; g_printerr ("%s: Connection to %s failed: %s, trying next\n", argv[0], socket_address_to_string (address), error->message); g_error_free (error); error = NULL; g_object_unref (address); } g_object_unref (enumerator); g_object_unref (connectable); g_print ("Connected to %s\n", socket_address_to_string (address)); /* TODO: Test non-blocking connect */ if (non_blocking) g_socket_set_blocking (socket, FALSE); src_address = g_socket_get_local_address (socket, &error); if (!src_address) { g_printerr ("Error getting local address: %s\n", error->message); return 1; } g_print ("local address: %s\n", socket_address_to_string (src_address)); g_object_unref (src_address); while (TRUE) { gchar buffer[4096]; gssize size; gsize to_send; if (fgets (buffer, sizeof buffer, stdin) == NULL) break; to_send = strlen (buffer); while (to_send > 0) { ensure_condition (socket, "send", cancellable, G_IO_OUT); if (use_udp) size = g_socket_send_to (socket, address, buffer, to_send, cancellable, &error); else size = g_socket_send (socket, buffer, to_send, cancellable, &error); if (size < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_print ("socket send would block, handling\n"); g_error_free (error); error = NULL; continue; } else { g_printerr ("Error sending to socket: %s\n", error->message); return 1; } } g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); if (size == 0) { g_printerr ("Unexpected short write\n"); return 1; } to_send -= size; } ensure_condition (socket, "receive", cancellable, G_IO_IN); if (use_udp) size = g_socket_receive_from (socket, &src_address, buffer, sizeof buffer, cancellable, &error); else size = g_socket_receive (socket, buffer, sizeof buffer, cancellable, &error); if (size < 0) { g_printerr ("Error receiving from socket: %s\n", error->message); return 1; } if (size == 0) break; g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); if (use_udp) g_print (" from %s", socket_address_to_string (src_address)); g_print ("\n"); if (verbose) g_print ("-------------------------\n" "%.*s" "-------------------------\n", (int)size, buffer); } g_print ("closing socket\n"); if (!g_socket_close (socket, &error)) { g_printerr ("Error closing master socket: %s\n", error->message); return 1; } g_object_unref (G_OBJECT (socket)); g_object_unref (G_OBJECT (address)); return 0; }
static gpointer gst_net_client_internal_clock_thread (gpointer data) { GstNetClientInternalClock *self = data; GSocket *socket = self->socket; GError *err = NULL; GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket); g_socket_set_blocking (socket, TRUE); g_socket_set_timeout (socket, 0); while (!g_cancellable_is_cancelled (self->cancel)) { GstClockTime expiration_time = self->timeout_expiration; GstClockTime now = gst_util_get_timestamp (); gint64 socket_timeout; if (now >= expiration_time || (expiration_time - now) <= GST_MSECOND) { socket_timeout = 0; } else { socket_timeout = (expiration_time - now) / GST_USECOND; } GST_TRACE_OBJECT (self, "timeout: %" G_GINT64_FORMAT "us", socket_timeout); if (!g_socket_condition_timed_wait (socket, G_IO_IN, socket_timeout, self->cancel, &err)) { /* cancelled, timeout or error */ if (err->code == G_IO_ERROR_CANCELLED) { GST_INFO_OBJECT (self, "cancelled"); g_clear_error (&err); break; } else if (err->code == G_IO_ERROR_TIMED_OUT) { /* timed out, let's send another packet */ GST_DEBUG_OBJECT (self, "timed out"); if (self->is_ntp) { GstNtpPacket *packet; packet = gst_ntp_packet_new (NULL, NULL); packet->transmit_time = gst_clock_get_internal_time (GST_CLOCK_CAST (self)); GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->transmit_time)); gst_ntp_packet_send (packet, self->socket, self->servaddr, NULL); g_free (packet); } else { GstNetTimePacket *packet; packet = gst_net_time_packet_new (NULL); packet->local_time = gst_clock_get_internal_time (GST_CLOCK_CAST (self)); GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); gst_net_time_packet_send (packet, self->socket, self->servaddr, NULL); g_free (packet); } /* reset timeout (but are expecting a response sooner anyway) */ self->timeout_expiration = gst_util_get_timestamp () + gst_clock_get_timeout (GST_CLOCK_CAST (self)); } else { GST_DEBUG_OBJECT (self, "socket error: %s", err->message); g_usleep (G_USEC_PER_SEC / 10); /* throttle */ } g_clear_error (&err); } else { GstClockTime new_local; /* got packet */ new_local = gst_clock_get_internal_time (GST_CLOCK_CAST (self)); if (self->is_ntp) { GstNtpPacket *packet; packet = gst_ntp_packet_receive (socket, NULL, &err); if (packet != NULL) { GST_LOG_OBJECT (self, "got packet back"); GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->origin_time)); GST_LOG_OBJECT (self, "remote_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->receive_time)); GST_LOG_OBJECT (self, "remote_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->transmit_time)); GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (new_local)); GST_LOG_OBJECT (self, "poll_interval = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->poll_interval)); /* Remember the last poll interval we ever got from the server */ if (packet->poll_interval != GST_CLOCK_TIME_NONE) self->last_remote_poll_interval = packet->poll_interval; /* observe_times will reset the timeout */ gst_net_client_internal_clock_observe_times (self, packet->origin_time, packet->receive_time, packet->transmit_time, new_local); g_free (packet); } else if (err != NULL) { if (g_error_matches (err, GST_NTP_ERROR, GST_NTP_ERROR_WRONG_VERSION) || g_error_matches (err, GST_NTP_ERROR, GST_NTP_ERROR_KOD_DENY)) { GST_ERROR_OBJECT (self, "fatal receive error: %s", err->message); g_clear_error (&err); break; } else if (g_error_matches (err, GST_NTP_ERROR, GST_NTP_ERROR_KOD_RATE)) { GST_WARNING_OBJECT (self, "need to limit rate"); /* If the server did not tell us a poll interval before, double * our minimum poll interval. Otherwise we assume that the server * already told us something sensible and that this error here * was just a spurious error */ if (self->last_remote_poll_interval == GST_CLOCK_TIME_NONE) self->minimum_update_interval *= 2; /* And wait a bit before we send the next packet instead of * sending it immediately */ self->timeout_expiration = gst_util_get_timestamp () + gst_clock_get_timeout (GST_CLOCK_CAST (self)); } else { GST_WARNING_OBJECT (self, "receive error: %s", err->message); } g_clear_error (&err); } } else { GstNetTimePacket *packet; packet = gst_net_time_packet_receive (socket, NULL, &err); if (packet != NULL) { GST_LOG_OBJECT (self, "got packet back"); GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->remote_time)); GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (new_local)); /* observe_times will reset the timeout */ gst_net_client_internal_clock_observe_times (self, packet->local_time, packet->remote_time, packet->remote_time, new_local); g_free (packet); } else if (err != NULL) { GST_WARNING_OBJECT (self, "receive error: %s", err->message); g_clear_error (&err); } } } } GST_INFO_OBJECT (self, "shutting down net client clock thread"); return NULL; }
NiceSocket * nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; NiceSocket *sock; TcpPassivePriv *priv; GSocket *gsock = NULL; gboolean gret = FALSE; GSocketAddress *gaddr; if (addr != NULL) { nice_address_copy_to_sockaddr(addr, &name.addr); } else { memset (&name, 0, sizeof (name)); name.storage.ss_family = AF_UNSPEC; } if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in); #endif } else if (name.storage.ss_family == AF_INET6) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in6); #endif } if (gsock == NULL) { return NULL; } gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_object_unref (gsock); return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); gret = g_socket_bind (gsock, gaddr, FALSE, NULL) && g_socket_listen (gsock, NULL); g_object_unref (gaddr); if (gret == FALSE) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } gaddr = g_socket_get_local_address (gsock, NULL); if (gaddr == NULL || !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_object_unref (gaddr); if (ctx == NULL) { ctx = g_main_context_default (); } sock = g_slice_new0 (NiceSocket); nice_address_set_from_sockaddr (&sock->addr, &name.addr); sock->priv = priv = g_slice_new0 (TcpPassivePriv); priv->context = g_main_context_ref (ctx); priv->connections = g_hash_table_new_full ((GHashFunc) nice_address_hash, (GEqualFunc) nice_address_equal, ( GDestroyNotify) nice_address_free, NULL); priv->writable_cb = NULL; priv->writable_data = NULL; sock->type = NICE_SOCKET_TYPE_TCP_PASSIVE; sock->fileno = gsock; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->close = socket_close; return sock; }
NiceSocket * nice_tcp_bsd_socket_new (GMainContext *ctx, NiceAddress *addr) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; NiceSocket *sock; TcpPriv *priv; GSocket *gsock = NULL; GError *gerr = NULL; gboolean gret = FALSE; GSocketAddress *gaddr; if (addr == NULL) { /* We can't connect a tcp socket with no destination address */ return NULL; } sock = g_slice_new0 (NiceSocket); nice_address_copy_to_sockaddr (addr, &name.addr); if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in); #endif } else if (name.storage.ss_family == AF_INET6) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in6); #endif } if (gsock == NULL) { g_slice_free (NiceSocket, sock); return NULL; } gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_object_unref (gsock); g_slice_free (NiceSocket, sock); return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); gret = g_socket_connect (gsock, gaddr, NULL, &gerr); g_object_unref (gaddr); if (gret == FALSE) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) { g_error_free (gerr); g_socket_close (gsock, NULL); g_object_unref (gsock); g_slice_free (NiceSocket, sock); return NULL; } g_error_free (gerr); } gaddr = g_socket_get_local_address (gsock, NULL); if (gaddr == NULL || !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) { g_slice_free (NiceSocket, sock); g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_object_unref (gaddr); nice_address_set_from_sockaddr (&sock->addr, &name.addr); sock->priv = priv = g_slice_new0 (TcpPriv); if (ctx == NULL) ctx = g_main_context_default (); priv->context = g_main_context_ref (ctx); priv->server_addr = *addr; priv->error = FALSE; sock->fileno = gsock; sock->send_messages = socket_send_messages; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->close = socket_close; return sock; }
static gpointer gst_net_client_clock_thread (gpointer data) { GstNetClientClock *self = data; GstNetTimePacket *packet; GMainContext *ctx; GSourceFuncs funcs = { NULL, }; GSource *source; GIOCondition cond; gboolean timeout; GSocket *socket = self->priv->socket; GError *err = NULL; GstClock *clock = data; GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket); g_socket_set_blocking (socket, TRUE); g_socket_set_timeout (socket, 0); ctx = g_main_context_new (); source = g_socket_create_source (socket, G_IO_IN, self->priv->cancel); g_source_set_name (source, "GStreamer net client clock thread socket"); g_source_set_callback (source, (GSourceFunc) gst_net_client_clock_socket_cb, &cond, NULL); g_source_attach (source, ctx); g_source_unref (source); /* GSocket only support second granularity for timeouts, so roll our own * timeout source (so we don't have to create a new source whenever the * timeout changes, as we would have to do with the default timeout source) */ funcs.prepare = gst_net_client_clock_timeout_source_prepare; funcs.check = gst_net_client_clock_timeout_source_check; funcs.dispatch = gst_net_client_clock_timeout_source_dispatch; funcs.finalize = NULL; source = g_source_new (&funcs, sizeof (GstNetClientClockTimeoutSource)); ((GstNetClientClockTimeoutSource *) source)->clock = self; ((GstNetClientClockTimeoutSource *) source)->p_timeout = &timeout; g_source_set_name (source, "GStreamer net client clock timeout"); g_source_attach (source, ctx); g_source_unref (source); while (!g_cancellable_is_cancelled (self->priv->cancel)) { cond = 0; timeout = FALSE; g_main_context_iteration (ctx, TRUE); if (g_cancellable_is_cancelled (self->priv->cancel)) break; if (timeout) { /* timed out, let's send another packet */ GST_DEBUG_OBJECT (self, "timed out"); packet = gst_net_time_packet_new (NULL); packet->local_time = gst_clock_get_internal_time (GST_CLOCK (self)); GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); gst_net_time_packet_send (packet, self->priv->socket, self->priv->servaddr, NULL); g_free (packet); /* reset timeout (but are expecting a response sooner anyway) */ self->priv->timeout_expiration = gst_util_get_timestamp () + gst_clock_get_timeout (clock); continue; } /* got data to read? */ if ((cond & G_IO_IN)) { GstClockTime new_local; new_local = gst_clock_get_internal_time (GST_CLOCK (self)); packet = gst_net_time_packet_receive (socket, NULL, &err); if (err != NULL) { GST_WARNING_OBJECT (self, "receive error: %s", err->message); g_error_free (err); err = NULL; continue; } GST_LOG_OBJECT (self, "got packet back"); GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->remote_time)); GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (new_local)); /* observe_times will reset the timeout */ gst_net_client_clock_observe_times (self, packet->local_time, packet->remote_time, new_local); g_free (packet); continue; } if ((cond & (G_IO_ERR | G_IO_HUP))) { GST_DEBUG_OBJECT (self, "socket error?! %s", g_strerror (errno)); g_usleep (G_USEC_PER_SEC / 10); continue; } } GST_INFO_OBJECT (self, "shutting down net client clock thread"); g_main_context_unref (ctx); return NULL; }
/* coroutine context */ static void *spice_channel_coroutine(void *data) { SpiceChannel *channel = SPICE_CHANNEL(data); spice_channel *c = channel->priv; int ret; guint verify; SPICE_DEBUG("Started background coroutine %p", &c->coroutine); if (spice_session_get_client_provided_socket(c->session)) { if (c->fd < 0) { g_critical("fd not provided!"); goto cleanup; } if (!(c->sock = g_socket_new_from_fd(c->fd, NULL))) { SPICE_DEBUG("Failed to open socket from fd %d", c->fd); return FALSE; } g_socket_set_blocking(c->sock, FALSE); goto connected; } reconnect: c->sock = spice_session_channel_open_host(c->session, c->tls); if (c->sock == NULL) { if (!c->tls) { SPICE_DEBUG("connection failed, trying with TLS port"); c->tls = true; /* FIXME: does that really work with provided fd */ goto reconnect; } else { SPICE_DEBUG("Connect error"); emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_CONNECT); goto cleanup; } } c->has_error = FALSE; if (c->tls) { int rc; c->ctx = SSL_CTX_new(TLSv1_method()); if (c->ctx == NULL) { g_critical("SSL_CTX_new failed"); goto cleanup; } verify = spice_session_get_verify(c->session); if (verify & (SPICE_SESSION_VERIFY_PUBKEY | SPICE_SESSION_VERIFY_HOSTNAME)) { gchar *ca_file; g_object_get(c->session, "ca-file", &ca_file, NULL); if (ca_file) { rc = SSL_CTX_load_verify_locations(c->ctx, ca_file, NULL); if (rc != 1) g_warning("loading ca certs from %s failed", ca_file); g_free(ca_file); if (rc != 1) { if (verify & SPICE_SESSION_VERIFY_PUBKEY) { g_warning("only pubkey active"); verify = SPICE_SESSION_VERIFY_PUBKEY; } else goto cleanup; } } } c->ssl = SSL_new(c->ctx); if (c->ssl == NULL) { g_critical("SSL_new failed"); goto cleanup; } rc = SSL_set_fd(c->ssl, g_socket_get_fd(c->sock)); if (rc <= 0) { g_critical("SSL_set_fd failed"); goto cleanup; } { gchar *hostname, *subject; guint8 *pubkey; guint pubkey_len; g_object_get(c->session, "host", &hostname, "cert-subject", &subject, NULL); spice_session_get_pubkey(c->session, &pubkey, &pubkey_len); c->sslverify = spice_openssl_verify_new(c->ssl, verify, hostname, (char*)pubkey, pubkey_len, subject); g_free(hostname); g_free(subject); } ssl_reconnect: rc = SSL_connect(c->ssl); if (rc <= 0) { rc = SSL_get_error(c->ssl, rc); if (rc == SSL_ERROR_WANT_READ || rc == SSL_ERROR_WANT_WRITE) { g_io_wait(c->sock, G_IO_OUT|G_IO_ERR|G_IO_HUP); goto ssl_reconnect; } else { g_warning("%s: SSL_connect: %s", c->name, ERR_error_string(rc, NULL)); emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_TLS); goto cleanup; } } } connected: c->state = SPICE_CHANNEL_STATE_LINK_HDR; spice_channel_send_link(channel); while ((ret = spice_channel_iterate(channel))) ; /* TODO: improve it, this is a bit hairy, c->coroutine will be overwritten on (re)connect, so we skip the normal cleanup path. Ideally, we shouldn't use the same channel structure? */ if (c->state == SPICE_CHANNEL_STATE_CONNECTING) { g_object_unref(channel); goto end; } cleanup: SPICE_DEBUG("Coroutine exit"); SPICE_CHANNEL_GET_CLASS(channel)->channel_disconnect(channel); g_idle_add(spice_channel_delayed_unref, data); end: /* Co-routine exits now - the SpiceChannel object may no longer exist, so don't do anything else now unless you like SEGVs */ exit(1); return NULL; }
static void arv_gv_interface_discover (ArvGvInterface *gv_interface) { ArvGvDiscoverSocketList *socket_list; GSList *iter; char buffer[ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE]; int count; int i; socket_list = arv_gv_discover_socket_list_new (); if (socket_list->n_sockets < 1) { arv_gv_discover_socket_list_free (socket_list); return; } arv_gv_discover_socket_list_send_discover_packet (socket_list); do { if (g_poll (socket_list->poll_fds, socket_list->n_sockets, ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0) { arv_gv_discover_socket_list_free (socket_list); return; } for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) { ArvGvDiscoverSocket *discover_socket = iter->data; do { g_socket_set_blocking (discover_socket->socket, FALSE); count = g_socket_receive (discover_socket->socket, buffer, ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE, NULL, NULL); g_socket_set_blocking (discover_socket->socket, TRUE); if (count > 0) { ArvGvcpPacket *packet = (ArvGvcpPacket *) buffer; if (g_ntohs (packet->header.command) == ARV_GVCP_COMMAND_DISCOVERY_ACK && g_ntohs (packet->header.id) == 0xffff) { ArvGvInterfaceDeviceInfos *device_infos; GInetAddress *interface_address; char *address_string; char *data = buffer + sizeof (ArvGvcpHeader); arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); interface_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (discover_socket->interface_address)); device_infos = arv_gv_interface_device_infos_new (interface_address, data); address_string = g_inet_address_to_string (interface_address); arv_debug_interface ("[GvInterface::discovery] Device '%s' found " "(interface %s) user_name '%s' - MAC_name '%s'", device_infos->name, address_string, device_infos->user_name, device_infos->mac_string); g_free (address_string); if (device_infos->name != NULL && device_infos->name[0] != '\0') { arv_gv_interface_device_infos_ref (device_infos); g_hash_table_replace (gv_interface->priv->devices, device_infos->name, device_infos); } if (device_infos->user_name != NULL && device_infos->user_name[0] != '\0') { arv_gv_interface_device_infos_ref (device_infos); g_hash_table_replace (gv_interface->priv->devices, device_infos->user_name, device_infos); } arv_gv_interface_device_infos_ref (device_infos); g_hash_table_replace (gv_interface->priv->devices, device_infos->mac_string, device_infos); arv_gv_interface_device_infos_unref (device_infos); } } } while (count > 0); } } while (1); }
int main (int argc, char *argv[]) { GSocket *socket, *new_socket, *recv_socket; GSocketAddress *src_address; GSocketAddress *address; GSocketType socket_type; GSocketFamily socket_family; GError *error = NULL; GOptionContext *context; GCancellable *cancellable; char *display_addr; GTlsCertificate *tlscert = NULL; GIOStream *connection; GInputStream *istream; GOutputStream *ostream; g_type_init (); context = g_option_context_new (" - Test GSocket server stuff"); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (unix_socket && argc != 2) { g_printerr ("%s: %s\n", argv[0], "Need to specify unix socket name"); return 1; } if (cancel_timeout) { GThread *thread; cancellable = g_cancellable_new (); thread = g_thread_new ("cancel", cancel_thread, cancellable); g_thread_unref (thread); } else { cancellable = NULL; } if (tls_cert_file) { if (use_udp) { g_printerr ("DTLS (TLS over UDP) is not supported"); return 1; } tlscert = g_tls_certificate_new_from_file (tls_cert_file, &error); if (!tlscert) { g_printerr ("Could not read server certificate '%s': %s\n", tls_cert_file, error->message); return 1; } } loop = g_main_loop_new (NULL, FALSE); if (use_udp) socket_type = G_SOCKET_TYPE_DATAGRAM; else socket_type = G_SOCKET_TYPE_STREAM; if (unix_socket) socket_family = G_SOCKET_FAMILY_UNIX; else socket_family = G_SOCKET_FAMILY_IPV4; socket = g_socket_new (socket_family, socket_type, 0, &error); if (socket == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (non_blocking) g_socket_set_blocking (socket, FALSE); if (unix_socket) { src_address = socket_address_from_string (argv[1]); if (src_address == NULL) { g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]); return 1; } } else { src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port); } if (!g_socket_bind (socket, src_address, !dont_reuse_address, &error)) { g_printerr ("Can't bind socket: %s\n", error->message); return 1; } g_object_unref (src_address); if (!use_udp) { if (!g_socket_listen (socket, &error)) { g_printerr ("Can't listen on socket: %s\n", error->message); return 1; } address = g_socket_get_local_address (socket, &error); if (!address) { g_printerr ("Error getting local address: %s\n", error->message); return 1; } display_addr = socket_address_to_string (address); g_print ("listening on %s...\n", display_addr); g_free (display_addr); ensure_socket_condition (socket, G_IO_IN, cancellable); new_socket = g_socket_accept (socket, cancellable, &error); if (!new_socket) { g_printerr ("Error accepting socket: %s\n", error->message); return 1; } if (non_blocking) g_socket_set_blocking (new_socket, FALSE); if (read_timeout) g_socket_set_timeout (new_socket, read_timeout); address = g_socket_get_remote_address (new_socket, &error); if (!address) { g_printerr ("Error getting remote address: %s\n", error->message); return 1; } display_addr = socket_address_to_string (address); g_print ("got a new connection from %s\n", display_addr); g_free(display_addr); g_object_unref (address); recv_socket = new_socket; connection = G_IO_STREAM (g_socket_connection_factory_create_connection (recv_socket)); g_object_unref (new_socket); } else { recv_socket = socket; connection = NULL; } if (tlscert) { GIOStream *tls_conn; tls_conn = g_tls_server_connection_new (connection, tlscert, &error); if (!tls_conn) { g_printerr ("Could not create TLS connection: %s\n", error->message); return 1; } if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn), cancellable, &error)) { g_printerr ("Error during TLS handshake: %s\n", error->message); return 1; } g_object_unref (connection); connection = tls_conn; } if (connection) { istream = g_io_stream_get_input_stream (connection); ostream = g_io_stream_get_output_stream (connection); } else { g_assert (use_udp); istream = NULL; ostream = NULL; } while (TRUE) { gchar buffer[4096]; gssize size; gsize to_send; if (use_udp) { ensure_socket_condition (recv_socket, G_IO_IN, cancellable); size = g_socket_receive_from (recv_socket, &address, buffer, sizeof buffer, cancellable, &error); } else { ensure_connection_condition (connection, G_IO_IN, cancellable); size = g_input_stream_read (istream, buffer, sizeof buffer, cancellable, &error); } if (size < 0) { g_printerr ("Error receiving from socket: %s\n", error->message); return 1; } if (size == 0) break; g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); if (use_udp) g_print (" from %s", socket_address_to_string (address)); g_print ("\n"); if (verbose) g_print ("-------------------------\n" "%.*s\n" "-------------------------\n", (int)size, buffer); to_send = size; #ifdef __QNXNTO__ if (delay_) #else if (delay) #endif { #ifdef __QNXNTO__ if (verbose) g_print ("delaying %d seconds before response\n", delay_); g_usleep (1000 * 1000 * delay_); #else if (verbose) g_print ("delaying %d seconds before response\n", delay); g_usleep (1000 * 1000 * delay); #endif } while (to_send > 0) { if (use_udp) { ensure_socket_condition (recv_socket, G_IO_OUT, cancellable); size = g_socket_send_to (recv_socket, address, buffer, to_send, cancellable, &error); } else { ensure_connection_condition (connection, G_IO_OUT, cancellable); size = g_output_stream_write (ostream, buffer, to_send, cancellable, &error); } if (size < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_print ("socket send would block, handling\n"); g_error_free (error); error = NULL; continue; } else { g_printerr ("Error sending to socket: %s\n", error->message); return 1; } } g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); if (size == 0) { g_printerr ("Unexpected short write\n"); return 1; } to_send -= size; } } g_print ("connection closed\n"); if (connection) { if (!g_io_stream_close (connection, NULL, &error)) { g_printerr ("Error closing connection stream: %s\n", error->message); return 1; } g_object_unref (connection); } if (!g_socket_close (socket, &error)) { g_printerr ("Error closing master socket: %s\n", error->message); return 1; } g_object_unref (socket); return 0; }
int main (int argc, char *argv[]) { GSocket *socket, *new_socket, *recv_socket; GSocketAddress *src_address; GSocketAddress *address; GSocketType socket_type; GError *error = NULL; GOptionContext *context; GCancellable *cancellable; g_thread_init (NULL); g_type_init (); context = g_option_context_new (" - Test GSocket server stuff"); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (cancel_timeout) { cancellable = g_cancellable_new (); g_thread_create (cancel_thread, cancellable, FALSE, NULL); } else { cancellable = NULL; } loop = g_main_loop_new (NULL, FALSE); if (use_udp) socket_type = G_SOCKET_TYPE_DATAGRAM; else socket_type = G_SOCKET_TYPE_STREAM; socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, 0, &error); if (socket == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (non_blocking) g_socket_set_blocking (socket, FALSE); src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port); if (!g_socket_bind (socket, src_address, !dont_reuse_address, &error)) { g_printerr ("Can't bind socket: %s\n", error->message); return 1; } if (!use_udp) { if (!g_socket_listen (socket, &error)) { g_printerr ("Can't listen on socket: %s\n", error->message); return 1; } g_print ("listening on port %d...\n", port); ensure_condition (socket, "accept", cancellable, G_IO_IN); new_socket = g_socket_accept (socket, &error); if (!new_socket) { g_printerr ("Error accepting socket: %s\n", error->message); return 1; } if (non_blocking) g_socket_set_blocking (new_socket, FALSE); address = g_socket_get_remote_address (new_socket, &error); if (!address) { g_printerr ("Error getting remote address: %s\n", error->message); return 1; } g_print ("got a new connection from %s (blocking: %d)\n", socket_address_to_string (address), g_socket_get_blocking (new_socket)); recv_socket = new_socket; } else { recv_socket = socket; new_socket = NULL; } while (TRUE) { gchar buffer[4096] = { }; gssize size; gsize to_send; ensure_condition (recv_socket, "receive", cancellable, G_IO_IN); if (use_udp) size = g_socket_receive_from (recv_socket, &address, buffer, sizeof buffer, &error); else size = g_socket_receive (recv_socket, buffer, sizeof buffer, &error); if (size < 0) { g_printerr ("Error receiving from socket: %s\n", error->message); return 1; } if (size == 0) break; g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); if (use_udp) g_print (" from %s", socket_address_to_string (address)); g_print ("\n"); if (verbose) g_print ("-------------------------\n" "%.*s\n" "-------------------------\n", (int)size, buffer); to_send = size; while (to_send > 0) { ensure_condition (recv_socket, "send", cancellable, G_IO_OUT); if (use_udp) size = g_socket_send_to (recv_socket, address, buffer, to_send, &error); else size = g_socket_send (recv_socket, buffer, to_send, &error); if (size < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_print ("socket send would block, handling\n"); g_error_free (error); error = NULL; continue; } else { g_printerr ("Error sending to socket: %s\n", error->message); return 1; } } g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); if (size == 0) { g_printerr ("Unexpected short write\n"); return 1; } to_send -= size; } } g_print ("connection closed\n"); if (new_socket) { if (!g_socket_close (new_socket, &error)) { g_printerr ("Error closing connection socket: %s\n", error->message); return 1; } g_object_unref (G_OBJECT (new_socket)); } if (!g_socket_close (socket, &error)) { g_printerr ("Error closing master socket: %s\n", error->message); return 1; } g_object_unref (G_OBJECT (socket)); return 0; }