Commit be44f5c2 authored by Youness Alaoui's avatar Youness Alaoui

Merge commit 'remotes/tester/force-candidate-kakaroto' into tester-force-candidates

parents ad9e2e2f bfab5cb7
......@@ -1977,3 +1977,62 @@ guint agent_timeout_add_with_context (NiceAgent *agent, guint interval,
return id;
}
/**
* nice_agent_set_selected_remote_candidate:
* @agent: a #NiceAgent
* @stream_id: the stream id
* @component_id: the component id
* @candidate: the #NiceCandidate to force
*
* Sets the selected remote candidate for media transmission
* for given stream component. Calling this function will
* disable all further ICE processing (connection check,
* state machine updates, etc). Note that keepalives will
* continue to be sent.
*
* Returns: %TRUE on success, %FALSE on failure
*/
NICEAPI_EXPORT gboolean
nice_agent_set_selected_remote_candidate (
NiceAgent *agent,
guint stream_id,
guint component_id,
NiceCandidate *candidate)
{
Component *component;
Stream *stream;
NiceCandidate *lcandidate = NULL;
gboolean ret = FALSE;
g_static_rec_mutex_lock (&agent->mutex);
/* step: check if the component exists*/
if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) {
goto done;
}
/* step: stop connectivity checks (note: for the whole stream) */
conn_check_prune_stream (agent, stream);
/* step: set the selected pair */
lcandidate = component_set_selected_remote_candidate (agent, component,
candidate);
if (!lcandidate)
goto done;
/* step: change component state */
agent_signal_component_state_change (agent, stream_id, component_id, NICE_COMPONENT_STATE_READY);
agent_signal_new_selected_pair (agent, stream_id, component_id,
lcandidate->foundation,
candidate->foundation);
ret = TRUE;
done:
g_static_rec_mutex_unlock (&agent->mutex);
return ret;
}
......@@ -238,6 +238,14 @@ nice_agent_set_selected_pair (
const gchar *lfoundation,
const gchar *rfoundation);
gboolean
nice_agent_set_selected_remote_candidate (
NiceAgent *agent,
guint stream_id,
guint component_id,
NiceCandidate *candidate);
G_END_DECLS
#endif /* _AGENT_H */
......
......@@ -243,3 +243,66 @@ component_find_remote_candidate (const Component *component, const NiceAddress *
return NULL;
}
/*
* Sets the desired remote candidate as the selected pair
*
* It will start sending on the highest priority pair available with
* this candidate.
*/
NiceCandidate *
component_set_selected_remote_candidate (NiceAgent *agent, Component *component,
NiceCandidate *candidate)
{
NiceCandidate *local = NULL;
NiceCandidate *remote = NULL;
guint32 priority = 0;
GSList *item = NULL;
for (item = component->local_candidates; item; item = g_slist_next (item)) {
NiceCandidate *tmp = item->data;
guint32 tmp_prio = 0;
if (tmp->transport != candidate->transport ||
tmp->addr.s.addr.sa_family != candidate->addr.s.addr.sa_family ||
tmp->type != NICE_CANDIDATE_TYPE_HOST)
continue;
tmp_prio = agent_candidate_pair_priority (agent, tmp, candidate);
if (tmp_prio > priority) {
priority = tmp_prio;
local = tmp;
}
}
if (local == NULL)
return NULL;
remote = component_find_remote_candidate (component, &candidate->addr,
candidate->transport);
if (!remote) {
GSList *modified_list = NULL;
remote = nice_candidate_copy (candidate);
modified_list = g_slist_append (component->remote_candidates,
remote);
if (modified_list) {
component->remote_candidates = modified_list;
agent_signal_new_remote_candidate (agent, remote);
}
else { /* error: memory alloc / list */
nice_candidate_free (remote), remote = NULL;
return NULL;
}
}
component->selected_pair.local = local;
component->selected_pair.remote = remote;
component->selected_pair.priority = priority;
return local;
}
......@@ -116,6 +116,10 @@ component_update_selected_pair (Component *component, const CandidatePair *pair)
NiceCandidate *
component_find_remote_candidate (const Component *component, const NiceAddress *addr, NiceCandidateTransport transport);
NiceCandidate *
component_set_selected_remote_candidate (NiceAgent *agent, Component *component,
NiceCandidate *candidate);
G_END_DECLS
#endif /* _NICE_COMPONENT_H */
......
......@@ -61,6 +61,7 @@ static int global_lagent_cands = 0;
static int global_ragent_cands = 0;
static gint global_ragent_read = 0;
static gint global_ragent_read_exit = 0;
static gboolean global_accept_non_data = TRUE;
static void priv_print_global_status (void)
{
......@@ -76,9 +77,7 @@ static gboolean timer_cb (gpointer pointer)
/* signal status via a global variable */
/* note: should not be reached, abort */
g_debug ("ERROR: test has got stuck, aborting...");
exit (-1);
g_error ("ERROR: test has got stuck, aborting...");
}
static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data)
......@@ -88,6 +87,16 @@ static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id,
/* XXX: dear compiler, these are for you: */
(void)agent; (void)stream_id; (void)component_id; (void)buf;
/*
* Lets ignore stun packets that got through
*/
if (len != 16 || strncmp ("1234567812345678", buf, 16)) {
if (global_accept_non_data)
return;
else
g_error ("Got non-data packet of lenght %u", len);
}
if ((intptr_t)user_data == 2) {
global_ragent_read += len;
......@@ -331,6 +340,137 @@ static int run_fallback_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress
return 0;
}
static int run_safe_fallback_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr)
{
NiceAddress laddr, raddr, laddr_rtcp, raddr_rtcp;
NiceCandidate cdes;
guint ls_id, rs_id;
memset (&cdes, 0, sizeof(NiceCandidate));
cdes.priority = 100000;
strcpy (cdes.foundation, "1");
cdes.type = NICE_CANDIDATE_TYPE_HOST;
cdes.transport = NICE_CANDIDATE_TRANSPORT_UDP;
cdes.base_addr = *baseaddr;
/* step: initialize variables modified by the callbacks */
global_components_ready = 0;
global_components_ready_exit = 4;
global_components_failed = 0;
global_components_failed_exit = 4;
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_ragent_read_exit = -1;
global_accept_non_data = 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);
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, (gpointer)1);
nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP,
g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1);
nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2);
nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP,
g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)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-fallback: 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-fallback: 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-fallback: 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-fallback: 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-fallback: local RTCP port L %u",
nice_address_get_port (&laddr_rtcp));
/* step: exchange candidate information but not the credentials */
cdes.component_id = NICE_COMPONENT_TYPE_RTP;
cdes.addr = raddr;
g_assert (nice_agent_set_selected_remote_candidate (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, &cdes));
cdes.addr = laddr;
g_assert (nice_agent_set_selected_remote_candidate (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, &cdes));
cdes.component_id = NICE_COMPONENT_TYPE_RTCP;
cdes.addr = raddr_rtcp;
g_assert (nice_agent_set_selected_remote_candidate (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, &cdes));
cdes.addr = laddr_rtcp;
g_assert (nice_agent_set_selected_remote_candidate (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, &cdes));
g_debug ("test-fallback: Requested for fallback, running mainloop until component state change is completed...");
/* step: run the mainloop until connectivity checks succeed
* (see timer_cb() above) */
if (global_components_ready < global_components_ready_exit)
g_main_loop_run (global_mainloop);
/* note: verify that agents are in correct state */
g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY);
/* step: next send a packet -> should work even if no ICE processing
* has been done */
g_debug ("test-fallback: Sent a payload packet, run mainloop until packet received.");
/* step: send a new test packet from L ot R */
global_ragent_read = 0;
g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16);
global_ragent_read_exit = 16;
g_main_loop_run (global_mainloop);
/* note: verify that payload was succesfully received */
g_assert (global_ragent_read == 16);
g_debug ("test-fallback: Ran mainloop, removing streams...");
/* step: clean up resources and exit */
nice_agent_remove_stream (lagent, ls_id);
nice_agent_remove_stream (ragent, rs_id);
g_debug ("test-fallback: test COMPLETED");
return 0;
}
int main (void)
{
NiceAgent *lagent, *ragent; /* agent's L and R */
......@@ -406,6 +546,14 @@ int main (void)
g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY);
/* step: run the safe test without sending any stnu */
g_debug ("test-fallback: TEST STARTS / safe fallback test");
result = run_safe_fallback_test (lagent, ragent, &baseaddr);
priv_print_global_status ();
g_assert (result == 0);
g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);
g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY);
g_object_unref (lagent);
g_object_unref (ragent);
......
......@@ -74,9 +74,7 @@ static gboolean timer_cb (gpointer pointer)
/* signal status via a global variable */
/* note: should not be reached, abort */
g_debug ("ERROR: test has got stuck, aborting...");
exit (-1);
g_error ("ERROR: test has got stuck, aborting...");
}
static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data)
......@@ -86,6 +84,14 @@ static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id,
/* XXX: dear compiler, these are for you: */
(void)agent; (void)stream_id; (void)component_id; (void)buf;
/*
* Lets ignore stun packets that got through
*/
if (len < 8)
return;
if (strncmp ("12345678", buf, 8))
return;
if ((intptr_t)user_data == 2) {
global_ragent_read = len;
g_main_loop_quit (global_mainloop);
......
......@@ -31,6 +31,7 @@ nice_agent_send
nice_agent_set_remote_candidates
nice_agent_set_remote_credentials
nice_agent_set_selected_pair
nice_agent_set_selected_remote_candidate
nice_candidate_free
nice_candidate_ice_priority
nice_candidate_ice_priority_full
......
......@@ -96,7 +96,7 @@ finish_check (StunAgent *agent, StunMessage *msg)
uint8_t buf[STUN_MAX_MESSAGE_SIZE + 8];
size_t len;
uint16_t plen;
StunMessage msg2;
StunMessage msg2 = {0};
msg2.agent = msg->agent;
msg2.buffer = buf;
msg2.buffer_len = sizeof(buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment