Exemplo n.º 1
0
/*
 * Resets the component state to that of a ICE restarted
 * session.
 */
gboolean
component_restart (Component *cmp)
{
  GSList *i;

  for (i = cmp->remote_candidates; i; i = i->next) {
    NiceCandidate *candidate = i->data;

    /* note: do not remove the remote candidate that is
     *       currently part of the 'selected pair', see ICE
     *       9.1.1.1. "ICE Restarts" (ID-19) */
    if (candidate == cmp->selected_pair.remote) {
      if (cmp->restart_candidate)
	nice_candidate_free (cmp->restart_candidate);
      cmp->restart_candidate = candidate;
    }
    else 
      nice_candidate_free (candidate);
  }
  g_slist_free (cmp->remote_candidates),
    cmp->remote_candidates = NULL;

  for (i = cmp->incoming_checks; i; i = i->next) {
    IncomingCheck *icheck = i->data;
    g_free (icheck->username);
    g_slice_free (IncomingCheck, icheck);
  }
  g_slist_free (cmp->incoming_checks);
  cmp->incoming_checks = NULL;

  /* note: component state managed by agent */

  return TRUE;
}
Exemplo n.º 2
0
/*
 * Resets the component state to that of a ICE restarted
 * session.
 */
void
nice_component_restart (NiceComponent *cmp)
{
  GSList *i;

  for (i = cmp->remote_candidates; i; i = i->next) {
    NiceCandidate *candidate = i->data;

    /* note: do not remove the local candidate that is
     *       currently part of the 'selected pair', see ICE
     *       9.1.1.1. "ICE Restarts" (ID-19) */
    if (candidate == cmp->selected_pair.remote) {
      if (cmp->restart_candidate)
	nice_candidate_free (cmp->restart_candidate);
      cmp->restart_candidate = candidate;
    }
    else 
      nice_candidate_free (candidate);
  }
  g_slist_free (cmp->remote_candidates),
    cmp->remote_candidates = NULL;

  g_slist_free_full (cmp->incoming_checks,
      (GDestroyNotify) incoming_check_free);
  cmp->incoming_checks = NULL;

  /* Reset the priority to 0 to make sure we get a new pair */
  cmp->selected_pair.priority = 0;

  /* note: component state managed by agent */
}
Exemplo n.º 3
0
void
nice_component_clean_turn_servers (NiceComponent *cmp)
{
  GSList *i;

  g_list_free_full (cmp->turn_servers, (GDestroyNotify) turn_server_unref);
  cmp->turn_servers = NULL;

  for (i = cmp->local_candidates; i;) {
    NiceCandidate *candidate = i->data;
    GSList *next = i->next;

    if (candidate->type != NICE_CANDIDATE_TYPE_RELAYED) {
      i = next;
      continue;
    }

    /* note: do not remove the remote candidate that is
     *       currently part of the 'selected pair', see ICE
     *       9.1.1.1. "ICE Restarts" (ID-19)
     *
     * So what we do instead is that we put the selected candidate
     * in a special location and keep it "alive" that way. This is
     * especially important for TURN, because refresh requests to the
     * server need to keep happening.
     */
    if (candidate == cmp->selected_pair.local) {
      if (cmp->turn_candidate) {
        refresh_prune_candidate (cmp->agent, cmp->turn_candidate);
        discovery_prune_socket (cmp->agent, cmp->turn_candidate->sockptr);
        conn_check_prune_socket (cmp->agent, cmp->stream, cmp,
            cmp->turn_candidate->sockptr);
        nice_component_detach_socket (cmp, cmp->turn_candidate->sockptr);
	nice_candidate_free (cmp->turn_candidate);
      }
      /* Bring the priority down to 0, so that it will be replaced
       * on the new run.
       */
      cmp->selected_pair.priority = 0;
      cmp->turn_candidate = candidate;
    } else {
      refresh_prune_candidate (cmp->agent, candidate);
      discovery_prune_socket (cmp->agent, candidate->sockptr);
      conn_check_prune_socket (cmp->agent, cmp->stream, cmp,
          candidate->sockptr);
      nice_component_detach_socket (cmp, candidate->sockptr);
      agent_remove_local_candidate (cmp->agent, candidate);
      nice_candidate_free (candidate);
    }
    cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i);
    i = next;
  }
}
Exemplo n.º 4
0
/*
 * Changes the selected pair for the component to 'pair'. Does not
 * emit the "selected-pair-changed" signal.
 */ 
