summaryrefslogtreecommitdiff
path: root/agent/component.c
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2017-04-04 21:27:39 -0400
committerOlivier CrĂȘte <olivier.crete@collabora.com>2017-04-11 17:50:40 -0400
commitffc7fddac42728bac6e4753a17bc52e5e610ae8b (patch)
tree8708b9dcd7206ce1c843b30a8a5b5a32016d40e4 /agent/component.c
parent1e9e28dbc98b4f6a7cf4bda0ca73b5abc2735ddc (diff)
downloadlibnice-ffc7fddac42728bac6e4753a17bc52e5e610ae8b.tar.gz
agent: Drop packets not from validated addresses
This is required by the WebRTC spec. Remove test-mainloop as it doesnt even try to do a negotiation. https://phabricator.freedesktop.org/T104 Differential Revision: https://phabricator.freedesktop.org/D1716
Diffstat (limited to 'agent/component.c')
-rw-r--r--agent/component.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/agent/component.c b/agent/component.c
index a679b30..ba28ffa 100644
--- a/agent/component.c
+++ b/agent/component.c
@@ -435,6 +435,8 @@ nice_component_update_selected_pair (NiceComponent *component, const CandidatePa
component->selected_pair.remote = pair->remote;
component->selected_pair.priority = pair->priority;
component->selected_pair.prflx_priority = pair->prflx_priority;
+
+ nice_component_add_valid_candidate (component, pair->remote);
}
/*
@@ -514,6 +516,11 @@ nice_component_set_selected_remote_candidate (NiceComponent *component,
component->selected_pair.remote = remote;
component->selected_pair.priority = priority;
+ /* Get into fallback mode where packets from any source is accepted once
+ * this has been called. This is the expected behavior of pre-ICE SIP.
+ */
+ component->fallback_mode = TRUE;
+
return local;
}
@@ -1107,6 +1114,9 @@ nice_component_finalize (GObject *obj)
g_warn_if_fail (cmp->remote_candidates == NULL);
g_warn_if_fail (cmp->incoming_checks == NULL);
+ g_list_free_full (cmp->valid_candidates,
+ (GDestroyNotify) nice_candidate_free);
+
g_clear_object (&cmp->tcp);
g_clear_object (&cmp->stop_cancellable);
g_clear_object (&cmp->iostream);
@@ -1421,3 +1431,83 @@ turn_server_unref (TurnServer *turn)
g_slice_free (TurnServer, turn);
}
}
+
+void
+nice_component_add_valid_candidate (NiceComponent *component,
+ const NiceCandidate *candidate)
+{
+ guint count = 0;
+ GList *item, *last = NULL;
+
+ for (item = component->valid_candidates; item; item = item->next) {
+ NiceCandidate *cand = item->data;
+
+ last = item;
+ count++;
+ if (nice_candidate_equal_target (cand, candidate))
+ return;
+ }
+
+ /* New candidate */
+
+ if (nice_debug_is_enabled ()) {
+ char str[INET6_ADDRSTRLEN];
+ nice_address_to_string (&candidate->addr, str);
+ nice_debug ("Agent %p : %d:%d Adding valid source"
+ " candidate: %s:%d trans: %d\n", component->agent,
+ candidate->stream_id, candidate->component_id, str,
+ nice_address_get_port (&candidate->addr), candidate->transport);
+ }
+
+ component->valid_candidates = g_list_prepend (
+ component->valid_candidates, nice_candidate_copy (candidate));
+
+ /* Delete the last one to make sure we don't have a list that is too long,
+ * the candidates are not freed on ICE restart as this would be more complex,
+ * we just keep the list not too long.
+ */
+ if (count > NICE_COMPONENT_MAX_VALID_CANDIDATES) {
+ NiceCandidate *cand = last->data;
+
+ component->valid_candidates = g_list_delete_link (
+ component->valid_candidates, last);
+ nice_candidate_free (cand);
+ }
+}
+
+gboolean
+nice_component_verify_remote_candidate (NiceComponent *component,
+ const NiceAddress *address, NiceSocket *nicesock)
+{
+ GList *item;
+
+ if (component->fallback_mode)
+ return TRUE;
+
+ for (item = component->valid_candidates; item; item = item->next) {
+ NiceCandidate *cand = item->data;
+
+ if (((nicesock->type == NICE_SOCKET_TYPE_TCP_BSD &&
+ (cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE ||
+ cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE ||
+ cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_SO)) ||
+ cand->transport == NICE_CANDIDATE_TRANSPORT_UDP) &&
+ nice_address_equal (address, &cand->addr)) {
+ /* fast return if it's already the first */
+ if (item == component->valid_candidates)
+ return TRUE;
+
+ /* Put the current candidate at the top so that in the normal use-case,
+ * this function becomes O(1).
+ */
+ component->valid_candidates = g_list_remove_link (
+ component->valid_candidates, item);
+ component->valid_candidates = g_list_concat (item,
+ component->valid_candidates);
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}