Commit a08fe4cb authored by Kai Vehmanen's avatar Kai Vehmanen

Changed semantics and implementation of set_remote_candidates(). Candidates...

Changed semantics and implementation of set_remote_candidates(). Candidates given as argument are used to update, but not replace, the list of remote candidates.

darcs-hash:20080311152130-77cd4-a48cc0b77634773da56693880feec4394e0983a8.gz
parent edadfe7b
......@@ -756,6 +756,12 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr)
return FALSE;
}
/**
* Adds a new, or updates an existing, remote candidate.
*
* @return TRUE if candidate was succesfully added or
* update, otherwise FALSE
*/
static gboolean priv_add_remote_candidate (
NiceAgent *agent,
guint stream_id,
......@@ -777,55 +783,70 @@ static gboolean priv_add_remote_candidate (
if (!agent_find_component (agent, stream_id, component_id, NULL, &component))
return FALSE;
if (username)
username_dup = g_strdup (username);
if (password)
password_dup = g_strdup (password);
candidate = nice_candidate_new (type);
/* step: check whether the candidate already exists */
candidate = component_find_remote_candidate(component, addr, transport);
if (candidate) {
GSList *modified_list = g_slist_append (component->remote_candidates, candidate);
if (modified_list) {
component->remote_candidates = modified_list;
candidate->stream_id = stream_id;
candidate->component_id = component_id;
candidate->type = type;
if (addr)
candidate->addr = *addr;
g_debug("Update existing remote candidate %p.", candidate);
/* case 1: an existing candidate, update the attributes */
candidate->type = type;
if (related_addr)
candidate->base_addr = *related_addr;
candidate->priority = priority;
if (foundation)
strncpy(candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION);
/* note: username and password must remain the same during
* a session; see sect 9.1.2 in ICE ID-19 */
if (conn_check_add_for_candidate (agent, stream_id, component, candidate) < 0)
error_flag = TRUE;
}
else {
/* case 2: add a new candidate */
if (username)
username_dup = g_strdup (username);
if (password)
password_dup = g_strdup (password);
candidate = nice_candidate_new (type);
if (candidate) {
GSList *modified_list = g_slist_append (component->remote_candidates, candidate);
if (modified_list) {
component->remote_candidates = modified_list;
candidate->stream_id = stream_id;
candidate->component_id = component_id;
candidate->type = type;
if (addr)
candidate->addr = *addr;
#ifndef NDEBUG
{
gchar tmpbuf[INET6_ADDRSTRLEN];
nice_address_to_string (addr, tmpbuf);
g_debug ("Adding remote candidate with addr [%s]:%u.", tmpbuf,
nice_address_get_port (addr));
}
{
gchar tmpbuf[INET6_ADDRSTRLEN];
nice_address_to_string (addr, tmpbuf);
g_debug ("Adding remote candidate with addr [%s]:%u.", tmpbuf,
nice_address_get_port (addr));
}
#endif
if (related_addr)
candidate->base_addr = *related_addr;
candidate->transport = transport;
candidate->priority = priority;
candidate->username = username_dup;
candidate->password = password_dup;
if (foundation)
g_strlcpy (candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION);
/* XXX: may be called before candidate-gathering-done is signalled,
* make sure this is handled correctly! */
if (conn_check_add_for_candidate (agent, stream_id, component, candidate) < 0)
if (related_addr)
candidate->base_addr = *related_addr;
candidate->transport = transport;
candidate->priority = priority;
candidate->username = username_dup;
candidate->password = password_dup;
if (foundation)
g_strlcpy (candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION);
if (conn_check_add_for_candidate (agent, stream_id, component, candidate) < 0)
error_flag = TRUE;
}
else /* memory alloc error: list insert */
error_flag = TRUE;
}
else /* memory alloc error: list insert */
else /* memory alloc error: candidate creation */
error_flag = TRUE;
}
else /* memory alloc error: candidate creation */
error_flag = TRUE;
}
if (error_flag) {
if (candidate)
......@@ -973,6 +994,10 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
const GSList *i;
int added = 0;
if (agent->discovery_unsched_items > 0)
return -1;
/* XXX: clean up existing remote candidates, and abort any
* connectivity checks using these candidates */
......
......@@ -220,3 +220,26 @@ void component_update_selected_pair (Component *component, const CandidatePair *
component->selected_pair.remote = pair->remote;
component->selected_pair.priority = pair->priority;
}
/**
* Finds a remote candidate with matching address and
* transport.
*
* @return pointer to candidate or NULL if not found
*/
NiceCandidate *
component_find_remote_candidate (const Component *component, const NiceAddress *addr, NiceCandidateTransport transport)
{
GSList *i;
for (i = component->remote_candidates; i; i = i->next) {
NiceCandidate *candidate = i->data;
if (nice_address_equal(&candidate->addr, addr) &&
candidate->transport == transport)
return candidate;
}
return NULL;
}
......@@ -108,6 +108,9 @@ component_restart (Component *cmp);
void
component_update_selected_pair (Component *component, const CandidatePair *pair);
NiceCandidate *
component_find_remote_candidate (const Component *component, const NiceAddress *addr, NiceCandidateTransport transport);
G_END_DECLS
#endif /* _NICE_COMPONENT_H */
......
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