summaryrefslogtreecommitdiff
path: root/agent/candidate.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/candidate.c')
-rw-r--r--agent/candidate.c43
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