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);