static void set_up_mock_xdg_runtime_dir (void) { GError *error = NULL; GSocketAddress *addr; mock_bus = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error); g_assert_no_error (error); g_assert_true (G_IS_SOCKET (mock_bus)); /* alters tmpdir in-place */ if (g_mkdtemp_full (tmpdir, 0700) == NULL) { int errsv = errno; g_error ("g_mkdtemp_full: %s", g_strerror (errsv)); } mock_bus_path = g_strconcat (tmpdir, "/bus", NULL); addr = g_unix_socket_address_new (mock_bus_path); g_socket_bind (mock_bus, addr, FALSE, &error); g_assert_no_error (error); g_object_unref (addr); g_setenv ("XDG_RUNTIME_DIR", tmpdir, TRUE); }
KmsSCTPResult kms_sctp_connection_bind (KmsSCTPConnection * conn, GCancellable * cancellable, GError ** err) { gint bound_port; g_return_val_if_fail (conn != NULL, KMS_SCTP_ERROR); g_return_val_if_fail (conn->socket != NULL, KMS_SCTP_ERROR); g_return_val_if_fail (conn->saddr != NULL, KMS_SCTP_ERROR); /* bind it */ GST_DEBUG ("binding server socket"); if (!g_socket_bind (conn->socket, conn->saddr, TRUE, err)) return KMS_SCTP_ERROR; g_socket_set_listen_backlog (conn->socket, SCTP_BACKLOG); if (!g_socket_listen (conn->socket, err)) return KMS_SCTP_ERROR; bound_port = kms_sctp_connection_get_bound_port (conn); if (bound_port > 0) { GST_DEBUG ("listening on port %d", bound_port); } return KMS_SCTP_OK; }
ArvDevice * arv_gv_device_new (GInetAddress *interface_address, GInetAddress *device_address) { ArvGvDevice *gv_device; ArvGvDeviceIOData *io_data; ArvGvDeviceHeartbeatData *heartbeat_data; char *address_string; g_return_val_if_fail (G_IS_INET_ADDRESS (interface_address), NULL); g_return_val_if_fail (G_IS_INET_ADDRESS (device_address), NULL); address_string = g_inet_address_to_string (interface_address); arv_debug_device ("[GvDevice::new] Interface address = %s", address_string); g_free (address_string); address_string = g_inet_address_to_string (device_address); arv_debug_device ("[GvDevice::new] Device address = %s", address_string); g_free (address_string); gv_device = g_object_new (ARV_TYPE_GV_DEVICE, NULL); io_data = g_new0 (ArvGvDeviceIOData, 1); io_data->mutex = g_mutex_new (); io_data->packet_id = 65300; /* Start near the end of the circular counter */ io_data->interface_address = g_inet_socket_address_new (interface_address, 0); io_data->device_address = g_inet_socket_address_new (device_address, ARV_GVCP_PORT); io_data->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); g_socket_bind (io_data->socket, io_data->interface_address, TRUE, NULL); io_data->buffer = g_malloc (ARV_GV_DEVICE_BUFFER_SIZE); io_data->gvcp_n_retries = ARV_GV_DEVICE_GVCP_N_RETRIES_DEFAULT; io_data->gvcp_timeout_ms = ARV_GV_DEVICE_GVCP_TIMEOUT_MS_DEFAULT; io_data->poll_in_event.fd = g_socket_get_fd (io_data->socket); io_data->poll_in_event.events = G_IO_IN; io_data->poll_in_event.revents = 0; gv_device->priv->io_data = io_data; arv_gv_device_load_genicam (gv_device); arv_gv_device_take_control (gv_device); heartbeat_data = g_new (ArvGvDeviceHeartbeatData, 1); heartbeat_data->gv_device = gv_device; heartbeat_data->io_data = io_data; heartbeat_data->period_us = ARV_GV_DEVICE_HEARTBEAT_PERIOD_US; heartbeat_data->cancel = FALSE; gv_device->priv->heartbeat_data = heartbeat_data; gv_device->priv->heartbeat_thread = g_thread_create (arv_gv_device_heartbeat_thread, gv_device->priv->heartbeat_data, TRUE, NULL); return ARV_DEVICE (gv_device); }
/** * g_socket_listener_add_address: * @listener: a #GSocketListener * @address: a #GSocketAddress * @type: a #GSocketType * @protocol: a #GSocketProtocol * @source_object: (allow-none): Optional #GObject identifying this source * @effective_address: (out) (allow-none): location to store the address that was bound to, or %NULL. * @error: #GError for error reporting, or %NULL to ignore. * * Creates a socket of type @type and protocol @protocol, binds * it to @address and adds it to the set of sockets we're accepting * sockets from. * * Note that adding an IPv6 address, depending on the platform, * may or may not result in a listener that also accepts IPv4 * connections. For more deterministic behavior, see * g_socket_listener_add_inet_port(). * * @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. * * If successful and @effective_address is non-%NULL then it will * be set to the address that the binding actually occurred at. This * is helpful for determining the port number that was used for when * requesting a binding to port 0 (ie: "any port"). This address, if * requested, belongs to the caller and must be freed. * * Returns: %TRUE on success, %FALSE on error. * * Since: 2.22 */ gboolean g_socket_listener_add_address (GSocketListener *listener, GSocketAddress *address, GSocketType type, GSocketProtocol protocol, GObject *source_object, GSocketAddress **effective_address, GError **error) { GSocketAddress *local_address; GSocketFamily family; GSocket *socket; if (!check_listener (listener, error)) return FALSE; family = g_socket_address_get_family (address); socket = g_socket_new (family, type, protocol, error); if (socket == NULL) return FALSE; g_socket_set_listen_backlog (socket, listener->priv->listen_backlog); if (!g_socket_bind (socket, address, TRUE, error) || !g_socket_listen (socket, error)) { g_object_unref (socket); return FALSE; } local_address = NULL; if (effective_address) { local_address = g_socket_get_local_address (socket, error); if (local_address == NULL) { g_object_unref (socket); return FALSE; } } if (!g_socket_listener_add_socket (listener, socket, source_object, error)) { if (local_address) g_object_unref (local_address); g_object_unref (socket); return FALSE; } if (effective_address) *effective_address = local_address; g_object_unref (socket); /* add_socket refs this */ return TRUE; }
static void arv_gv_interface_build_discover_infos_list (ArvGvInterface *gv_interface) { struct ifaddrs *ifap = NULL; struct ifaddrs *ifap_iter; int return_value; arv_gv_interface_free_discover_infos_list (gv_interface); return_value = getifaddrs (&ifap); if (return_value < 0) return; for (ifap_iter = ifap; ifap_iter != NULL; ifap_iter = ifap_iter->ifa_next) { if ((ifap_iter->ifa_flags & IFF_UP) != 0 && (ifap_iter->ifa_flags & IFF_POINTOPOINT) == 0 && (ifap_iter->ifa_addr->sa_family == AF_INET)) { ArvGvInterfaceDiscoverInfos *infos = g_new (ArvGvInterfaceDiscoverInfos, 1); GSocketAddress *socket_address; GInetAddress *inet_address; char *inet_address_string; GError *error = NULL; socket_address = g_socket_address_new_from_native (ifap_iter->ifa_addr, sizeof (struct sockaddr)); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address)); inet_address_string = g_inet_address_to_string (inet_address); arv_debug_interface ("[GvInterface::build_discover_infos_list] Add interface %s", inet_address_string); g_free (inet_address_string); infos->interface_address = g_inet_socket_address_new (inet_address, 0); 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)); infos->broadcast_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT); inet_address_string = g_inet_address_to_string (inet_address); arv_debug_interface ("[GvInterface::build_discover_infos_list] Broadcast address is %s", inet_address_string); g_free (inet_address_string); g_object_unref (socket_address); infos->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); g_socket_bind (infos->socket, infos->interface_address, TRUE, &error); gv_interface->priv->discover_infos_list = g_slist_prepend (gv_interface->priv->discover_infos_list, infos); gv_interface->priv->n_discover_infos++; } } freeifaddrs (ifap); }
static ArvGvDiscoverSocketList * arv_gv_discover_socket_list_new (void) { ArvGvDiscoverSocketList *socket_list; GSList *iter; struct ifaddrs *ifap = NULL; struct ifaddrs *ifap_iter; int i; socket_list = g_new0 (ArvGvDiscoverSocketList, 1); if (getifaddrs (&ifap) < 0) return socket_list; for (ifap_iter = ifap; ifap_iter != NULL; ifap_iter = ifap_iter->ifa_next) { if ((ifap_iter->ifa_flags & IFF_UP) != 0 && (ifap_iter->ifa_flags & IFF_POINTOPOINT) == 0 && (ifap_iter->ifa_addr != NULL) && (ifap_iter->ifa_addr->sa_family == AF_INET)) { ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1); GSocketAddress *socket_address; GInetAddress *inet_address; char *inet_address_string; GError *error = NULL; socket_address = g_socket_address_new_from_native (ifap_iter->ifa_addr, sizeof (struct sockaddr)); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address)); inet_address_string = g_inet_address_to_string (inet_address); arv_debug_interface ("[GvDiscoverSocket::new] Add interface %s", inet_address_string); g_free (inet_address_string); discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0); g_object_unref (socket_address); discover_socket->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); g_socket_bind (discover_socket->socket, discover_socket->interface_address, TRUE, &error); socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); socket_list->n_sockets++; } } freeifaddrs (ifap); socket_list->poll_fds = g_new (GPollFD, socket_list->n_sockets); for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) { ArvGvDiscoverSocket *discover_socket = iter->data; socket_list->poll_fds[i].fd = g_socket_get_fd (discover_socket->socket); socket_list->poll_fds[i].events = G_IO_IN; socket_list->poll_fds[i].revents = 0; } return socket_list; }
GSocket *create_socket(void) { GSocket *sock; GSocketAddress *addr; sock = g_socket_new( G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, NULL); addr = g_unix_socket_address_new(EMACS_FCITX_SOCKET); unlink(EMACS_FCITX_SOCKET); g_socket_bind(sock, addr, FALSE, NULL); g_socket_listen(sock, NULL); return sock; }
int main(int argc, char *argv[]) { GError *err = NULL; GSocket *serv_gsock; GSocketAddress *gaddr; struct sockaddr_in addr; /* Create socket */ serv_gsock = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, 0, &err); if (!serv_gsock) { printf("GSocket creation failure: %s\n", err->message); g_clear_error(&err); } /* Bind to 127.0.0.1 */ bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(10086); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); gaddr = g_socket_address_new_from_native(&addr, sizeof(addr)); if (!g_socket_bind(serv_gsock, gaddr, TRUE, &err)) { printf("GSocket bind failure: %s\n", err->message); g_clear_error(&err); } /* Listen */ if (!g_socket_listen(serv_gsock, &err)) { printf("GSocket listen failure: %s\n", err->message); g_clear_error(&err); } /* Accept */ gchar buffer[256]; gsize bytes_read; GSocket *clnt_gsock; clnt_gsock = g_socket_accept(serv_gsock, NULL, &err); bytes_read = g_socket_receive(clnt_gsock, buffer, 256, NULL, &err); printf("%u read: <%s>\n", (unsigned int)bytes_read, buffer); return 0; }
GSocket *multicast_createSocket(gchar *interface, gchar *groupaddress, guint port, GSocketAddress **sa) { GError *err = NULL; GInetAddress *addr = g_inet_address_new_from_string(groupaddress); *sa = g_inet_socket_address_new(addr,port); GSocket *socket = g_socket_new(G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); ub_assert(socket != NULL); int on = 1; setsockopt(g_socket_get_fd(socket), SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if( g_socket_bind(socket, *sa, TRUE, &err) == FALSE ){ syslog(LOG_ERR, "net_createSockets: Error while binding udp socket: %s\n", err->message); g_error_free(err); g_object_unref(*sa); g_object_unref(socket); return NULL; } struct addrinfo *resmulti; struct ipv6_mreq mreq; mreq.ipv6mr_interface = if_nametoindex(interface); gchar *tmp = g_inet_address_to_string(addr); syslog(LOG_DEBUG,"using address: %s\n",tmp); int ret = getaddrinfo(tmp, NULL, NULL, &resmulti); g_free(tmp); if( ret ){ syslog(LOG_ERR,"net_multicast.c: %s", gai_strerror(ret)); g_object_unref(*sa); g_object_unref(socket); return NULL; } mreq.ipv6mr_multiaddr = ((struct sockaddr_in6 *)resmulti->ai_addr)->sin6_addr; setsockopt(g_socket_get_fd(socket), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); return socket; }
static GSocket * create_socket (GSocketClient *client, GSocketAddress *dest_address, GError **error) { GSocketFamily family; GSocket *socket; family = client->priv->family; if (family == G_SOCKET_FAMILY_INVALID && client->priv->local_address != NULL) family = g_socket_address_get_family (client->priv->local_address); if (family == G_SOCKET_FAMILY_INVALID) family = g_socket_address_get_family (dest_address); socket = g_socket_new (family, client->priv->type, client->priv->protocol, error); if (socket == NULL) return NULL; if (client->priv->local_address) { if (!g_socket_bind (socket, client->priv->local_address, FALSE, error)) { g_object_unref (socket); return NULL; } } if (client->priv->timeout) g_socket_set_timeout (socket, client->priv->timeout); return socket; }
GSocket * _client_create_local_socket (GError **error) { GSocket *socket = NULL; GInetAddress * inet_address = NULL; GSocketAddress *socket_address = NULL; /* Create the IPv4 socket, and listen for connection on it */ socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, error); if (socket != NULL) { inet_address = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); socket_address = g_inet_socket_address_new (inet_address, 0); g_socket_bind (socket, socket_address, FALSE, error); } tp_clear_object (&inet_address); tp_clear_object (&socket_address); return socket; }
/** * g_vfs_ftp_connection_listen_data_connection: * @conn: a connection * @error: %NULL or location to take potential errors * * Initiates a listening socket that the FTP server can connect to. To accept * connections and initialize data transfers, use * g_vfs_ftp_connection_accept_data_connection(). * This function supports what is known as "active FTP", while * g_vfs_ftp_connection_open_data_connection() is to be used for "passive FTP". * * Returns: the actual address the socket is listening on or %NULL on error **/ GSocketAddress * g_vfs_ftp_connection_listen_data_connection (GVfsFtpConnection *conn, GError ** error) { GSocketAddress *local, *addr; g_return_val_if_fail (conn != NULL, NULL); g_return_val_if_fail (conn->data == NULL, NULL); g_vfs_ftp_connection_stop_listening (conn); local = g_socket_connection_get_local_address (conn->connection, error); if (local == NULL) return NULL; conn->listen_socket = g_socket_new (g_socket_address_get_family (local), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, error); if (conn->listen_socket == NULL) return NULL; g_assert (G_IS_INET_SOCKET_ADDRESS (local)); addr = g_inet_socket_address_new (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (local)), 0); g_object_unref (local); if (!g_socket_bind (conn->listen_socket, addr, TRUE, error) || !g_socket_listen (conn->listen_socket, error) || !(local = g_socket_get_local_address (conn->listen_socket, error))) { g_object_unref (addr); g_vfs_ftp_connection_stop_listening (conn); return NULL; } g_object_unref (addr); return local; }
static gboolean net_createUDPSocket(struct node *n, guint classid) { GError * err = NULL; GInetAddress *addr = n->netadr; guint port = 2300+n->classes[classid]; syslog(LOG_DEBUG,"net_createSockets: Creating udp socket on port %u\n", port); GSocketAddress * sa = g_inet_socket_address_new(addr,port); n->udpsockets[classid].n = n; GSocket *socket = g_socket_new(G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); ub_assert(socket != NULL); if( g_socket_bind(socket, sa, TRUE, &err) == FALSE ){ syslog(LOG_WARNING, "net_createSockets: Error while binding udp socket: %s\n", err->message); g_error_free(err); return FALSE; } GSource *source = g_socket_create_source(socket, G_IO_IN, NULL); ub_assert(source != NULL); g_source_set_callback(source, (GSourceFunc)udp_read, &(n->udpsockets[classid]) , NULL); g_source_attach(source, g_main_context_default()); n->udpsockets[classid].socket = socket; n->udpsockets[classid].source = source; n->udpsockets[classid].socketaddress = sa; n->udpsockets[classid].classid = classid; //broadcast_addService(n->classes[classid]); return TRUE; }
static ArvGvDiscoverSocketList * arv_gv_discover_socket_list_new (void) { ArvGvDiscoverSocketList *socket_list; GInetAddress *broadcast_address; GSList *iter; const char *envar; struct ifaddrs *ifap = NULL; struct ifaddrs *ifap_iter; int i; socket_list = g_new0 (ArvGvDiscoverSocketList, 1); if (getifaddrs (&ifap) < 0) return socket_list; broadcast_address = g_inet_address_new_from_string ("255.255.255.255"); for (ifap_iter = ifap; ifap_iter != NULL; ifap_iter = ifap_iter->ifa_next) { if ((ifap_iter->ifa_flags & IFF_UP) != 0 && (ifap_iter->ifa_flags & IFF_POINTOPOINT) == 0 && (ifap_iter->ifa_addr != NULL) && (ifap_iter->ifa_addr->sa_family == AF_INET)) { ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1); GSocketAddress *socket_address; GInetAddress *inet_address; char *inet_address_string; GError *error = NULL; socket_address = g_socket_address_new_from_native (ifap_iter->ifa_addr, sizeof (struct sockaddr)); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address)); inet_address_string = g_inet_address_to_string (inet_address); arv_debug_interface ("[GvDiscoverSocket::new] Add interface %s", inet_address_string); g_free (inet_address_string); discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0); g_object_unref (socket_address); discover_socket->target_address = g_inet_socket_address_new (broadcast_address, ARV_GVCP_PORT); discover_socket->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); g_socket_bind (discover_socket->socket, discover_socket->interface_address, TRUE, &error); socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); socket_list->n_sockets++; } } g_object_unref (broadcast_address); freeifaddrs (ifap); if ((envar=g_getenv("ARV_IPS"))!=NULL) { gchar **ips_alloc, **ips, *addr; ips_alloc = ips = g_strsplit(envar, ":", -1); for (addr = *ips; addr; addr = *++ips) { ArvGvDiscoverSocket *discover_socket; GSocketAddress *target_addr = g_inet_socket_address_new_from_string(addr, ARV_GVCP_PORT); if(!target_addr) continue; discover_socket = g_new0 (ArvGvDiscoverSocket, 1); discover_socket->target_address = target_addr; discover_socket->interface_address = g_inet_socket_address_new_from_string("0.0.0.0", ARV_GVCP_PORT); /* TODO, wrong */ discover_socket->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); /* implict bind of wildcard w/ arbitrary port */ arv_debug_interface("[GvDiscoverSocket::new] Add unicast destination %s", addr); socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket); socket_list->n_sockets++; } g_strfreev(ips_alloc); } socket_list->poll_fds = g_new (GPollFD, socket_list->n_sockets); for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) { ArvGvDiscoverSocket *discover_socket = iter->data; socket_list->poll_fds[i].fd = g_socket_get_fd (discover_socket->socket); socket_list->poll_fds[i].events = G_IO_IN; socket_list->poll_fds[i].revents = 0; } return socket_list; }
static gboolean gssdp_socket_source_do_init (GInitable *initable, G_GNUC_UNUSED GCancellable *cancellable, GError **error) { GSSDPSocketSource *self = NULL; GInetAddress *iface_address = NULL; GSocketAddress *bind_address = NULL; GInetAddress *group = NULL; GError *inner_error = NULL; GSocketFamily family; gboolean success = FALSE; self = GSSDP_SOCKET_SOURCE (initable); iface_address = g_inet_address_new_from_string (self->priv->host_ip); if (iface_address == NULL) { g_set_error (error, GSSDP_ERROR, GSSDP_ERROR_FAILED, "Invalid host ip: %s", self->priv->host_ip); goto error; } family = g_inet_address_get_family (iface_address); if (family == G_SOCKET_FAMILY_IPV4) group = g_inet_address_new_from_string (SSDP_ADDR); else { g_set_error_literal (error, GSSDP_ERROR, GSSDP_ERROR_FAILED, "IPv6 address"); goto error; } /* Create socket */ self->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &inner_error); if (!self->priv->socket) { g_propagate_prefixed_error (error, inner_error, "Could not create socket"); goto error; } /* Enable broadcasting */ if (!gssdp_socket_enable_broadcast (self->priv->socket, TRUE, &inner_error)) { g_propagate_prefixed_error (error, inner_error, "Failed to enable broadcast"); goto error; } /* TTL */ if (!self->priv->ttl) /* UDA/1.0 says 4, UDA/1.1 says 2 */ self->priv->ttl = 4; if (!gssdp_socket_set_ttl (self->priv->socket, self->priv->ttl, &inner_error)) { g_propagate_prefixed_error (error, inner_error, "Failed to set TTL to %u", self->priv->ttl); goto error; } /* Set up additional things according to the type of socket desired */ if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) { /* Enable multicast loopback */ if (!gssdp_socket_enable_loop (self->priv->socket, TRUE, &inner_error)) { g_propagate_prefixed_error ( error, inner_error, "Failed to enable loop-back"); goto error; } if (!gssdp_socket_mcast_interface_set (self->priv->socket, iface_address, &inner_error)) { g_propagate_prefixed_error ( error, inner_error, "Failed to set multicast interface"); goto error; } #ifdef G_OS_WIN32 bind_address = g_inet_socket_address_new (iface_address, SSDP_PORT); #else bind_address = g_inet_socket_address_new (group, SSDP_PORT); #endif } else { guint port = SSDP_PORT; /* Use user-supplied or random port for the socket source used * by M-SEARCH */ if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_SEARCH) port = self->priv->port; bind_address = g_inet_socket_address_new (iface_address, port); } /* Normally g_socket_bind does this, but it is disabled on * windows since SO_REUSEADDR has different semantics * there, also we nees SO_REUSEPORT on OpenBSD. This is a nop * everywhere else. */ if (!gssdp_socket_reuse_address (self->priv->socket, TRUE, &inner_error)) { g_propagate_prefixed_error ( error, inner_error, "Failed to enable reuse"); goto error; } /* Bind to requested port and address */ if (!g_socket_bind (self->priv->socket, bind_address, TRUE, &inner_error)) { g_propagate_prefixed_error (error, inner_error, "Failed to bind socket"); goto error; } if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) { /* Subscribe to multicast channel */ if (!gssdp_socket_mcast_group_join (self->priv->socket, group, iface_address, &inner_error)) { char *address = g_inet_address_to_string (group); g_propagate_prefixed_error (error, inner_error, "Failed to join group %s", address); g_free (address); goto error; } } self->priv->source = g_socket_create_source (self->priv->socket, G_IO_IN | G_IO_ERR, NULL); success = TRUE; error: if (iface_address != NULL) g_object_unref (iface_address); if (bind_address != NULL) g_object_unref (bind_address); if (group != NULL) g_object_unref (group); if (!success) /* Be aware that inner_error has already been free'd by * g_propagate_error(), so we cannot access its contents * anymore. */ if (error == NULL) g_warning ("Failed to create socket source"); return success; }
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; }
/* set up server */ static gboolean gst_tcp_server_src_start (GstBaseSrc * bsrc) { GstTCPServerSrc *src = GST_TCP_SERVER_SRC (bsrc); GError *err = NULL; GInetAddress *addr; GSocketAddress *saddr; GResolver *resolver; /* look up name if we need to */ addr = g_inet_address_new_from_string (src->host); if (!addr) { GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, src->host, src->cancellable, &err); if (!results) goto name_resolve; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } #ifndef GST_DISABLE_GST_DEBUG { gchar *ip = g_inet_address_to_string (addr); GST_DEBUG_OBJECT (src, "IP address for host %s is %s", src->host, ip); g_free (ip); } #endif saddr = g_inet_socket_address_new (addr, src->server_port); g_object_unref (addr); /* create the server listener socket */ src->server_socket = g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &err); if (!src->server_socket) goto no_socket; GST_DEBUG_OBJECT (src, "opened receiving server socket"); /* bind it */ GST_DEBUG_OBJECT (src, "binding server socket to address"); if (!g_socket_bind (src->server_socket, saddr, TRUE, &err)) goto bind_failed; g_object_unref (saddr); GST_DEBUG_OBJECT (src, "listening on server socket"); g_socket_set_listen_backlog (src->server_socket, TCP_BACKLOG); if (!g_socket_listen (src->server_socket, &err)) goto listen_failed; GST_OBJECT_FLAG_SET (src, GST_TCP_SERVER_SRC_OPEN); return TRUE; /* ERRORS */ no_socket: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to create socket: %s", err->message)); g_clear_error (&err); g_object_unref (saddr); return FALSE; } name_resolve: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (src, "Cancelled name resolval"); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to resolve host '%s': %s", src->host, err->message)); } g_clear_error (&err); g_object_unref (resolver); return FALSE; } bind_failed: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (src, "Cancelled binding"); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to bind on host '%s:%d': %s", src->host, src->server_port, err->message)); } g_clear_error (&err); g_object_unref (saddr); gst_tcp_server_src_stop (GST_BASE_SRC (src)); return FALSE; } listen_failed: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (src, "Cancelled listening"); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to listen on host '%s:%d': %s", src->host, src->server_port, err->message)); } g_clear_error (&err); gst_tcp_server_src_stop (GST_BASE_SRC (src)); return FALSE; } }
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; } }
ArvStream * arv_gv_stream_new (GInetAddress *device_address, guint16 port, ArvStreamCallback callback, void *user_data, guint64 timestamp_tick_frequency, guint packet_size) { ArvGvStream *gv_stream; ArvStream *stream; GInetAddress *incoming_inet_address; ArvGvStreamThreadData *thread_data; g_return_val_if_fail (G_IS_INET_ADDRESS (device_address), NULL); g_return_val_if_fail (packet_size > ARV_GVSP_PACKET_PROTOCOL_OVERHEAD, NULL); gv_stream = g_object_new (ARV_TYPE_GV_STREAM, NULL); stream = ARV_STREAM (gv_stream); gv_stream->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); incoming_inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); gv_stream->incoming_address = g_inet_socket_address_new (incoming_inet_address, port); g_object_unref (incoming_inet_address); g_socket_bind (gv_stream->socket, gv_stream->incoming_address, TRUE, NULL); thread_data = g_new (ArvGvStreamThreadData, 1); thread_data->stream = stream; thread_data->callback = callback; thread_data->user_data = user_data; thread_data->socket = gv_stream->socket; thread_data->device_address = g_inet_socket_address_new (device_address, ARV_GVCP_PORT); thread_data->packet_resend = ARV_GV_STREAM_PACKET_RESEND_ALWAYS; thread_data->packet_timeout_us = ARV_GV_STREAM_PACKET_TIMEOUT_US_DEFAULT; thread_data->frame_retention_us = ARV_GV_STREAM_FRAME_RETENTION_US_DEFAULT; thread_data->timestamp_tick_frequency = timestamp_tick_frequency; thread_data->data_size = packet_size - ARV_GVSP_PACKET_PROTOCOL_OVERHEAD; thread_data->cancel = FALSE; thread_data->packet_id = 65300; thread_data->last_frame_id = 0; thread_data->n_completed_buffers = 0; thread_data->n_failures = 0; thread_data->n_underruns = 0; thread_data->n_aborteds = 0; thread_data->n_timeouts = 0; thread_data->n_missing_frames = 0; thread_data->n_size_mismatch_errors = 0; thread_data->n_received_packets = 0; thread_data->n_missing_packets = 0; thread_data->n_error_packets = 0; thread_data->n_ignored_packets = 0; thread_data->n_resent_packets = 0; thread_data->n_resend_requests = 0; thread_data->n_duplicated_packets = 0; thread_data->statistic = arv_statistic_new (1, 5000, 200, 0); thread_data->statistic_count = 0; arv_statistic_set_name (thread_data->statistic, 0, "Buffer reception time"); thread_data->socket_buffer_option = ARV_GV_STREAM_SOCKET_BUFFER_FIXED; thread_data->socket_buffer_size = 0; thread_data->current_socket_buffer_size = 0; gv_stream->thread_data = thread_data; gv_stream->thread = arv_g_thread_new ("arv_gv_stream", arv_gv_stream_thread, gv_stream->thread_data); return ARV_STREAM (gv_stream); }
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; }
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; } }
/* 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; } }
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; }
static gint initRTP(AirplayRenderer *self, gint *controlPort, gint *timingPort) { AirplayRendererPrivate *priv = AIRPLAY_RENDERER_GET_PRIVATE(self); if(priv->dataSocket) { g_object_unref(priv->dataSocket); priv->dataSocket = NULL; } if(priv->controlSocket) { g_object_unref(priv->controlSocket); priv->controlSocket = NULL; } if(priv->timingSocket) { g_object_unref(priv->timingSocket); priv->timingSocket = NULL; } GError *error = NULL; struct sockaddr_in addr4; struct sockaddr_in6 addr6; gushort *sinPort = NULL; if(priv->socketFamily == G_SOCKET_FAMILY_IPV4) { memset(&addr4, 0, sizeof(addr4)); addr4.sin_family = AF_INET; addr4.sin_addr.s_addr = htonl(INADDR_ANY); sinPort = &(addr4.sin_port); } else { memset(&addr6, 0, sizeof(addr6)); addr6.sin6_family = AF_INET6; addr6.sin6_addr = in6addr_any; addr6.sin6_flowinfo = 0; sinPort = &(addr6.sin6_port); } gint port = 6000; GSocket *dataSocket = NULL; GSocket *controlSocket = NULL; GSocket *timingSocket = NULL; gint serverPort = -1; for(; TRUE; port += 3) { if(!dataSocket) { dataSocket = g_socket_new(priv->socketFamily, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error); if(error) { g_printerr("AirplayRenderer: data socket create failed: %s\n", error->message); return 0; } } if(!controlSocket) { controlSocket = g_socket_new(priv->socketFamily, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error); if(error) { g_printerr("AirplayRenderer: control socket create failed: %s\n", error->message); return 0; } } if(!timingSocket) { timingSocket = g_socket_new(priv->socketFamily, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error); if(error) { g_printerr("AirplayRenderer: timing socket create failed: %s\n", error->message); return 0; } } *sinPort = htons(port); GSocketAddress *addr = NULL; if(priv->socketFamily == G_SOCKET_FAMILY_IPV4) { addr = g_socket_address_new_from_native(&addr4, sizeof(addr4)); } else { addr = g_socket_address_new_from_native(&addr6, sizeof(addr6)); } if(!g_socket_bind(dataSocket, addr, TRUE, &error)) { g_socket_close(dataSocket, &error); continue; } else { serverPort = port; } g_object_unref(addr); *sinPort = htons(port + 1); if(priv->socketFamily == G_SOCKET_FAMILY_IPV4) { addr = g_socket_address_new_from_native(&addr4, sizeof(addr4)); } else { addr = g_socket_address_new_from_native(&addr6, sizeof(addr6)); } if(!g_socket_bind(controlSocket, addr, TRUE, &error)) { g_socket_close(controlSocket, &error); continue; } else { *controlPort = port + 1; } g_object_unref(addr); *sinPort = htons(port + 2); if(priv->socketFamily == G_SOCKET_FAMILY_IPV4) { addr = g_socket_address_new_from_native(&addr4, sizeof(addr4)); } else { addr = g_socket_address_new_from_native(&addr6, sizeof(addr6)); } if(!g_socket_bind(timingSocket, addr, TRUE, &error)) { g_socket_close(timingSocket, &error); continue; } else { *timingPort = port + 2; } g_object_unref(addr); break; } priv->dataSocket = dataSocket; priv->controlSocket = controlSocket; priv->timingSocket = timingSocket; gint fd = g_socket_get_fd(dataSocket); gint nRcvbuf = 81920 * 4; setsockopt(fd, SOL_SOCKET,SO_RCVBUF, (char *)&nRcvbuf, sizeof(gint)); // gint nNetTimeout = 5000; // setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(gint)); priv->dataChannel = g_io_channel_unix_new(fd); priv->dataWatchID = g_io_add_watch(priv->dataChannel, G_IO_IN, (GIOFunc)dataRead, self); fd = g_socket_get_fd(controlSocket); priv->controlChannel = g_io_channel_unix_new(fd); priv->controlWatchID = g_io_add_watch(priv->controlChannel, G_IO_IN, (GIOFunc)controlRead, self); fd = g_socket_get_fd(timingSocket); priv->timingChannel = g_io_channel_unix_new(fd); priv->timingWatchID = g_io_add_watch(priv->timingChannel, G_IO_IN, (GIOFunc)timingRead, self); return serverPort; }
/* create a socket for sending to remote machine */ static gboolean gst_multiudpsink_start (GstBaseSink * bsink) { GstMultiUDPSink *sink; GList *clients; GstUDPClient *client; GError *err = NULL; sink = GST_MULTIUDPSINK (bsink); sink->external_socket = FALSE; if (sink->socket) { GST_DEBUG_OBJECT (sink, "using configured socket"); if (g_socket_get_family (sink->socket) == G_SOCKET_FAMILY_IPV6) { sink->used_socket_v6 = G_SOCKET (g_object_ref (sink->socket)); sink->external_socket = TRUE; } else { sink->used_socket = G_SOCKET (g_object_ref (sink->socket)); sink->external_socket = TRUE; } } if (sink->socket_v6) { GST_DEBUG_OBJECT (sink, "using configured IPv6 socket"); g_return_val_if_fail (g_socket_get_family (sink->socket) != G_SOCKET_FAMILY_IPV6, FALSE); if (sink->used_socket_v6 && sink->used_socket_v6 != sink->socket_v6) { GST_ERROR_OBJECT (sink, "Provided different IPv6 sockets in socket and socket-v6 properties"); return FALSE; } sink->used_socket_v6 = G_SOCKET (g_object_ref (sink->socket_v6)); sink->external_socket = TRUE; } if (!sink->used_socket && !sink->used_socket_v6) { GSocketAddress *bind_addr; GInetAddress *bind_iaddr; if (sink->bind_address) { GSocketFamily family; bind_iaddr = g_inet_address_new_from_string (sink->bind_address); if (!bind_iaddr) { GList *results; GResolver *resolver; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, sink->bind_address, sink->cancellable, &err); if (!results) { g_object_unref (resolver); goto name_resolve; } bind_iaddr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port); g_object_unref (bind_iaddr); family = g_socket_address_get_family (G_SOCKET_ADDRESS (bind_addr)); if ((sink->used_socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL) { g_object_unref (bind_addr); goto no_socket; } g_socket_bind (sink->used_socket, bind_addr, TRUE, &err); if (err != NULL) goto bind_error; } else { /* create sender sockets if none available */ if ((sink->used_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL) goto no_socket; bind_iaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port); g_socket_bind (sink->used_socket, bind_addr, TRUE, &err); g_object_unref (bind_addr); g_object_unref (bind_iaddr); if (err != NULL) goto bind_error; if ((sink->used_socket_v6 = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL) { GST_INFO_OBJECT (sink, "Failed to create IPv6 socket: %s", err->message); g_clear_error (&err); } else { bind_iaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6); bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port); g_socket_bind (sink->used_socket_v6, bind_addr, TRUE, &err); g_object_unref (bind_addr); g_object_unref (bind_iaddr); if (err != NULL) goto bind_error; } } } #ifdef SO_SNDBUF { socklen_t len; gint sndsize, ret; len = sizeof (sndsize); if (sink->buffer_size != 0) { sndsize = sink->buffer_size; GST_DEBUG_OBJECT (sink, "setting udp buffer of %d bytes", sndsize); /* set buffer size, Note that on Linux this is typically limited to a * maximum of around 100K. Also a minimum of 128 bytes is required on * Linux. */ if (sink->used_socket) { ret = setsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, len); if (ret != 0) { GST_ELEMENT_WARNING (sink, RESOURCE, SETTINGS, (NULL), ("Could not create a buffer of requested %d bytes, %d: %s", sndsize, ret, g_strerror (errno))); } } if (sink->used_socket_v6) { ret = setsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, len); if (ret != 0) { GST_ELEMENT_WARNING (sink, RESOURCE, SETTINGS, (NULL), ("Could not create a buffer of requested %d bytes, %d: %s", sndsize, ret, g_strerror (errno))); } } } /* read the value of the receive buffer. Note that on linux this returns 2x the * value we set because the kernel allocates extra memory for metadata. * The default on Linux is about 100K (which is about 50K without metadata) */ if (sink->used_socket) { ret = getsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, &len); if (ret == 0) GST_DEBUG_OBJECT (sink, "have UDP buffer of %d bytes", sndsize); else GST_DEBUG_OBJECT (sink, "could not get UDP buffer size"); } if (sink->used_socket_v6) { ret = getsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, &len); if (ret == 0) GST_DEBUG_OBJECT (sink, "have UDPv6 buffer of %d bytes", sndsize); else GST_DEBUG_OBJECT (sink, "could not get UDPv6 buffer size"); } } #endif #ifdef SO_BINDTODEVICE if (sink->multi_iface) { if (sink->used_socket) { setsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET, SO_BINDTODEVICE, sink->multi_iface, strlen (sink->multi_iface)); } if (sink->used_socket_v6) { setsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET, SO_BINDTODEVICE, sink->multi_iface, strlen (sink->multi_iface)); } } #endif if (sink->used_socket) g_socket_set_broadcast (sink->used_socket, TRUE); if (sink->used_socket_v6) g_socket_set_broadcast (sink->used_socket_v6, TRUE); sink->bytes_to_serve = 0; sink->bytes_served = 0; gst_multiudpsink_setup_qos_dscp (sink, sink->used_socket); gst_multiudpsink_setup_qos_dscp (sink, sink->used_socket_v6); /* look for multicast clients and join multicast groups appropriately set also ttl and multicast loopback delivery appropriately */ for (clients = sink->clients; clients; clients = g_list_next (clients)) { client = (GstUDPClient *) clients->data; if (!gst_multiudpsink_configure_client (sink, client)) return FALSE; } return TRUE; /* ERRORS */ no_socket: { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL), ("Could not create socket: %s", err->message)); g_clear_error (&err); return FALSE; } bind_error: { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL), ("Failed to bind socket: %s", err->message)); g_clear_error (&err); return FALSE; } name_resolve: { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL), ("Failed to resolve bind address %s: %s", sink->bind_address, err->message)); g_clear_error (&err); return FALSE; } }
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; }
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; } }
/** * g_socket_listener_add_inet_port: * @listener: a #GSocketListener * @port: an IP port number (non-zero) * @source_object: (allow-none): Optional #GObject identifying this source * @error: #GError for error reporting, or %NULL to ignore. * * Helper function for g_socket_listener_add_address() that * creates a TCP/IP socket listening on IPv4 and IPv6 (if * supported) on the specified port on all interfaces. * * @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: %TRUE on success, %FALSE on error. * * Since: 2.22 */ gboolean g_socket_listener_add_inet_port (GSocketListener *listener, guint16 port, GObject *source_object, GError **error) { gboolean need_ipv4_socket = TRUE; GSocket *socket4 = NULL; GSocket *socket6; g_return_val_if_fail (listener != NULL, FALSE); g_return_val_if_fail (port != 0, FALSE); if (!check_listener (listener, error)) return FALSE; /* first try to create an IPv6 socket */ socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, NULL); if (socket6 != NULL) /* IPv6 is supported on this platform, so if we fail now it is * a result of being unable to bind to our port. Don't fail * silently as a result of this! */ { GInetAddress *inet_address; GSocketAddress *address; gboolean result; inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6); address = g_inet_socket_address_new (inet_address, port); g_object_unref (inet_address); g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog); result = g_socket_bind (socket6, address, TRUE, error) && g_socket_listen (socket6, error); g_object_unref (address); if (!result) { g_object_unref (socket6); return FALSE; } if (source_object) g_object_set_qdata_full (G_OBJECT (socket6), source_quark, g_object_ref (source_object), g_object_unref); /* If this socket already speaks IPv4 then we are done. */ if (g_socket_speaks_ipv4 (socket6)) need_ipv4_socket = FALSE; } if (need_ipv4_socket) /* We are here for exactly one of the following reasons: * * - our platform doesn't support IPv6 * - we successfully created an IPv6 socket but it's V6ONLY * * In either case, we need to go ahead and create an IPv4 socket * and fail the call if we can't bind to it. */ { socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, error); if (socket4 != NULL) /* IPv4 is supported on this platform, so if we fail now it is * a result of being unable to bind to our port. Don't fail * silently as a result of this! */ { GInetAddress *inet_address; GSocketAddress *address; gboolean result; inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); address = g_inet_socket_address_new (inet_address, port); g_object_unref (inet_address); g_socket_set_listen_backlog (socket4, listener->priv->listen_backlog); result = g_socket_bind (socket4, address, TRUE, error) && g_socket_listen (socket4, error); g_object_unref (address); if (!result) { g_object_unref (socket4); if (socket6 != NULL) g_object_unref (socket6); return FALSE; } if (source_object) g_object_set_qdata_full (G_OBJECT (socket4), source_quark, g_object_ref (source_object), g_object_unref); } else /* Ok. So IPv4 is not supported on this platform. If we * succeeded at creating an IPv6 socket then that's OK, but * otherwise we need to tell the user we failed. */ { if (socket6 != NULL) g_clear_error (error); else return FALSE; } } g_assert (socket6 != NULL || socket4 != NULL); if (socket6 != NULL) g_ptr_array_add (listener->priv->sockets, socket6); if (socket4 != NULL) g_ptr_array_add (listener->priv->sockets, socket4); if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed) G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener); return TRUE; }
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; }
/** * 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; }