void
nice_component_update_selected_pair (NiceComponent *component, const CandidatePair *pair)
{
  g_assert (component);
  g_assert (pair);
  nice_debug ("setting SELECTED PAIR for component %u: %s:%s (prio:%"
      G_GUINT64_FORMAT ").", component->id, pair->local->foundation,
      pair->remote->foundation, pair->priority);

  if (component->selected_pair.local &&
      component->selected_pair.local == component->turn_candidate) {
    refresh_prune_candidate (component->agent, component->turn_candidate);
    discovery_prune_socket (component->agent,
        component->turn_candidate->sockptr);
    conn_check_prune_socket (component->agent, component->stream, component,
        component->turn_candidate->sockptr);
    nice_component_detach_socket (component, component->turn_candidate->sockptr);
    nice_candidate_free (component->turn_candidate);
    component->turn_candidate = NULL;
  }

  nice_component_clear_selected_pair (component);

  component->selected_pair.local = pair->local;
  component->selected_pair.remote = pair->remote;
  component->selected_pair.priority = pair->priority;
  component->selected_pair.prflx_priority = pair->prflx_priority;
}
Exemplo n.º 5
0
/*
 * Creates a server reflexive candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
NiceCandidate*
discovery_add_server_reflexive_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceCandidateTransport transport,
  NiceSocket *base_socket,
  gboolean nat_assisted)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  gboolean result = FALSE;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return NULL;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE);
  candidate->transport = transport;
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;

  /* step: link to the base candidate+socket */
  candidate->sockptr = base_socket;
  candidate->base_addr = base_socket->addr;

  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, nat_assisted);
  } else {
    candidate->priority =  nice_candidate_ice_priority (candidate,
        agent->reliable, nat_assisted);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_generate_candidate_credentials (agent, candidate);
  priv_assign_foundation (agent, candidate);

  result = priv_add_local_candidate_pruned (agent, stream_id, component, candidate);
  if (result) {
    agent_signal_new_candidate (agent, candidate);
  }
  else {
    /* error: duplicate candidate */
    nice_candidate_free (candidate), candidate = NULL;
  }

  return candidate;
}
Exemplo n.º 6
0
static KmsIceCandidate *
kms_ice_nice_agent_get_default_local_candidate (KmsIceBaseAgent * self,
    const char *stream_id, guint component_id)
{
  KmsIceNiceAgent *nice_agent = KMS_ICE_NICE_AGENT (self);
  NiceCandidate *nice_cand;
  KmsIceCandidate *ret = NULL;
  guint id = atoi (stream_id);
  KmsSdpSession *sdp_sess = KMS_SDP_SESSION (nice_agent->priv->session);
  SdpMessageContext *local_sdp_ctx = sdp_sess->local_sdp_ctx;
  const GSList *item = kms_sdp_message_context_get_medias (local_sdp_ctx);

  nice_cand =
      nice_agent_get_default_local_candidate (nice_agent->priv->agent, id,
      component_id);

  for (; item != NULL; item = g_slist_next (item)) {
    SdpMediaConfig *mconf = item->data;
    gint idx = kms_sdp_media_config_get_id (mconf);
    const gchar *mid;
    gchar *media_stream_id;

    if (kms_sdp_media_config_is_inactive (mconf)) {
      GST_DEBUG_OBJECT (self, "Media (id=%d) inactive", idx);
      continue;
    }

    media_stream_id =
        kms_webrtc_session_get_stream_id (nice_agent->priv->session, mconf);
    if (media_stream_id == NULL) {
      goto end;
    }

    if (media_stream_id != stream_id) {
      goto end;
    }

    mid = kms_sdp_media_config_get_mid (mconf);

    if (mid != NULL) {
      ret = kms_ice_candidate_new_from_nice (nice_agent->priv->agent, nice_cand,
          mid, idx);
      goto end;
    }
  }

end:
  nice_candidate_free (nice_cand);

  return ret;
}
Exemplo n.º 7
0
static void set_candidates (NiceAgent *from, guint from_stream,
    NiceAgent *to, guint to_stream, guint component, gboolean remove_non_relay)
{
  GSList *cands = NULL, *i;

  cands = nice_agent_get_local_candidates (from, from_stream, component);
  if (remove_non_relay) {
  restart:
    for (i = cands; i; i = i->next) {
      NiceCandidate *cand = i->data;
      if (cand->type != NICE_CANDIDATE_TYPE_RELAYED) {
        cands = g_slist_remove (cands, cand);
        nice_candidate_free (cand);
        goto restart;
      }
    }
  }
  nice_agent_set_remote_candidates (to, to_stream, component, cands);

  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
}
Exemplo n.º 8
0
static void set_candidates (NiceAgent *from, guint from_stream,
    NiceAgent *to, guint to_stream, guint component)
{
  GSList *cands = NULL, *i;

  cands = nice_agent_get_local_candidates (from, from_stream, component);

 restart:
  for (i = cands; i; i = i->next) {
    NiceCandidate *cand = i->data;
    if (cand->transport == NICE_CANDIDATE_TRANSPORT_UDP) {
      cands = g_slist_remove (cands, cand);
      nice_candidate_free (cand);
      goto restart;
    }
  }


  nice_agent_set_remote_candidates (to, to_stream, component, cands);

  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
}
Exemplo n.º 9
0
static void priv_get_local_addr (NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *dstaddr)
{
  GSList *cands, *i;
  cands = nice_agent_get_local_candidates(agent, stream_id, component_id);
  for (i = cands; i; i = i->next) {
    NiceCandidate *cand = i->data;
    if (cand) {
      g_assert (dstaddr);
      *dstaddr = cand->addr;
    }
  }
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
}
Exemplo n.º 10
0
static NiceCandidate *
parse_candidate(char *scand, guint stream_id)
{
  NiceCandidate *cand = NULL;
  NiceCandidateType ntype;
  gchar **tokens = NULL;
  guint i;

  tokens = g_strsplit (scand, ",", 5);
  for (i = 0; tokens[i]; i++);
  if (i != 5)
    goto end;

  for (i = 0; i < G_N_ELEMENTS (candidate_type_name); i++) {
    if (strcmp(tokens[4], candidate_type_name[i]) == 0) {
      ntype = i;
      break;
    }
  }
  if (i == G_N_ELEMENTS (candidate_type_name))
    goto end;

  cand = nice_candidate_new(ntype);
  cand->component_id = 1;
  cand->stream_id = stream_id;
  cand->transport = NICE_CANDIDATE_TRANSPORT_UDP;
  strncpy(cand->foundation, tokens[0], NICE_CANDIDATE_MAX_FOUNDATION);
  cand->foundation[NICE_CANDIDATE_MAX_FOUNDATION - 1] = 0;
  cand->priority = atoi (tokens[1]);

  if (!nice_address_set_from_string(&cand->addr, tokens[2])) {
    g_message("failed to parse addr: %s", tokens[2]);
    nice_candidate_free(cand);
    cand = NULL;
    goto end;
  }

  nice_address_set_port(&cand->addr, atoi (tokens[3]));

 end:
  g_strfreev(tokens);

  return cand;
}
Exemplo n.º 11
0
static GSList *priv_get_local_candidate (NiceAgent *agent, guint stream_id, guint component_id)
{
  GSList *cands, *i;
  GSList *result = NULL;
  NiceCandidate *out_cand = NULL;
  cands = nice_agent_get_local_candidates(agent, stream_id, component_id);
  for (i = cands; i; i = i->next) {
    NiceCandidate *cand = i->data;
    if (cand) {
      out_cand = cand;
    }
  }
  result = g_slist_append (result, nice_candidate_copy (out_cand));

  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
  return result;
}
Exemplo n.º 12
0
int
main (void)
{
  NiceAgent *agent;
  NiceAddress addr;
  guint stream;

  nice_address_init (&addr);
  g_type_init ();
  g_thread_init(NULL);

  loop = g_main_loop_new (NULL, FALSE);

  agent = nice_agent_new (g_main_loop_get_context (loop), NICE_COMPATIBILITY_RFC5245);
  nice_address_set_ipv4 (&addr, 0x7f000001);
  nice_agent_add_local_address (agent, &addr);
  stream = nice_agent_add_stream (agent, 1);
  nice_agent_gather_candidates (agent, stream);

  // attach to default main context
  nice_agent_attach_recv (agent, stream, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (loop), recv_cb, GUINT_TO_POINTER (42));

    {
      NiceCandidate *candidate;
      GSList *candidates, *i;

      candidates = nice_agent_get_local_candidates (agent, 1, 1);
      candidate = candidates->data;

      nice_socket_send (candidate->sockptr, &(candidate->addr), 6, "\x80hello");
      for (i = candidates; i; i = i->next)
        nice_candidate_free ((NiceCandidate *) i->data);
      g_slist_free (candidates);
    }

  g_main_loop_run (loop);

  g_object_unref (agent);
  return 0;
}
Exemplo n.º 13
0
static gboolean
kms_ice_nice_agent_add_ice_candidate (KmsIceBaseAgent * self,
    KmsIceCandidate * candidate, const char *stream_id)
{
  KmsIceNiceAgent *nice_agent = KMS_ICE_NICE_AGENT (self);
  NiceCandidate *nice_cand;
  guint id = atoi (stream_id);
  gboolean ret;
  GSList *candidates;
  const gchar *cand_str;

  GST_DEBUG_OBJECT (self, "Add ICE candidate '%s'",
      kms_ice_candidate_get_candidate (candidate));

  ret = kms_ice_candidate_create_nice (candidate, &nice_cand);
  if (nice_cand == NULL) {
    return ret;
  }

  nice_cand->stream_id = id;
  cand_str = kms_ice_candidate_get_candidate (candidate);
  candidates = g_slist_append (NULL, nice_cand);

  if (nice_agent_set_remote_candidates (nice_agent->priv->agent,
          nice_cand->stream_id, nice_cand->component_id, candidates) < 0) {
    GST_WARNING_OBJECT (self, "Cannot add candidate: '%s'in stream_id: %d.",
        cand_str, nice_cand->stream_id);
    ret = FALSE;
  } else {
    GST_TRACE_OBJECT (self, "Candidate added: '%s' in stream_id: %d.",
        cand_str, nice_cand->stream_id);
    ret = TRUE;
  }

  g_slist_free (candidates);
  nice_candidate_free (nice_cand);

  return ret;
}
Exemplo n.º 14
0
void
nice_component_remove_socket (NiceComponent *cmp, NiceSocket *nsocket)
{
  GSList *i;

  for (i = cmp->local_candidates; i;) {
    NiceCandidate *candidate = i->data;
    GSList *next = i->next;

    if (!nice_socket_is_based_on (candidate->sockptr, nsocket)) {
      i = next;
      continue;
    }

    if (candidate == cmp->selected_pair.local) {
      nice_component_clear_selected_pair (cmp);
      agent_signal_component_state_change (cmp->agent, cmp->stream->id,
          cmp->id, NICE_COMPONENT_STATE_FAILED);
    }

    refresh_prune_candidate (cmp->agent, candidate);
    if (candidate->sockptr != nsocket) {
      discovery_prune_socket (cmp->agent, candidate->sockptr);
      conn_check_prune_socket (cmp->agent, cmp->stream, cmp,
          candidate->sockptr);
      nice_component_detach_socket (cmp, candidate->sockptr);
    }
    agent_remove_local_candidate (cmp->agent, candidate);
    nice_candidate_free (candidate);

    cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i);
    i = next;
  }

  discovery_prune_socket (cmp->agent, nsocket);
  conn_check_prune_socket (cmp->agent, cmp->stream, cmp, nsocket);
  nice_component_detach_socket (cmp, nsocket);
}
Exemplo n.º 15
0
static gchar *
kms_ice_nice_agent_generate_local_candidate_sdp (KmsIceBaseAgent * self,
    KmsIceCandidate * candidate)
{
  KmsIceNiceAgent *nice_agent = KMS_ICE_NICE_AGENT (self);
  NiceCandidate *nice_cand;
  gchar *ret;

  GST_DEBUG_OBJECT (self, "Add ICE candidate '%s'",
      kms_ice_candidate_get_candidate (candidate));

  kms_ice_candidate_create_nice (candidate, &nice_cand);
  if (nice_cand == NULL) {
    return NULL;
  }

  ret =
      nice_agent_generate_local_candidate_sdp (nice_agent->priv->agent,
      nice_cand);
  nice_candidate_free (nice_cand);

  return ret;
}
Exemplo n.º 16
0
/*
 * Creates a server reflexive candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
NiceCandidate*
discovery_add_relay_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceCandidateTransport transport,
  NiceSocket *base_socket,
  TurnServer *turn)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  NiceSocket *relay_socket = NULL;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return NULL;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_RELAYED);
  candidate->transport = transport;
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;
  candidate->turn = turn_server_ref (turn);

  /* step: link to the base candidate+socket */
  relay_socket = nice_udp_turn_socket_new (agent->main_context, address,
      base_socket, &turn->server,
      turn->username, turn->password,
      agent_to_turn_socket_compatibility (agent));
  if (!relay_socket)
    goto errors;

  candidate->sockptr = relay_socket;
  candidate->base_addr = base_socket->addr;

  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, FALSE);
  } else {
    candidate->priority =  nice_candidate_ice_priority (candidate,
        agent->reliable, FALSE);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_generate_candidate_credentials (agent, candidate);

  /* Google uses the turn username as the candidate username */
  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    g_free (candidate->username);
    candidate->username = g_strdup (turn->username);
  }

  priv_assign_foundation (agent, candidate);

  if (!priv_add_local_candidate_pruned (agent, stream_id, component, candidate))
    goto errors;

  nice_component_attach_socket (component, relay_socket);
  agent_signal_new_candidate (agent, candidate);

  return candidate;

