static void
mapped_external_port_cb (GUPnPSimpleIgd *igd, gchar *proto,
    gchar *external_ip, gchar *replaces_external_ip, guint external_port,
    gchar *local_ip, guint local_port, gchar *description, gpointer user_data)
{
  guint requested_external_port = GPOINTER_TO_UINT (user_data);

  g_assert (invalid_ip == NULL);

  if (requested_external_port)
    g_assert (external_port == requested_external_port);
  else if (return_conflict)
    g_assert (external_port != INTERNAL_PORT);
  else
    g_assert (external_port == INTERNAL_PORT);
  g_assert (proto && !strcmp (proto, "UDP"));
  g_assert (local_port == INTERNAL_PORT);
  g_assert (local_ip && !strcmp (local_ip, "192.168.4.22"));
  g_assert (description != NULL);
  g_assert (external_ip);

  if (replaces_external_ip)
  {
    g_assert ((!strcmp (replaces_external_ip, IP_ADDRESS_FIRST) &&
            !strcmp (external_ip, IP_ADDRESS_SECOND)) ||
        (!strcmp (replaces_external_ip, PPP_ADDRESS_FIRST) &&
            !strcmp (external_ip, PPP_ADDRESS_SECOND)));
    if (dispose_removes)
      g_object_unref (igd);
    else
      gupnp_simple_igd_remove_port (igd, "UDP", requested_external_port);
  }
  else
  {
    if (!strcmp (external_ip, IP_ADDRESS_FIRST))
      gupnp_service_notify (GUPNP_SERVICE (ipservice),
          "ExternalIPAddress", G_TYPE_STRING, IP_ADDRESS_SECOND, NULL);
    else if (!strcmp (external_ip, PPP_ADDRESS_FIRST))
      gupnp_service_notify (GUPNP_SERVICE (pppservice),
          "ExternalIPAddress", G_TYPE_STRING, PPP_ADDRESS_SECOND, NULL);
    else
      g_assert_not_reached ();
  }
}
void
fs_rawudp_component_stop (FsRawUdpComponent *self)
{
  UdpPort *udpport = NULL;

  FS_RAWUDP_COMPONENT_LOCK (self);
  if (self->priv->stun_timeout_thread != NULL)
  {
    fs_rawudp_component_stop_stun_locked (self);
    FS_RAWUDP_COMPONENT_UNLOCK (self);
    g_thread_join (self->priv->stun_timeout_thread);
    FS_RAWUDP_COMPONENT_LOCK (self);

    self->priv->stun_timeout_thread = NULL;
  }

  udpport = self->priv->udpport;
  self->priv->udpport = NULL;

  if (udpport)
  {
#ifdef HAVE_GUPNP

    fs_rawudp_component_stop_upnp_discovery_locked (self);

    if (self->priv->upnp_igd  &&
        (self->priv->upnp_mapping || self->priv->upnp_discovery))
    {
      gupnp_simple_igd_remove_port (GUPNP_SIMPLE_IGD (self->priv->upnp_igd),
          "UDP", fs_rawudp_transmitter_udpport_get_port (udpport));
    }
#endif

    if (self->priv->buffer_recv_id)
    {
      fs_rawudp_transmitter_udpport_disconnect_recv (
          udpport,
          self->priv->buffer_recv_id);
      self->priv->buffer_recv_id = 0;
    }

    if (self->priv->remote_candidate)
    {
      if (self->priv->sending)
        fs_rawudp_transmitter_udpport_remove_dest (udpport,
            self->priv->remote_candidate->ip,
            self->priv->remote_candidate->port);
      else
        fs_rawudp_transmitter_udpport_remove_recvonly_dest (udpport,
            self->priv->remote_candidate->ip,
            self->priv->remote_candidate->port);


      fs_rawudp_transmitter_udpport_remove_known_address (udpport,
          self->priv->remote_address, remote_is_unique_cb, self);
    }

    FS_RAWUDP_COMPONENT_UNLOCK (self);

    fs_rawudp_transmitter_put_udpport (self->priv->transmitter, udpport);
  }
  else
    FS_RAWUDP_COMPONENT_UNLOCK (self);
}