#include "agent.h"
#include "component.h"
+#include "interfaces.h"
G_DEFINE_BOXED_TYPE (NiceCandidate, nice_candidate, nice_candidate_copy,
nice_candidate_free);
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)
{
}
return nice_candidate_ms_ice_local_preference_full(transport_preference,
- direction_preference, 0);
+ direction_preference, nice_candidate_ip_local_preference (candidate));
}
static guint8