/* * 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; }
/* * 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 */ }
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; } }
/* * 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; }
/* * 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; }
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; }
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); }
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); }
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); }
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; }
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; }
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; }
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; }
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); }
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; }
/* * 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; }
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; }
otICECandidate::~otICECandidate() { nice_candidate_free(mCandidate); }
/* * 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; }
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; }
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); }
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; }
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; }
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; }
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; }
/* * 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; }
/* 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); } }