errors:
  nice_candidate_free (candidate);
  if (relay_socket)
    nice_socket_free (relay_socket);
  return NULL;
}
Exemplo n.º 17
0
nsresult
createNiceCandidate(otIICECandidate *aCandidate, PRUint32 aStreamID,
                    NiceCandidate **_retval)
{
  nsresult res;
  PRInt16 val16;
  PRUint32 val32;
  nsCString valStr;
  NiceCandidate *cand;

  res = aCandidate->GetType(&val16);
  if (NS_FAILED(res))
    return res;

  cand = nice_candidate_new((NiceCandidateType)val16);

  cand->transport = NICE_CANDIDATE_TRANSPORT_UDP;

  res = aCandidate->GetIp(valStr);
  if (NS_FAILED(res))
    goto fail;

  nice_address_set_from_string(&cand->addr, valStr.get());

  res = aCandidate->GetPort(&val32);
  if (NS_FAILED(res))
    goto fail;

  nice_address_set_port(&cand->addr, val32);

  res = aCandidate->GetPriority(&val32);
  if (NS_FAILED(res))
    goto fail;
  cand->priority = val32;

  cand->stream_id = aStreamID;

  res = aCandidate->GetComponent(&val32);
  if (NS_FAILED(res))
    goto fail;
  cand->component_id = val32;

  res = aCandidate->GetFoundation(valStr);
  if (NS_FAILED(res))
    goto fail;
  strncpy(cand->foundation, valStr.get(), NICE_CANDIDATE_MAX_FOUNDATION);

  res = aCandidate->GetUfrag(valStr);
  if (NS_FAILED(res))
    goto fail;
  if (!valStr.IsEmpty())
    cand->username = strdup(valStr.get());

  res = aCandidate->GetPwd(valStr);
  if (NS_FAILED(res))
    goto fail;
  if (!valStr.IsEmpty())
    cand->password = strdup(valStr.get());

  res = aCandidate->GetRelIp(valStr);
  if (NS_FAILED(res))
    goto fail;

  if (!valStr.IsEmpty()) {
    nice_address_set_from_string(&cand->base_addr, valStr.get());

    res = aCandidate->GetRelPort(&val32);
    if (NS_FAILED(res))
      goto fail;

    nice_address_set_port(&cand->base_addr, val32);
  }

  *_retval = cand;

  return NS_OK;

fail:
  nice_candidate_free(cand);
  return res;
}
Exemplo n.º 18
0
otICECandidate::~otICECandidate() {
  nice_candidate_free(mCandidate);
}
Exemplo n.º 19
0
/*
 * Creates a peer reflexive candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
NiceCandidate*
discovery_add_peer_reflexive_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceSocket *base_socket,
  NiceCandidate *local,
  NiceCandidate *remote)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  gboolean result;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return NULL;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_PEER_REFLEXIVE);
  if (local)
    candidate->transport = local->transport;
  else if (remote)
    candidate->transport = conn_check_match_transport (remote->transport);
  else {
    if (base_socket->type == NICE_SOCKET_TYPE_UDP_BSD ||
        base_socket->type == NICE_SOCKET_TYPE_UDP_TURN)
      candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
    else
      candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE;
  }
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;
  candidate->sockptr = base_socket;
  candidate->base_addr = base_socket->addr;

  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, FALSE);
  } else {
    candidate->priority = nice_candidate_ice_priority (candidate,
        agent->reliable, FALSE);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_assign_foundation (agent, candidate);

  if ((agent->compatibility == NICE_COMPATIBILITY_MSN ||
       agent->compatibility == NICE_COMPATIBILITY_OC2007) &&
      remote && local) {
    guchar *new_username = NULL;
    guchar *decoded_local = NULL;
    guchar *decoded_remote = NULL;
    gsize local_size;
    gsize remote_size;
    g_free(candidate->username);
    g_free(candidate->password);

    decoded_local = g_base64_decode (local->username, &local_size);
    decoded_remote = g_base64_decode (remote->username, &remote_size);

    new_username = g_new0(guchar, local_size + remote_size);
    memcpy(new_username, decoded_local, local_size);
    memcpy(new_username + local_size, decoded_remote, remote_size);

    candidate->username = g_base64_encode (new_username, local_size + remote_size);
    g_free(new_username);
    g_free(decoded_local);
    g_free(decoded_remote);

    candidate->password = g_strdup(local->password);
  } else if (local) {
    g_free(candidate->username);
    g_free(candidate->password);

    candidate->username = g_strdup(local->username);
    candidate->password = g_strdup(local->password);
  }

  result = priv_add_local_candidate_pruned (agent, stream_id, component, candidate);
  if (result != TRUE) {
    /* error: memory allocation, or duplicate candidate */
    nice_candidate_free (candidate), candidate = NULL;
  }

  return candidate;
}
Exemplo n.º 20
0
static int run_full_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed)
{
  guint ls_id, rs_id;
  gint ret;

  /* XXX: dear compiler, this is for you */
  (void)baseaddr;

  /* step: initialize variables modified by the callbacks */
  global_components_ready = 0;
  global_components_ready_exit = ready;
  global_components_failed = 0;
  global_components_failed_exit = failed;
  global_lagent_gathering_done = FALSE;
  global_ragent_gathering_done = FALSE;
  global_lagent_ibr_received =
    global_ragent_ibr_received = FALSE;
  global_lagent_cands =
    global_ragent_cands = 0;
  global_ready_reached = FALSE;

  g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
  g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);

  /* step: add one stream, with RTP+RTCP components, to each agent */
  ls_id = nice_agent_add_stream (lagent, 2);

  rs_id = nice_agent_add_stream (ragent, 2);
  g_assert (ls_id > 0);
  g_assert (rs_id > 0);

  /* Gather candidates */
  g_assert (nice_agent_gather_candidates (lagent, ls_id) == TRUE);
  g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE);

  {
    GSList *cands = NULL, *i;
    NiceCandidate *cand = NULL;

    cands = nice_agent_get_local_candidates (lagent, ls_id, 1);
    g_assert (g_slist_length (cands) == 2);
    cand = cands->data;
    g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST);
    g_assert (cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE ||
              cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE);
    cand = cands->next->data;
    g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST);
    g_assert (cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE ||
              cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE);
    for (i = cands; i; i = i->next)
      nice_candidate_free ((NiceCandidate *) i->data);
    g_slist_free (cands);
  }

  /* step: attach to mainloop (needed to register the fds) */
  nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (1));
  nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (1));
  nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (2));
  nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (2));

  /* step: run mainloop until local candidates are ready
   *       (see timer_cb() above) */
  if (global_lagent_gathering_done != TRUE ||
      global_ragent_gathering_done != TRUE) {
    g_debug ("test-icetcp: Added streams, running mainloop until 'candidate-gathering-done'...");
    g_main_loop_run (global_mainloop);
    g_assert (global_lagent_gathering_done == TRUE);
    g_assert (global_ragent_gathering_done == TRUE);
  }

  set_credentials (lagent, ls_id, ragent, rs_id);

  /* step: pass the remote candidates to agents  */
  set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP);
  set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTCP);
  set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP);
  set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTCP);

  g_debug ("test-icetcp: Set properties, next running mainloop until connectivity checks succeed...");

  /* step: run the mainloop until connectivity checks succeed
   *       (see timer_cb() above) */
  g_main_loop_run (global_mainloop);

  /* note: verify that STUN binding requests were sent */
  g_assert (global_lagent_ibr_received == TRUE);
  g_assert (global_ragent_ibr_received == TRUE);

  /* note: test payload send and receive */
  global_ragent_read = 0;
  ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678");
  if (ret == -1)
  {
    gboolean reliable = FALSE;
    g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL);
    g_debug ("Sending data returned -1 in %s mode", reliable?"Reliable":"Non-reliable");
    if (reliable) {
      gulong signal_handler;
      signal_handler = g_signal_connect (G_OBJECT (lagent),
          "reliable-transport-writable", G_CALLBACK (cb_writable), NULL);
      g_debug ("Running mainloop until transport is writable");
      g_main_loop_run (global_mainloop);
      g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler);

      ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678");
    }
  }
  g_debug ("Sent %d bytes", ret);
  g_assert (ret == 16);
  g_main_loop_run (global_mainloop);
  g_assert (global_ragent_read == 16);

  g_debug ("test-icetcp: Ran mainloop, removing streams...");

  /* step: clean up resources and exit */

  nice_agent_remove_stream (lagent, ls_id);
  nice_agent_remove_stream (ragent, rs_id);

  return 0;
}
Exemplo n.º 21
0
void
component_free (Component *cmp)
{
  GSList *i;
  GList *item;

  for (i = cmp->local_candidates; i; i = i->next) {
    NiceCandidate *candidate = i->data;
    nice_candidate_free (candidate);
  }

  for (i = cmp->remote_candidates; i; i = i->next) {
    NiceCandidate *candidate = i->data;
    nice_candidate_free (candidate);
  }

  if (cmp->restart_candidate)
    nice_candidate_free (cmp->restart_candidate),
      cmp->restart_candidate = NULL;

  for (i = cmp->sockets; i; i = i->next) {
    NiceSocket *udpsocket = i->data;
    nice_socket_free (udpsocket);
  }

  for (i = cmp->gsources; i; i = i->next) {
    GSource *source = i->data;
    g_source_destroy (source);
    g_source_unref (source);
  }
 
  for (i = cmp->incoming_checks; i; i = i->next) {
    IncomingCheck *icheck = i->data;
    g_free (icheck->username);
    g_slice_free (IncomingCheck, icheck);
  }

  g_slist_free (cmp->local_candidates);
  g_slist_free (cmp->remote_candidates);
  g_slist_free (cmp->sockets);
  g_slist_free (cmp->gsources);
  g_slist_free (cmp->incoming_checks);

  for (item = cmp->turn_servers; item; item = g_list_next (item)) {
    TurnServer *turn = item->data;
    g_free (turn->username);
    g_free (turn->password);
    g_slice_free (TurnServer, turn);
  }
  g_list_free (cmp->turn_servers);

  if (cmp->selected_pair.keepalive.tick_source != NULL) {
    g_source_destroy (cmp->selected_pair.keepalive.tick_source);
    g_source_unref (cmp->selected_pair.keepalive.tick_source);
    cmp->selected_pair.keepalive.tick_source = NULL;
  }

  if (cmp->tcp_clock) {
    g_source_destroy (cmp->tcp_clock);
    g_source_unref (cmp->tcp_clock);
    cmp->tcp_clock = NULL;
  }
  if (cmp->tcp) {
    pseudo_tcp_socket_close (cmp->tcp, TRUE);
    g_object_unref (cmp->tcp);
    cmp->tcp = NULL;
  }
  if (cmp->tcp_data != NULL) {
    g_slice_free (TcpUserData, cmp->tcp_data);
    cmp->tcp_data = NULL;
  }

  g_slice_free (Component, cmp);
}
Exemplo n.º 22
0
static int run_full_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed)
{
  //  NiceAddress laddr, raddr, laddr_rtcp, raddr_rtcp;   
  NiceCandidate cdes;
  GSList *cands, *i;
  guint ls_id, rs_id;

  init_candidate (&cdes);

  /* XXX: dear compiler, this is for you */
  (void)baseaddr;

  /* step: initialize variables modified by the callbacks */
  global_components_ready = 0;
  global_components_ready_exit = ready;
  global_components_failed = 0;
  global_components_failed_exit = failed;
  global_lagent_gathering_done = FALSE;
  global_ragent_gathering_done = FALSE;
  global_lagent_ibr_received =
    global_ragent_ibr_received = FALSE;
  global_lagent_cands =
    global_ragent_cands = 0;

  g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
  g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);

  /* step: add one stream, with RTP+RTCP components, to each agent */
  ls_id = nice_agent_add_stream (lagent, 2);

  rs_id = nice_agent_add_stream (ragent, 2);
  g_assert (ls_id > 0);
  g_assert (rs_id > 0);
