From f93f37f4f296a43be5600c46114ee3b29c984530 Mon Sep 17 00:00:00 2001 From: Youness Alaoui Date: Tue, 8 Apr 2014 20:21:55 -0400 Subject: [PATCH] Add support for ice-tcp priorities, udp-tunneled and nat-assisted priorities --- agent/agent.c | 3 +- agent/candidate.c | 77 +++++++++++++++++++++++++++++++++++++++++++++------ agent/candidate.h | 5 +++- agent/conncheck.c | 6 ++-- agent/discovery.c | 18 ++++++++---- agent/discovery.h | 3 +- tests/test-priority.c | 4 ++- 7 files changed, 96 insertions(+), 20 deletions(-) diff --git a/agent/agent.c b/agent/agent.c index 5138597..5a33c0d 100644 --- a/agent/agent.c +++ b/agent/agent.c @@ -2084,7 +2084,8 @@ static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto, component->id, &externaddr, transport, - local_candidate->sockptr); + local_candidate->sockptr, + TRUE); goto end; } } diff --git a/agent/candidate.c b/agent/candidate.c index f326482..06d3894 100644 --- a/agent/candidate.c +++ b/agent/candidate.c @@ -133,28 +133,89 @@ nice_candidate_ice_priority_full ( (0x100 - component_id)); } +static guint32 +nice_candidate_ice_local_priority_full (guint direction_preference, + guint other_preference) +{ + return (0x2000 * direction_preference + + other_preference); +} + +static guint16 +nice_candidate_ice_local_priority (const NiceCandidate *candidate) +{ + guint direction_preference; + + switch (candidate->transport) + { + case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: + if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || + candidate->type == NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED) + direction_preference = 4; + else + direction_preference = 6; + break; + case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: + if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || + candidate->type == NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED) + direction_preference = 2; + else + direction_preference = 4; + break; + case NICE_CANDIDATE_TRANSPORT_TCP_SO: + if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || + candidate->type == NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED) + direction_preference = 6; + else + direction_preference = 2; + break; + case NICE_CANDIDATE_TRANSPORT_UDP: + default: + return 1; + break; + } + + return nice_candidate_ice_local_priority_full (direction_preference, 1); +} guint32 -nice_candidate_ice_priority (const NiceCandidate *candidate) +nice_candidate_ice_priority (const NiceCandidate *candidate, + gboolean reliable, gboolean nat_assisted) { guint8 type_preference; + guint16 local_preference; switch (candidate->type) { case NICE_CANDIDATE_TYPE_HOST: - type_preference = NICE_CANDIDATE_TYPE_PREF_HOST; break; + type_preference = NICE_CANDIDATE_TYPE_PREF_HOST; + break; case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: - type_preference = NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE; break; + type_preference = NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE; + break; case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: - type_preference = NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE; break; + if (nat_assisted) + type_preference = NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED; + else + type_preference = NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE; + break; case NICE_CANDIDATE_TYPE_RELAYED: - type_preference = NICE_CANDIDATE_TYPE_PREF_RELAYED; break; + type_preference = NICE_CANDIDATE_TYPE_PREF_RELAYED; + break; default: - type_preference = 0; break; + type_preference = 0; + break; } - /* return _candidate_ice_priority (type_preference, 1, candidate->component_id); */ - return nice_candidate_ice_priority_full (type_preference, 1, candidate->component_id); + if (reliable && candidate->transport == NICE_CANDIDATE_TRANSPORT_UDP) { + type_preference = NICE_CANDIDATE_TYPE_PREF_UDP_TUNNELED; + } else if (!reliable && candidate->transport != NICE_CANDIDATE_TRANSPORT_UDP) { + type_preference = type_preference / 2 - 1; + } + local_preference = nice_candidate_ice_local_priority (candidate); + + return nice_candidate_ice_priority_full (type_preference, local_preference, + candidate->component_id); } /* diff --git a/agent/candidate.h b/agent/candidate.h index d492e5c..006e377 100644 --- a/agent/candidate.h +++ b/agent/candidate.h @@ -59,7 +59,9 @@ G_BEGIN_DECLS #define NICE_CANDIDATE_TYPE_PREF_HOST 120 #define NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE 110 +#define NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED 105 #define NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE 100 +#define NICE_CANDIDATE_TYPE_PREF_UDP_TUNNELED 75 #define NICE_CANDIDATE_TYPE_PREF_RELAYED 60 /* Max foundation size '1*32ice-char' plus terminating NULL, ICE ID-19 */ @@ -230,7 +232,8 @@ nice_candidate_ice_priority_full (guint type_pref, guint local_pref, guint component_id); guint32 -nice_candidate_ice_priority (const NiceCandidate *candidate); +nice_candidate_ice_priority (const NiceCandidate *candidate, + gboolean reliable, gboolean nat_assisted); guint64 nice_candidate_pair_priority (guint32 o_prio, guint32 a_prio); diff --git a/agent/conncheck.c b/agent/conncheck.c index bfbf30d..66142be 100644 --- a/agent/conncheck.c +++ b/agent/conncheck.c @@ -2335,7 +2335,8 @@ static gboolean priv_map_reply_to_discovery_request (NiceAgent *agent, StunMessa d->component->id, &niceaddr, NICE_CANDIDATE_TRANSPORT_UDP, - d->nicesock); + d->nicesock, + FALSE); d->stun_message.buffer = NULL; d->stun_message.buffer_len = 0; @@ -2473,7 +2474,8 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage * d->component->id, &niceaddr, NICE_CANDIDATE_TRANSPORT_UDP, - d->nicesock); + d->nicesock, + FALSE); } nice_address_set_from_sockaddr (&niceaddr, &relayaddr.addr); diff --git a/agent/discovery.c b/agent/discovery.c index 3aeeccc..f63d3dc 100644 --- a/agent/discovery.c +++ b/agent/discovery.c @@ -486,7 +486,8 @@ NiceCandidate *discovery_add_local_host_candidate ( agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else { - candidate->priority = nice_candidate_ice_priority (candidate); + candidate->priority = nice_candidate_ice_priority (candidate, + agent->reliable, FALSE); } priv_generate_candidate_credentials (agent, candidate); @@ -534,7 +535,8 @@ discovery_add_server_reflexive_candidate ( guint component_id, NiceAddress *address, NiceCandidateTransport transport, - NiceSocket *base_socket) + NiceSocket *base_socket, + gboolean nat_assisted) { NiceCandidate *candidate; Component *component; @@ -556,7 +558,8 @@ discovery_add_server_reflexive_candidate ( agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else { - candidate->priority = nice_candidate_ice_priority (candidate); + candidate->priority = nice_candidate_ice_priority (candidate, + agent->reliable, nat_assisted); } /* step: link to the base candidate+socket */ @@ -616,7 +619,8 @@ discovery_add_relay_candidate ( agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else { - candidate->priority = nice_candidate_ice_priority (candidate); + candidate->priority = nice_candidate_ice_priority (candidate, + agent->reliable, FALSE); } /* step: link to the base candidate+socket */ @@ -692,7 +696,8 @@ discovery_add_peer_reflexive_candidate ( agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else { - candidate->priority = nice_candidate_ice_priority (candidate); + candidate->priority = nice_candidate_ice_priority (candidate, + agent->reliable, FALSE); } priv_assign_foundation (agent, candidate); @@ -785,7 +790,8 @@ NiceCandidate *discovery_learn_remote_peer_reflexive_candidate ( agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else { - candidate->priority = nice_candidate_ice_priority (candidate); + candidate->priority = nice_candidate_ice_priority (candidate, + agent->reliable, FALSE); } priv_assign_remote_foundation (agent, candidate); diff --git a/agent/discovery.h b/agent/discovery.h index 6befb54..5afed71 100644 --- a/agent/discovery.h +++ b/agent/discovery.h @@ -117,7 +117,8 @@ discovery_add_server_reflexive_candidate ( guint component_id, NiceAddress *address, NiceCandidateTransport transport, - NiceSocket *base_socket); + NiceSocket *base_socket, + gboolean nat_assisted); NiceCandidate* discovery_add_peer_reflexive_candidate ( diff --git a/tests/test-priority.c b/tests/test-priority.c index 72f1277..7a52c3c 100644 --- a/tests/test-priority.c +++ b/tests/test-priority.c @@ -47,7 +47,9 @@ main (void) /* test 1 */ candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST); - g_assert (nice_candidate_ice_priority (candidate) == 0x78000200); + candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; + candidate->component_id = 1; + g_assert (nice_candidate_ice_priority (candidate, FALSE, FALSE) == 0x780001FF); g_assert (nice_candidate_jingle_priority (candidate) == 1000); nice_candidate_free (candidate); -- 2.7.4