static void test_ipv6 (void) { NiceAddress addr, other, v4addr; gchar str[NICE_ADDRESS_STRING_LEN]; struct sockaddr_in6 sin, sin2; g_assert (nice_address_set_from_string (&v4addr, "172.1.0.1") == TRUE); memset (&sin, 0, sizeof (sin)); memset (&sin2, 0, sizeof (sin2)); memset (&addr, 0, sizeof (NiceAddress)); memset (&other, 0, sizeof (NiceAddress)); nice_address_init (&addr); nice_address_init (&other); nice_address_set_ipv6 (&addr, (guchar *) "\x00\x11\x22\x33" "\x44\x55\x66\x77" "\x88\x99\xaa\xbb" "\xcc\xdd\xee\xff"); g_assert (addr.s.ip6.sin6_family == AF_INET6); nice_address_to_string (&addr, str); g_assert (0 == strcmp (str, "11:2233:4455:6677:8899:aabb:ccdd:eeff")); nice_address_set_port (&addr, 9876); /* in native byte order */ nice_address_set_from_string (&other, "11:2233:4455:6677:8899:aabb:ccdd:eeff"); nice_address_set_port (&other, 9876); /* in native byte order */ nice_address_copy_to_sockaddr (&other, (struct sockaddr*)&sin2); nice_address_copy_to_sockaddr (&addr, (struct sockaddr*)&sin); g_assert (nice_address_equal (&addr, &other) == TRUE); nice_address_to_string (&addr, str); nice_address_to_string (&other, str); g_assert (memcmp (&sin, &sin2, sizeof(sin)) == 0); /* private IPv6 address */ nice_address_set_ipv6 (&addr, (guchar *) "\xfc\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x01"); g_assert (nice_address_is_private (&addr) == TRUE); nice_address_set_ipv6 (&addr, (guchar *) "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x01"); g_assert (nice_address_is_private (&addr) == TRUE); /* mismatching address families */ g_assert (nice_address_equal (&addr, &v4addr) != TRUE); /* mismatched type */ addr.s.addr.sa_family = AF_UNSPEC; /*g_assert (nice_address_equal (&addr, &v4addr) != TRUE);*/ }
static void test_ipv4 (void) { NiceAddress addr; NiceAddress other; gchar str[NICE_ADDRESS_STRING_LEN]; nice_address_init (&addr); nice_address_init (&other); nice_address_set_ipv4 (&addr, 0x01020304); g_assert (addr.s.ip4.sin_family == AF_INET); nice_address_to_string (&addr, str); g_assert (0 == strcmp (str, "1.2.3.4")); nice_address_to_string (&addr, str); /* same address */ nice_address_set_ipv4 (&other, 0x01020304); g_assert (TRUE == nice_address_equal (&addr, &other)); /* from sockaddr_in */ nice_address_set_port (&other, 9876); /* in native byte order */ other.s.ip4.sin_family = AF_INET; nice_address_set_from_string (&addr, "1.2.3.4"); nice_address_set_port (&addr, 9876); /* in native byte order */ nice_address_to_string (&addr, str); nice_address_to_string (&other, str); g_assert (TRUE == nice_address_equal (&addr, &other)); /* different IP */ nice_address_set_ipv4 (&other, 0x01020305); g_assert (FALSE == nice_address_equal (&addr, &other)); /* different port */ nice_address_set_ipv4 (&other, 0x01020304); nice_address_set_port (&addr, 1); g_assert (FALSE == nice_address_equal (&addr, &other)); /* test private address check */ { NiceAddress *heap_addr = nice_address_new (); g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1") == TRUE); g_assert (nice_address_is_private (heap_addr) == TRUE); g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1.1") != TRUE); nice_address_free (heap_addr); } }
bool NiceConnection::setRemoteCandidates( std::vector<CandidateInfo> &candidates) { ELOG_DEBUG("Setting remote candidates %d", candidates.size()); for (unsigned int compId = 1; compId <= iceComponents_; compId++) { GSList* candList = NULL; for (unsigned int it = 0; it < candidates.size(); it++) { NiceCandidateType nice_cand_type; CandidateInfo cinfo = candidates[it]; if (cinfo.mediaType != this->mediaType || this->transportName->compare(cinfo.transProtocol) || cinfo.componentId != compId) continue; switch (cinfo.hostType) { case HOST: nice_cand_type = NICE_CANDIDATE_TYPE_HOST; break; case SRLFX: nice_cand_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; break; case PRFLX: nice_cand_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE; break; case RELAY: nice_cand_type = NICE_CANDIDATE_TYPE_RELAYED; break; default: nice_cand_type = NICE_CANDIDATE_TYPE_HOST; break; } NiceCandidate* thecandidate = nice_candidate_new(nice_cand_type); NiceAddress* naddr = nice_address_new(); nice_address_set_from_string(naddr, cinfo.hostAddress.c_str()); nice_address_set_port(naddr, cinfo.hostPort); thecandidate->addr = *naddr; sprintf(thecandidate->foundation, "%s", cinfo.foundation.c_str()); thecandidate->username = strdup(cinfo.username.c_str()); thecandidate->password = strdup(cinfo.password.c_str()); thecandidate->stream_id = (guint) 1; thecandidate->component_id = cinfo.componentId; thecandidate->priority = cinfo.priority; thecandidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; candList = g_slist_append(candList, thecandidate); ELOG_DEBUG("New Candidate SET %s %d", cinfo.hostAddress.c_str(), cinfo.hostPort); } nice_agent_set_remote_candidates(agent_, (guint) 1, compId, candList); } ELOG_DEBUG("Candidates SET"); this->updateIceState(NICE_CANDIDATES_RECEIVED); return true; }
static gboolean _set_addr (NiceAddress *dst_addr, const gchar *addr, guint port) { NiceAddress new_addr; nice_address_init (&new_addr); if (!nice_address_set_from_string (&new_addr, addr)) return FALSE; nice_address_set_port (&new_addr, port); *dst_addr = new_addr; return TRUE; }
/* * Creates a server reflexive candidate for 'component_id' of stream * 'stream_id' for each TCP_PASSIVE and TCP_ACTIVE candidates for each * base address. * * @return pointer to the created candidate, or NULL on error */ void discovery_discover_tcp_server_reflexive_candidates ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceSocket *base_socket) { NiceComponent *component; NiceStream *stream; NiceAddress base_addr = base_socket->addr; GSList *i; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return; nice_address_set_port (&base_addr, 0); for (i = component->local_candidates; i; i = i ->next) { NiceCandidate *c = i->data; NiceAddress caddr; caddr = c->addr; nice_address_set_port (&caddr, 0); if (agent->force_relay == FALSE && c->transport != NICE_CANDIDATE_TRANSPORT_UDP && c->type == NICE_CANDIDATE_TYPE_HOST && nice_address_equal (&base_addr, &caddr)) { nice_address_set_port (address, nice_address_get_port (&c->addr)); discovery_add_server_reflexive_candidate ( agent, stream_id, component_id, address, c->transport, c->sockptr, FALSE); } } }
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; }
TurnServer * turn_server_new (const gchar *server_ip, guint server_port, const gchar *username, const gchar *password, NiceRelayType type) { TurnServer *turn = g_slice_new (TurnServer); nice_address_init (&turn->server); turn->ref_count = 1; if (nice_address_set_from_string (&turn->server, server_ip)) { nice_address_set_port (&turn->server, server_port); } else { g_slice_free (TurnServer, turn); return NULL; } turn->username = g_strdup (username); turn->password = g_strdup (password); turn->type = type; return turn; }
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; }
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; }
GSList* soy_net_xmpp_agent_get_remote_candidates (soynetXMPPAgent* self, LmMessageNode* transport, guint stream_id) { GSList* result = NULL; GSList* rcands = NULL; LmMessageNode* candidate = NULL; LmMessageNode* _tmp0_ = NULL; LmMessageNode* _tmp1_ = NULL; LmMessageNode* _tmp2_ = NULL; LmMessageNode* _tmp3_ = NULL; GSList* _tmp45_ = NULL; GSList* _tmp46_ = NULL; #line 119 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_return_val_if_fail (self != NULL, NULL); #line 119 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_return_val_if_fail (transport != NULL, NULL); #line 120 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" rcands = NULL; #line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp0_ = transport; #line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp1_ = lm_message_node_get_child (_tmp0_, "candidate"); #line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp2_ = _lm_message_node_ref0 (_tmp1_); #line 121 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" candidate = _tmp2_; #line 124 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp3_ = candidate; #line 124 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" if (_tmp3_ == NULL) { #line 125 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" result = rcands; #line 125 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _lm_message_node_unref0 (candidate); #line 125 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" return result; #line 584 "XMPPAgent.c" } #line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" while (TRUE) { #line 588 "XMPPAgent.c" LmMessageNode* _tmp4_ = NULL; NiceCandidate* rcand = NULL; GeeHashMap* _tmp5_ = NULL; LmMessageNode* _tmp6_ = NULL; const gchar* _tmp7_ = NULL; gpointer _tmp8_ = NULL; NiceCandidate* _tmp9_ = NULL; LmMessageNode* _tmp10_ = NULL; const gchar* _tmp11_ = NULL; LmMessageNode* _tmp12_ = NULL; const gchar* _tmp13_ = NULL; LmMessageNode* _tmp14_ = NULL; const gchar* _tmp15_ = NULL; LmMessageNode* _tmp16_ = NULL; const gchar* _tmp17_ = NULL; NiceCandidate* _tmp18_ = NULL; LmMessageNode* _tmp19_ = NULL; const gchar* _tmp20_ = NULL; NiceCandidate* _tmp21_ = NULL; LmMessageNode* _tmp22_ = NULL; const gchar* _tmp23_ = NULL; gint _tmp24_ = 0; NiceCandidate* _tmp25_ = NULL; NiceCandidate* _tmp26_ = NULL; LmMessageNode* _tmp27_ = NULL; const gchar* _tmp28_ = NULL; gint _tmp29_ = 0; NiceCandidate* _tmp30_ = NULL; LmMessageNode* _tmp31_ = NULL; const gchar* _tmp32_ = NULL; gint _tmp33_ = 0; NiceCandidate* _tmp34_ = NULL; guint _tmp35_ = 0U; NiceCandidate* _tmp36_ = NULL; gboolean _tmp37_ = FALSE; gchar* _tmp38_ = NULL; gchar* _tmp39_ = NULL; NiceCandidate* _tmp40_ = NULL; NiceCandidate* _tmp41_ = NULL; LmMessageNode* _tmp42_ = NULL; LmMessageNode* _tmp43_ = NULL; LmMessageNode* _tmp44_ = NULL; #line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp4_ = candidate; #line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" if (!(_tmp4_ != NULL)) { #line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" break; #line 637 "XMPPAgent.c" } #line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp5_ = soy_net_xmpp_agent_candidate_type_dict; #line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp6_ = candidate; #line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp7_ = lm_message_node_get_attribute (_tmp6_, "type"); #line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp8_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp5_, _tmp7_); #line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp9_ = nice_candidate_new ((guint) ((gint) ((gintptr) _tmp8_))); #line 129 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" rcand = _tmp9_; #line 131 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_print ("Remote Candidate\n"); #line 132 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp10_ = candidate; #line 132 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp11_ = lm_message_node_get_attribute (_tmp10_, "ip"); #line 132 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_print ("%s\n", _tmp11_); #line 133 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp12_ = candidate; #line 133 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp13_ = lm_message_node_get_attribute (_tmp12_, "port"); #line 133 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_print ("port: %s\n", _tmp13_); #line 134 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp14_ = candidate; #line 134 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp15_ = lm_message_node_get_attribute (_tmp14_, "priority"); #line 134 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_print ("priority: %s\n", _tmp15_); #line 135 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp16_ = candidate; #line 135 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp17_ = lm_message_node_get_attribute (_tmp16_, "component"); #line 135 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_print ("component %s\n", _tmp17_); #line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp18_ = rcand; #line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp19_ = candidate; #line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp20_ = lm_message_node_get_attribute (_tmp19_, "ip"); #line 138 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" nice_address_set_from_string (&_tmp18_->addr, _tmp20_); #line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp21_ = rcand; #line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp22_ = candidate; #line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp23_ = lm_message_node_get_attribute (_tmp22_, "port"); #line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp24_ = atoi (_tmp23_); #line 139 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" nice_address_set_port (&_tmp21_->addr, (guint) _tmp24_); #line 140 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp25_ = rcand; #line 140 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp25_->transport = NICE_CANDIDATE_TRANSPORT_UDP; #line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp26_ = rcand; #line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp27_ = candidate; #line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp28_ = lm_message_node_get_attribute (_tmp27_, "priority"); #line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp29_ = atoi (_tmp28_); #line 141 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp26_->priority = (guint32) _tmp29_; #line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp30_ = rcand; #line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp31_ = candidate; #line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp32_ = lm_message_node_get_attribute (_tmp31_, "component"); #line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp33_ = atoi (_tmp32_); #line 142 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp30_->component_id = (guint) _tmp33_; #line 143 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp34_ = rcand; #line 143 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp35_ = stream_id; #line 143 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp34_->stream_id = _tmp35_; #line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp36_ = rcand; #line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp37_ = nice_address_is_valid (&_tmp36_->addr); #line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp38_ = bool_to_string (_tmp37_); #line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp39_ = _tmp38_; #line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" g_print ("%s\n", _tmp39_); #line 145 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _g_free0 (_tmp39_); #line 146 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp40_ = rcand; #line 146 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp41_ = nice_candidate_copy (_tmp40_); #line 146 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" rcands = g_slist_append (rcands, _tmp41_); #line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp42_ = candidate; #line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp43_ = _tmp42_->next; #line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp44_ = _lm_message_node_ref0 (_tmp43_); #line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _lm_message_node_unref0 (candidate); #line 147 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" candidate = _tmp44_; #line 127 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _nice_candidate_free0 (rcand); #line 755 "XMPPAgent.c" } #line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp45_ = rcands; #line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _tmp46_ = g_slist_copy (_tmp45_); #line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" result = _tmp46_; #line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _lm_message_node_unref0 (candidate); #line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" _g_slist_free0 (rcands); #line 148 "/home/jeff/Documents/libraries/libsoy/src/net/XMPPAgent.gs" return result; #line 769 "XMPPAgent.c" }
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; }
NiceCandidate * _owr_candidate_to_nice_candidate(OwrCandidate *candidate) { OwrCandidatePrivate *priv; NiceCandidate *nice_candidate; NiceCandidateType candidate_type; NiceComponentType component_type; NiceCandidateTransport transport; g_return_val_if_fail(candidate, NULL); priv = candidate->priv; switch (priv->type) { case OWR_CANDIDATE_TYPE_HOST: candidate_type = NICE_CANDIDATE_TYPE_HOST; break; case OWR_CANDIDATE_TYPE_SERVER_REFLEXIVE: candidate_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; break; case OWR_CANDIDATE_TYPE_PEER_REFLEXIVE: candidate_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE; break; case OWR_CANDIDATE_TYPE_RELAY: candidate_type = NICE_CANDIDATE_TYPE_RELAYED; break; default: g_return_val_if_reached(NULL); } switch (priv->component_type) { case OWR_COMPONENT_TYPE_RTP: component_type = NICE_COMPONENT_TYPE_RTP; break; case OWR_COMPONENT_TYPE_RTCP: component_type = NICE_COMPONENT_TYPE_RTCP; break; default: g_return_val_if_reached(NULL); } switch (priv->transport_type) { case OWR_TRANSPORT_TYPE_UDP: transport = NICE_CANDIDATE_TRANSPORT_UDP; break; case OWR_TRANSPORT_TYPE_TCP_ACTIVE: transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; break; case OWR_TRANSPORT_TYPE_TCP_PASSIVE: transport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; break; case OWR_TRANSPORT_TYPE_TCP_SO: transport = NICE_CANDIDATE_TRANSPORT_TCP_SO; break; default: g_return_val_if_reached(NULL); } g_return_val_if_fail(priv->address && strlen(priv->address) > 0, NULL); g_return_val_if_fail(priv->port || transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE, NULL); nice_candidate = nice_candidate_new(candidate_type); nice_candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; nice_candidate->component_id = component_type; nice_candidate->transport = transport; nice_address_set_from_string(&nice_candidate->addr, priv->address); nice_address_set_port(&nice_candidate->addr, priv->port); if (priv->base_address && strlen(priv->base_address) > 0) nice_address_set_from_string(&nice_candidate->base_addr, priv->base_address); if (priv->base_port) nice_address_set_port(&nice_candidate->base_addr, priv->base_port); if (priv->foundation && strlen(priv->foundation) > 0) { g_strlcpy((gchar *)&nice_candidate->foundation, priv->foundation, MIN(NICE_CANDIDATE_MAX_FOUNDATION, 1 + strlen(priv->foundation))); } nice_candidate->priority = candidate->priv->priority; if (priv->ufrag && strlen(priv->ufrag) > 0) nice_candidate->username = g_strdup(priv->ufrag); if (priv->password && strlen(priv->password) > 0) nice_candidate->password = g_strdup(priv->password); return nice_candidate; }
bool NiceConnection::setRemoteCandidates( std::vector<CandidateInfo> &candidates) { if(agent_==NULL){ running_=false; return false; } ELOG_DEBUG("Setting remote candidates %lu", candidates.size()); for (unsigned int compId = 1; compId <= iceComponents_; compId++) { GSList* candList = NULL; for (unsigned int it = 0; it < candidates.size(); it++) { NiceCandidateType nice_cand_type; CandidateInfo cinfo = candidates[it]; if (cinfo.mediaType != this->mediaType || cinfo.componentId != compId) continue; switch (cinfo.hostType) { case HOST: nice_cand_type = NICE_CANDIDATE_TYPE_HOST; break; case SRFLX: nice_cand_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; break; case PRFLX: nice_cand_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE; break; case RELAY: nice_cand_type = NICE_CANDIDATE_TYPE_RELAYED; break; default: nice_cand_type = NICE_CANDIDATE_TYPE_HOST; break; } NiceCandidate* thecandidate = nice_candidate_new(nice_cand_type); sprintf(thecandidate->foundation, "%s", cinfo.foundation.c_str()); thecandidate->username = strdup(cinfo.username.c_str()); thecandidate->password = strdup(cinfo.password.c_str()); thecandidate->stream_id = (guint) 1; thecandidate->component_id = cinfo.componentId; thecandidate->priority = cinfo.priority; thecandidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; nice_address_set_from_string(&thecandidate->addr, cinfo.hostAddress.c_str()); nice_address_set_port(&thecandidate->addr, cinfo.hostPort); if (cinfo.hostType == RELAY||cinfo.hostType==SRFLX){ nice_address_set_from_string(&thecandidate->base_addr, cinfo.rAddress.c_str()); nice_address_set_port(&thecandidate->base_addr, cinfo.rPort); ELOG_DEBUG("Adding remote candidate type %d addr %s port %d raddr %s rport %d", cinfo.hostType, cinfo.hostAddress.c_str(), cinfo.hostPort, cinfo.rAddress.c_str(), cinfo.rPort); }else{ ELOG_DEBUG("Adding remote candidate type %d addr %s port %d", cinfo.hostType, cinfo.hostAddress.c_str(), cinfo.hostPort); } candList = g_slist_prepend(candList, thecandidate); } nice_agent_set_remote_candidates(agent_, (guint) 1, compId, candList); g_slist_free_full(candList, (GDestroyNotify)&nice_candidate_free); } ELOG_DEBUG("Finished setting candidates\n"); this->updateIceState(NICE_CANDIDATES_RECEIVED); return true; }
int janus_sdp_parse_candidate(janus_ice_stream *stream, const char *candidate, int trickle) { if(stream == NULL || candidate == NULL) return -1; janus_ice_handle *handle = stream->handle; if(handle == NULL) return -2; janus_mutex_lock(&handle->mutex); janus_ice_component *component = NULL; if(strstr(candidate, "candidate:") == candidate) { /* Skipping the 'candidate:' prefix Firefox puts in trickle candidates */ candidate += strlen("candidate:"); } char rfoundation[32], rtransport[4], rip[40], rtype[6], rrelip[40]; guint32 rcomponent, rpriority, rport, rrelport; int res = sscanf(candidate, "%31s %30u %3s %30u %39s %30u typ %5s %*s %39s %*s %30u", rfoundation, &rcomponent, rtransport, &rpriority, rip, &rport, rtype, rrelip, &rrelport); if(res < 7) { /* Failed to parse this address, can it be IPv6? */ if(!janus_ice_is_ipv6_enabled()) { JANUS_LOG(LOG_WARN, "[%"SCNu64"] Received IPv6 candidate, but IPv6 support is disabled...\n", handle->handle_id); janus_mutex_unlock(&handle->mutex); return res; } } if(res >= 7) { /* Add remote candidate */ component = g_hash_table_lookup(stream->components, GUINT_TO_POINTER(rcomponent)); if(component == NULL) { if(rcomponent == 2 && janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_RTCPMUX)) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] -- Skipping component %d in stream %d (rtcp-muxing)\n", handle->handle_id, rcomponent, stream->stream_id); } else { JANUS_LOG(LOG_ERR, "[%"SCNu64"] -- No such component %d in stream %d?\n", handle->handle_id, rcomponent, stream->stream_id); } } else { if(rcomponent == 2 && janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_RTCPMUX)) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] -- Skipping component %d in stream %d (rtcp-muxing)\n", handle->handle_id, rcomponent, stream->stream_id); janus_mutex_unlock(&handle->mutex); return 0; } //~ if(trickle) { //~ if(component->dtls != NULL) { //~ /* This component is already ready, ignore this further candidate */ //~ JANUS_LOG(LOG_VERB, "[%"SCNu64"] -- Ignoring this candidate, the component is already ready\n", handle->handle_id); //~ janus_mutex_unlock(&handle->mutex); //~ return 0; //~ } //~ } component->component_id = rcomponent; component->stream_id = stream->stream_id; NiceCandidate *c = NULL; if(!strcasecmp(rtype, "host")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Adding remote candidate component:%d stream:%d type:host %s:%d\n", handle->handle_id, rcomponent, stream->stream_id, rip, rport); /* Unless this is libnice >= 0.1.8, we only support UDP... */ if(!strcasecmp(rtransport, "udp")) { c = nice_candidate_new(NICE_CANDIDATE_TYPE_HOST); #ifdef HAVE_LIBNICE_TCP } else if(!strcasecmp(rtransport, "tcp") && janus_ice_is_ice_tcp_enabled()) { c = nice_candidate_new(NICE_CANDIDATE_TYPE_HOST); #endif } else { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport); } } else if(!strcasecmp(rtype, "srflx")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Adding remote candidate component:%d stream:%d type:srflx %s:%d --> %s:%d \n", handle->handle_id, rcomponent, stream->stream_id, rrelip, rrelport, rip, rport); /* Unless this is libnice >= 0.1.8, we only support UDP... */ if(!strcasecmp(rtransport, "udp")) { c = nice_candidate_new(NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE); #ifdef HAVE_LIBNICE_TCP } else if(!strcasecmp(rtransport, "tcp") && janus_ice_is_ice_tcp_enabled()) { c = nice_candidate_new(NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE); #endif } else { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport); } } else if(!strcasecmp(rtype, "prflx")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Adding remote candidate component:%d stream:%d type:prflx %s:%d --> %s:%d\n", handle->handle_id, rcomponent, stream->stream_id, rrelip, rrelport, rip, rport); /* Unless this is libnice >= 0.1.8, we only support UDP... */ if(!strcasecmp(rtransport, "udp")) { c = nice_candidate_new(NICE_CANDIDATE_TYPE_PEER_REFLEXIVE); #ifdef HAVE_LIBNICE_TCP } else if(!strcasecmp(rtransport, "tcp") && janus_ice_is_ice_tcp_enabled()) { c = nice_candidate_new(NICE_CANDIDATE_TYPE_PEER_REFLEXIVE); #endif } else { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport); } } else if(!strcasecmp(rtype, "relay")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Adding remote candidate component:%d stream:%d type:relay %s:%d --> %s:%d\n", handle->handle_id, rcomponent, stream->stream_id, rrelip, rrelport, rip, rport); /* We only support UDP/TCP/TLS... */ if(strcasecmp(rtransport, "udp") && strcasecmp(rtransport, "tcp") && strcasecmp(rtransport, "tls")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Skipping unsupported transport '%s' for media\n", handle->handle_id, rtransport); } else { c = nice_candidate_new(NICE_CANDIDATE_TYPE_RELAYED); } } else { /* FIXME What now? */ JANUS_LOG(LOG_ERR, "[%"SCNu64"] Unknown remote candidate type:%s for component:%d stream:%d!\n", handle->handle_id, rtype, rcomponent, stream->stream_id); } if(c != NULL) { c->component_id = rcomponent; c->stream_id = stream->stream_id; #ifndef HAVE_LIBNICE_TCP c->transport = NICE_CANDIDATE_TRANSPORT_UDP; #else if(!strcasecmp(rtransport, "udp")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Transport: UDP\n", handle->handle_id); c->transport = NICE_CANDIDATE_TRANSPORT_UDP; } else { /* Check the type (https://tools.ietf.org/html/rfc6544#section-4.5) */ const char *type = NULL; int ctype = 0; if(strstr(candidate, "tcptype active")) { type = "active"; ctype = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; } else if(strstr(candidate, "tcptype passive")) { type = "passive"; ctype = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; } else if(strstr(candidate, "tcptype so")) { type = "so"; ctype = NICE_CANDIDATE_TRANSPORT_TCP_SO; } else { /* TODO: We should actually stop here... */ JANUS_LOG(LOG_ERR, "[%"SCNu64"] Missing tcptype info for the TCP candidate!\n", handle->handle_id); } JANUS_LOG(LOG_VERB, "[%"SCNu64"] Transport: TCP (%s)\n", handle->handle_id, type); c->transport = ctype; } #endif strncpy(c->foundation, rfoundation, NICE_CANDIDATE_MAX_FOUNDATION); c->priority = rpriority; nice_address_set_from_string(&c->addr, rip); nice_address_set_port(&c->addr, rport); c->username = g_strdup(stream->ruser); c->password = g_strdup(stream->rpass); if(c->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || c->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE) { nice_address_set_from_string(&c->base_addr, rrelip); nice_address_set_port(&c->base_addr, rrelport); } else if(c->type == NICE_CANDIDATE_TYPE_RELAYED) { /* FIXME Do we really need the base address for TURN? */ nice_address_set_from_string(&c->base_addr, rrelip); nice_address_set_port(&c->base_addr, rrelport); } component->candidates = g_slist_append(component->candidates, c); JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Candidate added to the list! (%u elements for %d/%d)\n", handle->handle_id, g_slist_length(component->candidates), stream->stream_id, component->component_id); /* Save for the summary, in case we need it */ component->remote_candidates = g_slist_append(component->remote_candidates, g_strdup(candidate)); if(trickle) { if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_START)) { /* This is a trickle candidate and ICE has started, we should process it right away */ if(!component->process_started) { /* Actually, ICE has JUST started for this component, take care of the candidates we've added so far */ JANUS_LOG(LOG_INFO, "[%"SCNu64"] ICE already started for this component, setting candidates we have up to now\n", handle->handle_id); janus_ice_setup_remote_candidates(handle, component->stream_id, component->component_id); } else { GSList *candidates = NULL; candidates = g_slist_append(candidates, c); if(nice_agent_set_remote_candidates(handle->agent, stream->stream_id, component->component_id, candidates) < 1) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] Failed to add trickle candidate :-(\n", handle->handle_id); } else { JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Trickle candidate added!\n", handle->handle_id); } g_slist_free(candidates); } } else { /* ICE hasn't started yet: to make sure we're not stuck, also check if we stopped processing the SDP */ if(!janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_PROCESSING_OFFER)) { janus_flags_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_START); /* This is a trickle candidate and ICE has started, we should process it right away */ if(!component->process_started) { /* Actually, ICE has JUST started for this component, take care of the candidates we've added so far */ JANUS_LOG(LOG_INFO, "[%"SCNu64"] SDP processed but ICE not started yet for this component, setting candidates we have up to now\n", handle->handle_id); janus_ice_setup_remote_candidates(handle, component->stream_id, component->component_id); } else { GSList *candidates = NULL; candidates = g_slist_append(candidates, c); if(nice_agent_set_remote_candidates(handle->agent, stream->stream_id, component->component_id, candidates) < 1) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] Failed to add trickle candidate :-(\n", handle->handle_id); } else { JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Trickle candidate added!\n", handle->handle_id); } g_slist_free(candidates); } } else { /* Still processing the offer/answer: queue the trickle candidate for now, we'll process it later */ JANUS_LOG(LOG_VERB, "[%"SCNu64"] Queueing trickle candidate, status is not START yet\n", handle->handle_id); } } } } } } else { JANUS_LOG(LOG_ERR, "[%"SCNu64"] Failed to parse candidate (res=%d)...\n", handle->handle_id, res); janus_mutex_unlock(&handle->mutex); return res; } janus_mutex_unlock(&handle->mutex); return 0; }
/* Parse SDP */ int janus_sdp_parse(janus_ice_handle *handle, janus_sdp *sdp) { if(!handle || !sdp) return -1; //~ sdp_parser_t *parser = (sdp_parser_t *)sdp->parser; //~ if(!parser) //~ return -1; sdp_session_t *remote_sdp = (sdp_session_t *)sdp->sdp; if(!remote_sdp) return -1; janus_ice_stream *stream = NULL; janus_ice_component *component = NULL; gchar *ruser = NULL, *rpass = NULL, *rhashing = NULL, *rfingerprint = NULL; int audio = 0, video = 0; gint rstream = 0; /* Ok, let's start */ sdp_attribute_t *a = remote_sdp->sdp_attributes; while(a) { if(a->a_name) { if(!strcasecmp(a->a_name, "fingerprint")) { JANUS_PRINT("[%"SCNu64"] Fingerprint (global) : %s\n", handle->handle_id, a->a_value); if(strcasestr(a->a_value, "sha-256 ") == a->a_value) { rhashing = g_strdup("sha-256"); rfingerprint = g_strdup(a->a_value + strlen("sha-256 ")); } else if(strcasestr(a->a_value, "sha-1 ") == a->a_value) { JANUS_PRINT("[%"SCNu64"] Hashing algorithm not the one we expected (sha-1 instead of sha-256), but that's ok\n", handle->handle_id); rhashing = g_strdup("sha-1"); rfingerprint = g_strdup(a->a_value + strlen("sha-1 ")); } else { /* FIXME We should handle this somehow anyway... OpenSSL supports them all */ JANUS_PRINT("[%"SCNu64"] Hashing algorithm not the one we expected (sha-256/sha-1), *NOT* cool\n", handle->handle_id); } } else if(!strcasecmp(a->a_name, "ice-ufrag")) { JANUS_PRINT("[%"SCNu64"] ICE ufrag (global): %s\n", handle->handle_id, a->a_value); ruser = g_strdup(a->a_value); } else if(!strcasecmp(a->a_name, "ice-pwd")) { JANUS_PRINT("[%"SCNu64"] ICE pwd (global): %s\n", handle->handle_id, a->a_value); rpass = g_strdup(a->a_value); } } a = a->a_next; } sdp_media_t *m = remote_sdp->sdp_media; while(m) { /* What media type is this? */ if(m->m_type == sdp_media_audio) { audio++; if(audio > 1) { m = m->m_next; continue; } JANUS_PRINT("[%"SCNu64"] Parsing audio candidates (stream=%d)...\n", handle->handle_id, handle->audio_id); rstream = handle->audio_id; stream = g_hash_table_lookup(handle->streams, GUINT_TO_POINTER(handle->audio_id)); } else if(m->m_type == sdp_media_video) { video++; if(video > 1) { m = m->m_next; continue; } JANUS_PRINT("[%"SCNu64"] Parsing video candidates (stream=%d)...\n", handle->handle_id, handle->video_id); rstream = handle->video_id; stream = g_hash_table_lookup(handle->streams, GUINT_TO_POINTER(handle->video_id)); } else { JANUS_PRINT("[%"SCNu64"] Skipping unsupported media line...\n", handle->handle_id); m = m->m_next; continue; } /* Look for ICE credentials and fingerprint first: check media attributes */ a = m->m_attributes; while(a) { if(a->a_name) { if(!strcasecmp(a->a_name, "fingerprint")) { JANUS_PRINT("[%"SCNu64"] Fingerprint (local) : %s\n", handle->handle_id, a->a_value); if(strcasestr(a->a_value, "sha-256 ") == a->a_value) { if(rhashing) g_free(rhashing); /* FIXME We're overwriting the global one, if any */ rhashing = g_strdup("sha-256"); if(rfingerprint) g_free(rfingerprint); /* FIXME We're overwriting the global one, if any */ rfingerprint = g_strdup(a->a_value + strlen("sha-256 ")); } else if(strcasestr(a->a_value, "sha-1 ") == a->a_value) { JANUS_PRINT("[%"SCNu64"] Hashing algorithm not the one we expected (sha-1 instead of sha-256), but that's ok\n", handle->handle_id); if(rhashing) g_free(rhashing); /* FIXME We're overwriting the global one, if any */ rhashing = g_strdup("sha-1"); if(rfingerprint) g_free(rfingerprint); /* FIXME We're overwriting the global one, if any */ rfingerprint = g_strdup(a->a_value + strlen("sha-1 ")); } else { /* FIXME We should handle this somehow anyway... OpenSSL supports them all */ JANUS_PRINT("[%"SCNu64"] Hashing algorithm not the one we expected (sha-256), *NOT* cool\n", handle->handle_id); } } else if(!strcasecmp(a->a_name, "setup")) { JANUS_PRINT("[%"SCNu64"] DTLS setup (local): %s\n", handle->handle_id, a->a_value); if(!strcasecmp(a->a_value, "actpass") || !strcasecmp(a->a_value, "passive")) stream->dtls_role = JANUS_DTLS_ROLE_CLIENT; else if(!strcasecmp(a->a_value, "active")) stream->dtls_role = JANUS_DTLS_ROLE_SERVER; /* TODO Handle holdconn... */ } else if(!strcasecmp(a->a_name, "ice-ufrag")) { JANUS_PRINT("[%"SCNu64"] ICE ufrag (local): %s\n", handle->handle_id, a->a_value); if(ruser) g_free(ruser); /* FIXME We're overwriting the global one, if any */ ruser = g_strdup(a->a_value); } else if(!strcasecmp(a->a_name, "ice-pwd")) { JANUS_PRINT("[%"SCNu64"] ICE pwd (local): %s\n", handle->handle_id, a->a_value); if(rpass) g_free(rpass); /* FIXME We're overwriting the global one, if any */ rpass = g_strdup(a->a_value); } } a = a->a_next; } if(!ruser || !rpass || !rfingerprint || !rhashing) { /* Missing mandatory information, failure... */ if(ruser) g_free(ruser); ruser = NULL; if(rpass) g_free(rpass); rpass = NULL; if(rhashing) g_free(rhashing); rhashing = NULL; if(rfingerprint) g_free(rfingerprint); rfingerprint = NULL; return -2; } handle->remote_hashing = g_strdup(rhashing); handle->remote_fingerprint = g_strdup(rfingerprint); /* Now look for candidates and codec info */ a = m->m_attributes; while(a) { if(a->a_name) { if(!strcasecmp(a->a_name, "candidate")) { char rfoundation[32], rtransport[4], rip[24], rtype[6], rrelip[24]; guint32 rcomponent, rpriority, rport, rrelport; int res = 0; if((res = sscanf(a->a_value, "%31s %30u %3s %30u %23s %30u typ %5s %*s %23s %*s %30u", rfoundation, &rcomponent, rtransport, &rpriority, rip, &rport, rtype, rrelip, &rrelport)) >= 7) { /* Add remote candidate */ JANUS_PRINT("[%"SCNu64"] Adding remote candidate for component %d to stream %d\n", handle->handle_id, rcomponent, rstream); component = g_hash_table_lookup(stream->components, GUINT_TO_POINTER(rcomponent)); if(component == NULL) { JANUS_DEBUG("[%"SCNu64"] No such component %d in stream %d?\n", handle->handle_id, rcomponent, rstream); } else { component->component_id = rcomponent; component->stream_id = rstream; NiceCandidate *c = NULL; if(!strcasecmp(rtype, "host")) { JANUS_PRINT("[%"SCNu64"] Adding host candidate... %s:%d\n", handle->handle_id, rip, rport); /* We only support UDP... */ if(strcasecmp(rtransport, "udp")) { JANUS_DEBUG("[%"SCNu64"] Unsupported transport %s!\n", handle->handle_id, rtransport); } else { c = nice_candidate_new(NICE_CANDIDATE_TYPE_HOST); } } else if(!strcasecmp(rtype, "srflx")) { JANUS_PRINT("[%"SCNu64"] Adding srflx candidate... %s:%d --> %s:%d \n", handle->handle_id, rrelip, rrelport, rip, rport); /* We only support UDP... */ if(strcasecmp(rtransport, "udp")) { JANUS_DEBUG("[%"SCNu64"] Unsupported transport %s!\n", handle->handle_id, rtransport); }else { c = nice_candidate_new(NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE); } } else if(!strcasecmp(rtype, "prflx")) { JANUS_PRINT("[%"SCNu64"] Adding prflx candidate... %s:%d --> %s:%d\n", handle->handle_id, rrelip, rrelport, rip, rport); /* We only support UDP... */ if(strcasecmp(rtransport, "udp")) { JANUS_DEBUG("[%"SCNu64"] Unsupported transport %s!\n", handle->handle_id, rtransport); } else { c = nice_candidate_new(NICE_CANDIDATE_TYPE_PEER_REFLEXIVE); } } else if(!strcasecmp(rtype, "relay")) { JANUS_PRINT("[%"SCNu64"] Adding relay candidate... %s:%d --> %s:%d\n", handle->handle_id, rrelip, rrelport, rip, rport); /* We only support UDP/TCP/TLS... */ if(strcasecmp(rtransport, "udp") && strcasecmp(rtransport, "tcp") && strcasecmp(rtransport, "tls")) { JANUS_DEBUG("[%"SCNu64"] Unsupported transport %s!\n", handle->handle_id, rtransport); } else { c = nice_candidate_new(NICE_CANDIDATE_TYPE_RELAYED); } } else { /* FIXME What now? */ JANUS_DEBUG("[%"SCNu64"] Unknown candidate type %s!\n", handle->handle_id, rtype); } if(c != NULL) { c->component_id = rcomponent; c->stream_id = rstream; c->transport = NICE_CANDIDATE_TRANSPORT_UDP; strncpy(c->foundation, rfoundation, NICE_CANDIDATE_MAX_FOUNDATION); c->priority = rpriority; nice_address_set_from_string(&c->addr, rip); nice_address_set_port(&c->addr, rport); c->username = g_strdup(ruser); c->password = g_strdup(rpass); if(c->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || c->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE) { nice_address_set_from_string(&c->base_addr, rrelip); nice_address_set_port(&c->base_addr, rrelport); } else if(c->type == NICE_CANDIDATE_TYPE_RELAYED) { /* FIXME Do we really need the base address for TURN? */ nice_address_set_from_string(&c->base_addr, rrelip); nice_address_set_port(&c->base_addr, rrelport); } component->candidates = g_slist_append(component->candidates, c); JANUS_PRINT("[%"SCNu64"] Candidate added to the list! (%u elements for %d/%d)\n", handle->handle_id, g_slist_length(component->candidates), stream->stream_id, component->component_id); } } } else { JANUS_DEBUG("[%"SCNu64"] Failed to parse candidate... (%d)\n", handle->handle_id, res); } } } a = a->a_next; } m = m->m_next; } if(ruser) g_free(ruser); ruser = NULL; if(rpass) g_free(rpass); rpass = NULL; if(rhashing) g_free(rhashing); rhashing = NULL; if(rfingerprint) g_free(rfingerprint); rfingerprint = NULL; return 0; /* FIXME Handle errors better */ }
bool NiceConnection::setRemoteCandidates(std::vector<CandidateInfo> &candidates, bool isBundle) { if(agent_==NULL){ running_=false; return false; } GSList* candList = NULL; ELOG_DEBUG("Setting remote candidates %lu, mediatype %d", candidates.size(), this->mediaType); for (unsigned int it = 0; it < candidates.size(); it++) { NiceCandidateType nice_cand_type; CandidateInfo cinfo = candidates[it]; //If bundle we will add the candidates regardless the mediaType if (cinfo.componentId !=1 || (!isBundle && cinfo.mediaType!=this->mediaType )) continue; switch (cinfo.hostType) { case HOST: nice_cand_type = NICE_CANDIDATE_TYPE_HOST; break; case SRFLX: nice_cand_type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; break; case PRFLX: nice_cand_type = NICE_CANDIDATE_TYPE_PEER_REFLEXIVE; break; case RELAY: nice_cand_type = NICE_CANDIDATE_TYPE_RELAYED; break; default: nice_cand_type = NICE_CANDIDATE_TYPE_HOST; break; } NiceCandidate* thecandidate = nice_candidate_new(nice_cand_type); thecandidate->username = strdup(cinfo.username.c_str()); thecandidate->password = strdup(cinfo.password.c_str()); thecandidate->stream_id = (guint) 1; thecandidate->component_id = cinfo.componentId; thecandidate->priority = cinfo.priority; thecandidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; nice_address_set_from_string(&thecandidate->addr, cinfo.hostAddress.c_str()); nice_address_set_port(&thecandidate->addr, cinfo.hostPort); if (cinfo.hostType == RELAY||cinfo.hostType==SRFLX){ nice_address_set_from_string(&thecandidate->base_addr, cinfo.rAddress.c_str()); nice_address_set_port(&thecandidate->base_addr, cinfo.rPort); ELOG_DEBUG("Adding remote candidate type %d addr %s port %d raddr %s rport %d", cinfo.hostType, cinfo.hostAddress.c_str(), cinfo.hostPort, cinfo.rAddress.c_str(), cinfo.rPort); }else{ ELOG_DEBUG("Adding remote candidate type %d addr %s port %d priority %d componentId %d, username %s, pass %s", cinfo.hostType, cinfo.hostAddress.c_str(), cinfo.hostPort, cinfo.priority, cinfo.componentId, cinfo.username.c_str(), cinfo.password.c_str() ); } candList = g_slist_prepend(candList, thecandidate); } //TODO: Set Component Id properly, now fixed at 1 nice_agent_set_remote_candidates(agent_, (guint) 1, 1, candList); g_slist_free_full(candList, (GDestroyNotify)&nice_candidate_free); return true; }