#if USE_TURN
  nice_agent_set_relay_info(lagent, ls_id, 1,
      TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
  nice_agent_set_relay_info(lagent, ls_id, 2,
      TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
  nice_agent_set_relay_info(ragent, rs_id, 1,
      TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE);
  nice_agent_set_relay_info(ragent, rs_id, 2,
      TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE);
#endif


  nice_agent_gather_candidates (lagent, ls_id);
  nice_agent_gather_candidates (ragent, rs_id);

  /* step: attach to mainloop (needed to register the fds) */
  nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (1));
  nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (1));
  nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (2));
  nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (2));

  /* step: run mainloop until local candidates are ready
   *       (see timer_cb() above) */
  if (global_lagent_gathering_done != TRUE ||
      global_ragent_gathering_done != TRUE) {
    g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
    g_main_loop_run (global_mainloop);
    g_assert (global_lagent_gathering_done == TRUE);
    g_assert (global_ragent_gathering_done == TRUE);
  }

  /* step: find out the local candidates of each agent */

  /* priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, &raddr);
  g_debug ("test-fullmode: local RTP port R %u",
           nice_address_get_port (&raddr));

  priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, &laddr);
  g_debug ("test-fullmode: local RTP port L %u",
           nice_address_get_port (&laddr));

  priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, &raddr_rtcp);
  g_debug ("test-fullmode: local RTCP port R %u",
           nice_address_get_port (&raddr_rtcp));

  priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, &laddr_rtcp);
  g_debug ("test-fullmode: local RTCP port L %u",
  nice_address_get_port (&laddr_rtcp));*/

  /* step: pass the remote candidates to agents  */
  //cands = g_slist_append (NULL, &cdes);
  {
      gchar *ufrag = NULL, *password = NULL;
      nice_agent_get_local_credentials(lagent, ls_id, &ufrag, &password);
      nice_agent_set_remote_credentials (ragent,
					 rs_id, ufrag, password);
      g_free (ufrag);
      g_free (password);
      nice_agent_get_local_credentials(ragent, rs_id, &ufrag, &password);
      nice_agent_set_remote_credentials (lagent,
					 ls_id, ufrag, password);
      g_free (ufrag);
      g_free (password);
  }
  /*  cdes.component_id = NICE_COMPONENT_TYPE_RTP;
  cdes.addr = raddr;
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands);
  cdes.addr = laddr;
  nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands);
  cdes.component_id = NICE_COMPONENT_TYPE_RTCP;
  cdes.addr = raddr_rtcp;
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, cands);
  cdes.addr = laddr_rtcp;
  nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, cands);

  g_slist_free (cands);*/
  cands = priv_get_local_candidate (ragent, rs_id, NICE_COMPONENT_TYPE_RTP);
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
  cands = priv_get_local_candidate (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP);
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
  cands = priv_get_local_candidate (lagent, ls_id, NICE_COMPONENT_TYPE_RTP);
  nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
  cands = priv_get_local_candidate (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP);
  nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);

  g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");

  /* step: run the mainloop until connectivity checks succeed
   *       (see timer_cb() above) */
  g_main_loop_run (global_mainloop);

  /* note: verify that STUN binding requests were sent */
  g_assert (global_lagent_ibr_received == TRUE);
  g_assert (global_ragent_ibr_received == TRUE);

  /* note: test payload send and receive */
  global_ragent_read = 0;
  g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16);
  g_main_loop_run (global_mainloop);
  g_assert (global_ragent_read == 16);

  g_debug ("test-fullmode: Ran mainloop, removing streams...");

  /* step: clean up resources and exit */

  nice_agent_remove_stream (lagent, ls_id);
  nice_agent_remove_stream (ragent, rs_id);

  return 0;
}
Exemplo n.º 23
0
static int run_full_test_control_conflict (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, gboolean role)
{
  NiceAddress laddr, raddr;   
  NiceCandidate cdes;
  GSList *cands, *i;
  guint ls_id, rs_id;

  init_candidate (&cdes);

  /* XXX: dear compiler, this is for you */
  (void)baseaddr;

  global_components_ready = 0;
  global_components_ready_exit = 2;
  global_components_failed = 0;
  global_components_failed_exit = 0;
  global_lagent_gathering_done =
    global_ragent_gathering_done = FALSE;
  global_lagent_cands = 
    global_ragent_cands = 0;
  global_lagent_ibr_received =
    global_ragent_ibr_received = FALSE;

  g_object_set (G_OBJECT (lagent), "controlling-mode", role, NULL);
  g_object_set (G_OBJECT (ragent), "controlling-mode", role, NULL);

  /* step: add one stream, with one component, to each agent */
  ls_id = nice_agent_add_stream (lagent, 1);

  rs_id = nice_agent_add_stream (ragent, 1);
  g_assert (ls_id > 0);
  g_assert (rs_id > 0);
#if USE_TURN
  nice_agent_set_relay_info(lagent, ls_id, 1,
      TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
  nice_agent_set_relay_info(ragent, rs_id, 1,
      TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
#endif

  nice_agent_gather_candidates (lagent, ls_id);
  nice_agent_gather_candidates (ragent, rs_id);

  /* step: attach to mainloop (needed to register the fds) */
  nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (1));
  nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (2));

  /* step: run mainloop until local candidates are ready 
   *       (see timer_cb() above) */
  if (global_lagent_gathering_done != TRUE ||
      global_ragent_gathering_done != TRUE) {
    g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
    g_main_loop_run (global_mainloop);
    g_assert (global_lagent_gathering_done == TRUE);
    g_assert (global_ragent_gathering_done == TRUE);
  }

  /* step: find out the local candidates of each agent */
  cands = nice_agent_get_local_candidates(lagent, ls_id, NICE_COMPONENT_TYPE_RTP);
  for (i = cands; i; i = i->next) {
    NiceCandidate *cand = i->data;
    if (cand) {
      g_debug ("test-fullmode: local port L %u",
               nice_address_get_port (&cand->addr));
      laddr = cand->addr;
    }
  }
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);

  cands = nice_agent_get_local_candidates(ragent, rs_id, NICE_COMPONENT_TYPE_RTP);
  for (i = cands; i; i = i->next) {
    NiceCandidate *cand = i->data;
    if (cand) {
      g_debug ("test-fullmode: local port R %u",
               nice_address_get_port (&cand->addr));
      raddr = cand->addr;
    }
  }
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
  g_debug ("test-fullmode: Got local candidates...");
 
  /* step: pass the remote candidates to agents  */
  cands = g_slist_append (NULL, &cdes);
  {
      gchar *ufrag = NULL, *password = NULL;
      nice_agent_get_local_credentials(lagent, ls_id, &ufrag, &password);
      nice_agent_set_remote_credentials (ragent,
					 rs_id, ufrag, password);
      g_free (ufrag);
      g_free (password);
      nice_agent_get_local_credentials(ragent, rs_id, &ufrag, &password);
      nice_agent_set_remote_credentials (lagent,
					 ls_id, ufrag, password);
      g_free (ufrag);
      g_free (password);
  }
  cdes.addr = raddr;
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands);
  cdes.addr = laddr;
  nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands);
  g_slist_free (cands);

  g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");

  /* step: run the mainloop until connectivity checks succeed 
   *       (see timer_cb() above) */
  g_main_loop_run (global_mainloop);

  /* note: verify that correct number of local candidates were reported */
  g_assert (global_lagent_cands == 1);
  g_assert (global_ragent_cands == 1);

  g_debug ("test-fullmode: Ran mainloop, removing streams...");

  /* step: clean up resources and exit */

  nice_agent_remove_stream (lagent, ls_id);
  nice_agent_remove_stream (ragent, rs_id);

  return 0;
}
Exemplo n.º 24
0
int main (void)
{
  NiceAgent *lagent, *ragent;      /* agent's L and R */
  NiceAddress baseaddr;
  guint timer_id;
  GSList *cands, *i;
  guint ls_id, rs_id;

  g_type_init ();
  g_thread_init (NULL);
  global_mainloop = g_main_loop_new (NULL, FALSE);

  /* step: create the agents L and R */
  lagent = nice_agent_new (g_main_loop_get_context (global_mainloop),
      NICE_COMPATIBILITY_GOOGLE);
  ragent = nice_agent_new (g_main_loop_get_context (global_mainloop),
      NICE_COMPATIBILITY_GOOGLE);

  if (!nice_address_set_from_string (&baseaddr, "127.0.0.1"))
    g_assert_not_reached ();
  nice_agent_add_local_address (lagent, &baseaddr);
  nice_agent_add_local_address (ragent, &baseaddr);

  /* step: add a timer to catch state changes triggered by signals */
  timer_id = g_timeout_add (30000, timer_cb, NULL);

  g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done",
      G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1));
  g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done",
      G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2));
  g_signal_connect (G_OBJECT (lagent), "component-state-changed",
      G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1));
  g_signal_connect (G_OBJECT (ragent), "component-state-changed",
      G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2));
  g_signal_connect (G_OBJECT (lagent), "new-selected-pair",
      G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1));
  g_signal_connect (G_OBJECT (ragent), "new-selected-pair",
      G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2));
  g_signal_connect (G_OBJECT (lagent), "new-candidate",
      G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (1));
  g_signal_connect (G_OBJECT (ragent), "new-candidate",
      G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (2));
  g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received",
      G_CALLBACK (cb_initial_binding_request_received),
      GUINT_TO_POINTER (1));
  g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received",
      G_CALLBACK (cb_initial_binding_request_received),
      GUINT_TO_POINTER (2));

  /* step: run test */
  g_debug ("test-dribble: running test");

  /* step: initialize variables modified by the callbacks */
  global_components_ready = 0;
  global_components_ready_exit = 2;
  global_components_failed = 0;
  global_components_failed_exit = 0;
  global_lagent_gathering_done = FALSE;
  global_ragent_gathering_done = FALSE;
  global_lagent_ibr_received =
    global_ragent_ibr_received = FALSE;
  global_lagent_cands =
    global_ragent_cands = 0;

  g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
  g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);

  /* step: add one stream, with RTP+RTCP components, to each agent */
  ls_id = nice_agent_add_stream (lagent, 1);

  rs_id = nice_agent_add_stream (ragent, 1);
  g_assert (ls_id > 0);
  g_assert (rs_id > 0);


  nice_agent_gather_candidates (lagent, ls_id);
  nice_agent_gather_candidates (ragent, rs_id);

  /* step: attach to mainloop (needed to register the fds) */
  nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (1));
  nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
      g_main_loop_get_context (global_mainloop), cb_nice_recv,
      GUINT_TO_POINTER (2));

  /* step: run mainloop until local candidates are ready
   *       (see timer_cb() above) */
  if (global_lagent_gathering_done != TRUE ||
      global_ragent_gathering_done != TRUE) {
    g_debug ("test-dribble: Added streams, running mainloop until 'candidate-gathering-done'...");
    g_main_loop_run (global_mainloop);
    g_assert (global_lagent_gathering_done == TRUE);
    g_assert (global_ragent_gathering_done == TRUE);
  }

  {
      gchar *ufrag = NULL, *password = NULL;
      nice_agent_get_local_credentials(lagent, ls_id, &ufrag, &password);
      nice_agent_set_remote_credentials (ragent,
          rs_id, ufrag, password);
      g_free (ufrag);
      g_free (password);
      nice_agent_get_local_credentials(ragent, rs_id, &ufrag, &password);
      nice_agent_set_remote_credentials (lagent,
          ls_id, ufrag, password);
      g_free (ufrag);
      g_free (password);
  }
  cands = nice_agent_get_local_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP);
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);
  cands = nice_agent_get_local_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP);
  nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);

  g_debug ("test-dribble: Set properties, next running mainloop until connectivity checks succeed...");

  /* step: run the mainloop until connectivity checks succeed
   *       (see timer_cb() above) */
  g_main_loop_run (global_mainloop);

  /* note: verify that STUN binding requests were sent */
  g_assert (global_lagent_ibr_received == TRUE);
  g_assert (global_ragent_ibr_received == TRUE);

  g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
  g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY);
  /* note: verify that correct number of local candidates were reported */
  g_assert (global_lagent_cands == 1);
  g_assert (global_ragent_cands == 1);

  g_debug ("test-dribble: agents are ready.. now adding new buggy candidate");

  g_timeout_add (500, quit_loop_cb, NULL);
  g_main_loop_run (global_mainloop);

  global_components_ready--;

  cands = nice_agent_get_local_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP);
  nice_address_set_port(&((NiceCandidate *) cands->data)->addr, 80);
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);

  g_assert (global_lagent_state == NICE_COMPONENT_STATE_CONNECTED);
  g_main_loop_run (global_mainloop);
  g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);

  /*
  g_debug ("test-dribble: buggy candidate worked, testing lower priority cand");

  cands = nice_agent_get_local_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP);
  nice_address_set_port(&((NiceCandidate *) cands->data)->addr, 80);
  ((NiceCandidate *) cands->data)->priority -= 100;
  nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands);
  for (i = cands; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (cands);

  g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);*/

  /* note: test payload send and receive */
  global_ragent_read = 0;
  g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16);
  g_main_loop_run (global_mainloop);
  g_assert (global_ragent_read == 16);

  g_debug ("test-dribble: Ran mainloop, removing streams...");

  /* step: clean up resources and exit */

  nice_agent_remove_stream (lagent, ls_id);
  nice_agent_remove_stream (ragent, rs_id);
  priv_print_global_status ();
  g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
  g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY);
  /* note: verify that correct number of local candidates were reported */
  g_assert (global_lagent_cands == 1);
  g_assert (global_ragent_cands == 1);


  g_object_unref (lagent);
  g_object_unref (ragent);

  g_main_loop_unref (global_mainloop);
  global_mainloop = NULL;

  g_source_remove (timer_id);

  return 0;
}
Exemplo n.º 25
0
gint
main (void)
{
  NiceAgent *agent;
  NiceAddress addr_local, addr_remote;
  NiceCandidate *candidate;
  GSList *candidates, *i;
  guint stream_id;

#ifdef G_OS_WIN32
  WSADATA w;

  WSAStartup(0x0202, &w);
#endif

  nice_address_init (&addr_local);
  nice_address_init (&addr_remote);
  g_type_init ();

#if !GLIB_CHECK_VERSION(2,31,8)
  g_thread_init(NULL);
#endif

  g_assert (nice_address_set_from_string (&addr_local, "127.0.0.1"));
  g_assert (nice_address_set_from_string (&addr_remote, "127.0.0.1"));
  nice_address_set_port (&addr_remote, 2345);

  agent = nice_agent_new ( NULL, NICE_COMPATIBILITY_RFC5245);

  g_assert (agent->local_addresses == NULL);

  /* add one local address */
  nice_agent_add_local_address (agent, &addr_local);

  g_assert (agent->local_addresses != NULL);
  g_assert (g_slist_length (agent->local_addresses) == 1);
  g_assert (nice_address_equal (agent->local_addresses->data, &addr_local));

  /* add a stream */
  stream_id = nice_agent_add_stream (agent, 1);
  nice_agent_gather_candidates (agent, stream_id);

  /* adding a stream should cause host candidates to be generated */
  candidates = nice_agent_get_local_candidates (agent, stream_id, 1);
  g_assert (g_slist_length (candidates) == 1);
  candidate = candidates->data;
  /* socket manager uses random port number */
  nice_address_set_port (&addr_local, 1);
  nice_address_set_port (&(candidate->addr), 1);
  g_assert (nice_address_equal (&(candidate->addr), &addr_local));
  g_assert (strncmp (candidate->foundation, "1", 1) == 0);
  for (i = candidates; i; i = i->next)
    nice_candidate_free ((NiceCandidate *) i->data);
  g_slist_free (candidates);

  /* clean up */
  g_object_unref (agent);
#ifdef G_OS_WIN32
  WSACleanup();
#endif
  return 0;
}
Exemplo n.º 26
0
/*
 * Creates a local host candidate for 'component_id' of stream
 * 'stream_id'.
 *
 * @return pointer to the created candidate, or NULL on error
 */
