static void kms_rtp_endpoint_set_addr (KmsRtpEndpoint * self) { GList *ips, *l; gboolean done = FALSE; ips = nice_interfaces_get_local_ips (FALSE); for (l = ips; l != NULL && !done; l = l->next) { GInetAddress *addr; gboolean is_ipv6 = FALSE; addr = g_inet_address_new_from_string (l->data); if (G_IS_INET_ADDRESS (addr)) { switch (g_inet_address_get_family (addr)) { case G_SOCKET_FAMILY_INVALID: case G_SOCKET_FAMILY_UNIX: /* Ignore this addresses */ break; case G_SOCKET_FAMILY_IPV6: is_ipv6 = TRUE; case G_SOCKET_FAMILY_IPV4: { gchar *addr_str; gboolean use_ipv6; g_object_get (self, "use-ipv6", &use_ipv6, NULL); if (is_ipv6 != use_ipv6) { GST_DEBUG_OBJECT (self, "No valid address type: %d", is_ipv6); break; } addr_str = g_inet_address_to_string (addr); if (addr_str != NULL) { KmsBaseSdpEndpoint *base_sdp = KMS_BASE_SDP_ENDPOINT (self); KmsSdpAgent *agent = kms_base_sdp_endpoint_get_sdp_agent (base_sdp); g_object_set (agent, "addr", addr_str, NULL); g_free (addr_str); done = TRUE; } break; } } } if (G_IS_OBJECT (addr)) { g_object_unref (addr); } } g_list_free_full (ips, g_free); if (!done) { GST_WARNING_OBJECT (self, "Addr not set"); } }
static gboolean fs_msn_open_listening_port_unlock (FsMsnConnection *self, guint16 port, GError **error) { gint fd = -1; struct sockaddr_in myaddr; guint myaddr_len = sizeof (struct sockaddr_in); FsCandidate * candidate = NULL; GList *addresses = nice_interfaces_get_local_ips (FALSE); GList *item = NULL; gchar *session_id; addresses = filter_ips_ipv4 (addresses); GST_DEBUG ("Attempting to listen on port %d.....",port); if ( (fd = socket(PF_INET, SOCK_STREAM, 0)) < 0 ) { gchar error_str[256]; strerror_r (errno, error_str, 256); g_set_error (error, FS_ERROR, FS_ERROR_NETWORK, "Could not create socket: %s", error_str); goto error; } // set non-blocking mode fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); for (;;) { GST_DEBUG ("Attempting to listen on port %d.....",port); memset(&myaddr, 0, sizeof(myaddr)); myaddr.sin_family = AF_INET; myaddr.sin_port = htons (port); // bind if (bind(fd, (struct sockaddr *) &myaddr, sizeof(myaddr)) != 0) { if (port != 0 && errno == EADDRINUSE) { port++; } else { gchar error_str[256]; strerror_r (errno, error_str, 256); g_set_error (error, FS_ERROR, FS_ERROR_NETWORK, "Could not bind socket: %s", error_str); goto error; } } else { /* Listen */ if (listen(fd, 3) != 0) { if (port != 0 && errno == EADDRINUSE) { port++; } else { gchar error_str[256]; strerror_r (errno, error_str, 256); g_set_error (error, FS_ERROR, FS_ERROR_NETWORK, "Could not listen on socket: %s", error_str); goto error; } } else { goto done; } } } done: if (getsockname (fd, (struct sockaddr *) &myaddr, &myaddr_len) < 0) { gchar error_str[256]; strerror_r (errno, error_str, 256); g_set_error (error, FS_ERROR, FS_ERROR_NETWORK, "Could not get the socket name: %s", error_str); goto error; } port = ntohs (myaddr.sin_port); add_pollfd_locked (self, fd, accept_connection_cb, TRUE, TRUE, FALSE); GST_DEBUG ("Listening on port %d", port); self->local_recipient_id = g_strdup_printf ("%d", g_random_int_range (100, 199)); session_id = g_strdup_printf ("%u", self->session_id); FS_MSN_CONNECTION_UNLOCK (self); for (item = addresses; item; item = g_list_next (item)) { candidate = fs_candidate_new (self->local_recipient_id, 1, FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_TCP, item->data, port); candidate->username = g_strdup (session_id); g_signal_emit (self, signals[SIGNAL_NEW_LOCAL_CANDIDATE], 0, candidate); fs_candidate_destroy (candidate); } g_free (session_id); g_list_foreach (addresses, (GFunc) g_free, NULL); g_list_free (addresses); return TRUE; error: if (fd >= 0) close (fd); g_list_foreach (addresses, (GFunc) g_free, NULL); g_list_free (addresses); FS_MSN_CONNECTION_UNLOCK (self); return FALSE; }
gboolean fs_rawudp_component_gather_local_candidates (FsRawUdpComponent *self, GError **error) { if (self->priv->gathered) { g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS, "Call gather local candidates twice on the same component"); return FALSE; } if (!self->priv->udpport) { g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS, "You can not call gather_local_candidate() after the stream has" " been stopped"); return FALSE; } #ifdef HAVE_GUPNP if (self->priv->upnp_igd && (self->priv->upnp_mapping || self->priv->upnp_discovery)) { guint port; GList *ips; port = fs_rawudp_transmitter_udpport_get_port (self->priv->udpport); ips = nice_interfaces_get_local_ips (FALSE); ips = filter_ips (ips, TRUE, FALSE); if (ips) { gchar *ip = g_list_first (ips)->data; GMainContext *ctx; if (self->priv->upnp_discovery) { FS_RAWUDP_COMPONENT_LOCK (self); self->priv->upnp_signal_id = g_signal_connect (self->priv->upnp_igd, "mapped-external-port", G_CALLBACK (_upnp_mapped_external_port), self); FS_RAWUDP_COMPONENT_UNLOCK (self); } GST_DEBUG ("Doing UPnP Discovery for local ip:%s port:%u", ip, port); gupnp_simple_igd_add_port (GUPNP_SIMPLE_IGD (self->priv->upnp_igd), "UDP", port, ip, port, self->priv->upnp_mapping_timeout, "Farstream Raw UDP transmitter " PACKAGE_VERSION); if (self->priv->upnp_discovery) { FS_RAWUDP_COMPONENT_LOCK (self); self->priv->upnp_discovery_timeout_src = g_timeout_source_new_seconds ( self->priv->upnp_discovery_timeout); g_source_set_callback (self->priv->upnp_discovery_timeout_src, _upnp_discovery_timeout, self, NULL); g_object_get (self->priv->upnp_igd, "main-context", &ctx, NULL); g_source_attach (self->priv->upnp_discovery_timeout_src, ctx); FS_RAWUDP_COMPONENT_UNLOCK (self); } } else { FS_RAWUDP_COMPONENT_LOCK (self); fs_rawudp_component_stop_upnp_discovery_locked (self); FS_RAWUDP_COMPONENT_UNLOCK (self); } /* free list of ips */ g_list_foreach (ips, (GFunc) g_free, NULL); g_list_free (ips); } #endif if (self->priv->stun_ip) return fs_rawudp_component_start_stun (self, error); #ifdef HAVE_GUPNP else if (!self->priv->upnp_signal_id) return fs_rawudp_component_emit_local_candidates (self, error); else return TRUE; #else else return fs_rawudp_component_emit_local_candidates (self, error);