summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Skryabin <andrey.skryabin@nordigy.ru>2018-11-06 15:34:10 +0300
committerOlivier CrĂȘte <olivier.crete@collabora.com>2019-05-08 17:09:31 -0400
commit1faae8c83336eccb0fb3ddc7dd894bd36996d2fa (patch)
tree1744115a908a2b9dcf0d358bd2d3754ab9cbb7fa
parent62cbfbd552debcf477056dfadac52156b5ff6565 (diff)
downloadlibnice-1faae8c83336eccb0fb3ddc7dd894bd36996d2fa.tar.gz
conncheck: NOMINATION STUN attribute support
Attribute is proposed here: https://tools.ietf.org/html/draft-thatcher-ice-renomination-00 WebRTC supports this attribute: controlling side provides attribute value increased by one each time selected pair is changed: https://chromium.googlesource.com/external/webrtc/+/3c7d599750405bc734e1d5adbf1b54265b725a9d/p2p/base/p2ptransportchannel.cc#1821
-rw-r--r--agent/agent-priv.h1
-rw-r--r--agent/agent.c29
-rw-r--r--agent/agent.h3
-rw-r--r--agent/conncheck.c59
-rw-r--r--stun/stunmessage.h8
5 files changed, 98 insertions, 2 deletions
diff --git a/agent/agent-priv.h b/agent/agent-priv.h
index a38aa23..91f73a3 100644
--- a/agent/agent-priv.h
+++ b/agent/agent-priv.h
@@ -156,6 +156,7 @@ struct _NiceAgent
guint stun_initial_timeout; /* property: stun initial timeout, RTO */
guint stun_reliable_timeout; /* property: stun reliable timeout */
NiceNominationMode nomination_mode; /* property: Nomination mode */
+ gboolean support_renomination; /* property: support RENOMINATION STUN attribute */
GSList *local_addresses; /* list of NiceAddresses for local
interfaces */
diff --git a/agent/agent.c b/agent/agent.c
index 59028ce..86bf37a 100644
--- a/agent/agent.c
+++ b/agent/agent.c
@@ -119,6 +119,7 @@ enum
PROP_STUN_RELIABLE_TIMEOUT,
PROP_NOMINATION_MODE,
PROP_ICE_TRICKLE,
+ PROP_SUPPORT_RENOMINATION,
};
@@ -466,6 +467,24 @@ nice_agent_class_init (NiceAgentClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/**
+ * NiceAgent:support-renomination:
+ *
+ * Support RENOMINATION STUN attribute proposed here:
+ * https://tools.ietf.org/html/draft-thatcher-ice-renomination-00 As
+ * soon as RENOMINATION attribute is received from remote
+ * candidate's address, corresponding candidates pair gets
+ * selected. This is specific to Google Chrome/libWebRTC.
+ */
+ g_object_class_install_property (gobject_class, PROP_SUPPORT_RENOMINATION,
+ g_param_spec_boolean (
+ "support-renomination",
+ "Support RENOMINATION STUN attribute",
+ "As soon as RENOMINATION attribute is received from remote candidate's address, "
+ "corresponding candidates pair gets selected.",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
* NiceAgent:proxy-ip:
*
* The proxy server IP used to bypass a proxy firewall
@@ -1183,6 +1202,7 @@ nice_agent_init (NiceAgent *agent)
agent->saved_controlling_mode = TRUE;
agent->max_conn_checks = NICE_AGENT_MAX_CONNECTIVITY_CHECKS_DEFAULT;
agent->nomination_mode = NICE_NOMINATION_MODE_AGGRESSIVE;
+ agent->support_renomination = FALSE;
agent->discovery_list = NULL;
agent->discovery_unsched_items = 0;
@@ -1246,6 +1266,7 @@ nice_agent_new_full (GMainContext *ctx,
NICE_NOMINATION_MODE_REGULAR : NICE_NOMINATION_MODE_AGGRESSIVE,
"full-mode", (flags & NICE_AGENT_OPTION_LITE_MODE) ? FALSE : TRUE,
"ice-trickle", (flags & NICE_AGENT_OPTION_ICE_TRICKLE) ? TRUE : FALSE,
+ "support-renomination", (flags & NICE_AGENT_OPTION_SUPPORT_RENOMINATION) ? TRUE : FALSE,
NULL);
return agent;
@@ -1302,6 +1323,10 @@ nice_agent_get_property (
g_value_set_enum (value, agent->nomination_mode);
break;
+ case PROP_SUPPORT_RENOMINATION:
+ g_value_set_boolean (value, agent->support_renomination);
+ break;
+
case PROP_PROXY_IP:
g_value_set_string (value, agent->proxy_ip);
break;
@@ -1514,6 +1539,10 @@ nice_agent_set_property (
agent->nomination_mode = g_value_get_enum (value);
break;
+ case PROP_SUPPORT_RENOMINATION:
+ agent->support_renomination = g_value_get_boolean (value);
+ break;
+
case PROP_PROXY_IP:
g_free (agent->proxy_ip);
agent->proxy_ip = g_value_dup_string (value);
diff --git a/agent/agent.h b/agent/agent.h
index 2ad700c..688d784 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -405,6 +405,8 @@ typedef enum
* @NICE_AGENT_OPTION_RELIABLE: Enables reliable mode, possibly using PseudoTCP, * see nice_agent_new_reliable().
* @NICE_AGENT_OPTION_LITE_MODE: Enable lite mode
* @NICE_AGENT_OPTION_ICE_TRICKLE: Enable ICE trickle mode
+ * @NICE_AGENT_OPTION_SUPPORT_RENOMINATION: Enable renomination triggered by NOMINATION STUN attribute
+ * proposed here: https://tools.ietf.org/html/draft-thatcher-ice-renomination-00
*
* These are options that can be passed to nice_agent_new_full(). They set
* various properties on the agent. Not including them sets the property to
@@ -417,6 +419,7 @@ typedef enum {
NICE_AGENT_OPTION_RELIABLE = 1 << 1,
NICE_AGENT_OPTION_LITE_MODE = 1 << 2,
NICE_AGENT_OPTION_ICE_TRICKLE = 1 << 3,
+ NICE_AGENT_OPTION_SUPPORT_RENOMINATION = 1 << 4,
} NiceAgentOption;
/**
diff --git a/agent/conncheck.c b/agent/conncheck.c
index 06ba940..f8acfd6 100644
--- a/agent/conncheck.c
+++ b/agent/conncheck.c
@@ -3913,6 +3913,62 @@ static bool conncheck_stun_validater (StunAgent *agent,
return FALSE;
}
+/*
+ * handle RENOMINATION stun attribute
+ * @return TRUE if nomination changed. FALSE otherwise
+ */
+static gboolean conn_check_handle_renomination (NiceAgent *agent, NiceStream *stream,
+ NiceComponent *component, StunMessage *req,
+ NiceCandidate *remote_candidate, NiceCandidate *local_candidate)
+{
+ GSList *lst;
+ if (!agent->controlling_mode && NICE_AGENT_IS_COMPATIBLE_WITH_RFC5245_OR_OC2007R2 (agent) &&
+ agent->support_renomination && remote_candidate && local_candidate)
+ {
+ uint32_t nom_value = 0;
+ uint16_t nom_len = 0;
+ const void *value = stun_message_find (req, STUN_ATTRIBUTE_NOMINATION, &nom_len);
+ if (nom_len == 0) {
+ return FALSE;
+ }
+ if (nom_len == 4) {
+ memcpy (&nom_value, value, 4);
+ nom_value = ntohl (nom_value);
+ } else {
+ nice_debug ("Agent %p : received NOMINATION attr with incorrect octet length %u, expected 4 bytes",
+ agent, nom_len);
+ return FALSE;
+ }
+
+ if (nice_debug_is_enabled ()) {
+ gchar remote_str[INET6_ADDRSTRLEN];
+ nice_address_to_string(&remote_candidate->addr, remote_str);
+ nice_debug ("Agent %p : received NOMINATION attr for remote candidate [%s]:%u, value is %u",
+ agent, remote_str, nice_address_get_port (&remote_candidate->addr), nom_value);
+ }
+
+ /*
+ * If another pair is SELECTED, change this pair's priority to be greater than
+ * selected pair's priority so this pair gets SELECTED!
+ */
+ if (component->selected_pair.priority &&
+ component->selected_pair.remote && component->selected_pair.remote != remote_candidate &&
+ component->selected_pair.local && component->selected_pair.local != local_candidate) {
+ for (lst = stream->conncheck_list; lst; lst = lst->next) {
+ CandidateCheckPair *pair = lst->data;
+ if (pair->local == local_candidate && pair->remote == remote_candidate) {
+ if (pair->valid) {
+ pair->priority = component->selected_pair.priority + 1;
+ }
+ break;
+ }
+ }
+ }
+ priv_mark_pair_nominated (agent, stream, component, local_candidate, remote_candidate);
+ return TRUE;
+ }
+ return FALSE;
+}
/*
* Processing an incoming STUN message.
@@ -4278,6 +4334,9 @@ gboolean conn_check_handle_inbound_stun (NiceAgent *agent, NiceStream *stream,
"probably a keepalive.", agent);
}
+ /* RENOMINATION attribute support */
+ conn_check_handle_renomination(agent, stream, component, &req, local_candidate, remote_candidate);
+
return TRUE;
}
diff --git a/stun/stunmessage.h b/stun/stunmessage.h
index 26ee12d..0ac9977 100644
--- a/stun/stunmessage.h
+++ b/stun/stunmessage.h
@@ -230,6 +230,8 @@ typedef enum
* attribute as defined by [MS-ICE2]
* @STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION: The IMPLEMENTATION-VERSION
* optional attribute as defined by [MS-ICE2]
+ * @STUN_ATTRIBUTE_NOMINATION: The NOMINATION attribute as defined by
+ * draft-thatcher-ice-renomination-00 and deployed in Google Chrome
*
* Known STUN attribute types as defined by various RFCs and drafts
*/
@@ -309,8 +311,10 @@ typedef enum
/* 0x8051-0x8053 */ /* reserved */
STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER=0x8054, /* MS-ICE2 */
/* 0x8055-0x806F */ /* reserved */
- STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION=0x8070 /* MS-ICE2 */
- /* 0x8071-0xFFFF */ /* reserved */
+ STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION=0x8070, /* MS-ICE2 */
+ /* 0x8071-0xC000 */ /* reserved */
+ STUN_ATTRIBUTE_NOMINATION=0xC001 /* https://tools.ietf.org/html/draft-thatcher-ice-renomination-00 */
+ /* 0xC002-0xFFFF */ /* reserved */
} StunAttribute;