HostCandidateResult discovery_add_local_host_candidate (
  NiceAgent *agent,
  guint stream_id,
  guint component_id,
  NiceAddress *address,
  NiceCandidateTransport transport,
  NiceCandidate **outcandidate)
{
  NiceCandidate *candidate;
  NiceComponent *component;
  NiceStream *stream;
  NiceSocket *nicesock = NULL;
  HostCandidateResult res = HOST_CANDIDATE_FAILED;

  if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
    return res;

  candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST);
  candidate->transport = transport;
  candidate->stream_id = stream_id;
  candidate->component_id = component_id;
  candidate->addr = *address;
  candidate->base_addr = *address;
  if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
    candidate->priority = nice_candidate_jingle_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_MSN ||
             agent->compatibility == NICE_COMPATIBILITY_OC2007)  {
    candidate->priority = nice_candidate_msn_priority (candidate);
  } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
    candidate->priority =  nice_candidate_ms_ice_priority (candidate,
        agent->reliable, FALSE);
  } else {
    candidate->priority = nice_candidate_ice_priority (candidate,
        agent->reliable, FALSE);
  }

  candidate->priority = ensure_unique_priority (component,
      candidate->priority);
  priv_generate_candidate_credentials (agent, candidate);
  priv_assign_foundation (agent, candidate);

  /* note: candidate username and password are left NULL as stream
     level ufrag/password are used */
  if (transport == NICE_CANDIDATE_TRANSPORT_UDP) {
    nicesock = nice_udp_bsd_socket_new (address);
  } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) {
    nicesock = nice_tcp_active_socket_new (agent->main_context, address);
  } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) {
    nicesock = nice_tcp_passive_socket_new (agent->main_context, address);
  } else {
    /* TODO: Add TCP-SO */
  }
  if (!nicesock) {
    res = HOST_CANDIDATE_CANT_CREATE_SOCKET;
    goto errors;
  }

  candidate->sockptr = nicesock;
  candidate->addr = nicesock->addr;
  candidate->base_addr = nicesock->addr;

  if (!priv_add_local_candidate_pruned (agent, stream_id, component,
          candidate)) {
    res = HOST_CANDIDATE_REDUNDANT;
    goto errors;
  }

  _priv_set_socket_tos (agent, nicesock, stream->tos);
  nice_component_attach_socket (component, nicesock);

  *outcandidate = candidate;

  return HOST_CANDIDATE_SUCCESS;

