diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2017-04-04 21:27:39 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2017-04-11 17:50:40 -0400 |
commit | ffc7fddac42728bac6e4753a17bc52e5e610ae8b (patch) | |
tree | 8708b9dcd7206ce1c843b30a8a5b5a32016d40e4 /agent/component.c | |
parent | 1e9e28dbc98b4f6a7cf4bda0ca73b5abc2735ddc (diff) | |
download | libnice-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.c | 90 |
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; +} |