diff options
Diffstat (limited to 'agent/candidate.c')
-rw-r--r-- | agent/candidate.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/agent/candidate.c b/agent/candidate.c index a472c4a..0277a79 100644 --- a/agent/candidate.c +++ b/agent/candidate.c @@ -52,6 +52,7 @@ #include "agent.h" #include "component.h" +#include "interfaces.h" G_DEFINE_BOXED_TYPE (NiceCandidate, nice_candidate, nice_candidate_copy, nice_candidate_free); @@ -144,6 +145,43 @@ nice_candidate_ice_local_preference_full (guint direction_preference, other_preference); } +static guint8 +nice_candidate_ip_local_preference (const NiceCandidate *candidate) +{ + guint8 preference = 0; + gchar ip_string[INET6_ADDRSTRLEN]; + GList/*<owned gchar*>*/ *ips = NULL; + GList/*<unowned gchar*>*/ *iter; + + /* Ensure otherwise identical host candidates with only different IP addresses + * (multihomed host) get assigned different priorities. Position of the IP in + * the list obtained from nice_interfaces_get_local_ips() serves here as the + * distinguishing value of other_preference. Reflexive and relayed candidates + * are likewise differentiated by their base address. + * + * This is required by RFC 5245 Section 4.1.2.1: + * https://tools.ietf.org/html/rfc5245#section-4.1.2.1 + */ + if (candidate->type == NICE_CANDIDATE_TYPE_HOST) { + nice_address_to_string (&candidate->addr, ip_string); + } else { + nice_address_to_string (&candidate->base_addr, ip_string); + } + + ips = nice_interfaces_get_local_ips (TRUE); + + for (iter = ips; iter; iter = g_list_next (iter)) { + if (g_strcmp0 (ip_string, iter->data) == 0) { + break; + } + ++preference; + } + + g_list_free_full (ips, g_free); + + return preference; +} + static guint16 nice_candidate_ice_local_preference (const NiceCandidate *candidate) { @@ -178,7 +216,8 @@ nice_candidate_ice_local_preference (const NiceCandidate *candidate) break; } - return nice_candidate_ice_local_preference_full (direction_preference, 1); + return nice_candidate_ice_local_preference_full (direction_preference, + nice_candidate_ip_local_preference (candidate)); } static guint32 @@ -214,7 +253,7 @@ nice_candidate_ms_ice_local_preference (const NiceCandidate *candidate) } return nice_candidate_ms_ice_local_preference_full(transport_preference, - direction_preference, 0); + direction_preference, nice_candidate_ip_local_preference (candidate)); } static guint8 |