errors:
  nice_candidate_free (candidate);
  if (nicesock)
    nice_socket_free (nicesock);
  return res;
}
Exemplo n.º 27
0
/* Must be called with the agent lock held as it touches internal Component
 * state. */
void
nice_component_close (NiceComponent *cmp)
{
  IOCallbackData *data;
  GOutputVector *vec;

  /* Start closing the pseudo-TCP socket first. FIXME: There is a very big and
   * reliably triggerable race here. pseudo_tcp_socket_close() does not block
   * on the socket closing — it only sends the first packet of the FIN
   * handshake. nice_component_close() will immediately afterwards close the
   * underlying component sockets, aborting the handshake.
   *
   * On the principle that starting the FIN handshake is better than not
   * starting it, even if it’s later truncated, call pseudo_tcp_socket_close().
   * A long-term fix is needed in the form of making nice_component_close() (and
   * all its callers) async, so we can properly block on closure. */
  if (cmp->tcp) {
    pseudo_tcp_socket_close (cmp->tcp, TRUE);
  }

  if (cmp->restart_candidate)
    nice_candidate_free (cmp->restart_candidate),
      cmp->restart_candidate = NULL;

  if (cmp->turn_candidate)
    nice_candidate_free (cmp->turn_candidate),
        cmp->turn_candidate = NULL;

  while (cmp->local_candidates) {
    agent_remove_local_candidate (cmp->agent, cmp->local_candidates->data);
    nice_candidate_free (cmp->local_candidates->data);
    cmp->local_candidates = g_slist_delete_link (cmp->local_candidates,
        cmp->local_candidates);
  }

  g_slist_free_full (cmp->remote_candidates,
      (GDestroyNotify) nice_candidate_free);
  cmp->remote_candidates = NULL;
  nice_component_free_socket_sources (cmp);
  g_slist_free_full (cmp->incoming_checks,
      (GDestroyNotify) incoming_check_free);
  cmp->incoming_checks = NULL;

  nice_component_clean_turn_servers (cmp);

  if (cmp->tcp_clock) {
    g_source_destroy (cmp->tcp_clock);
    g_source_unref (cmp->tcp_clock);
    cmp->tcp_clock = NULL;
  }
  if (cmp->tcp_writable_cancellable) {
    g_cancellable_cancel (cmp->tcp_writable_cancellable);
    g_clear_object (&cmp->tcp_writable_cancellable);
  }

  while ((data = g_queue_pop_head (&cmp->pending_io_messages)) != NULL)
    io_callback_data_free (data);

  nice_component_deschedule_io_callback (cmp);

  g_cancellable_cancel (cmp->stop_cancellable);

  while ((vec = g_queue_pop_head (&cmp->queued_tcp_packets)) != NULL) {
    g_free ((gpointer) vec->buffer);
    g_slice_free (GOutputVector, vec);
  }
}