summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYouness Alaoui <kakaroto@kakaroto.homelinux.net>2017-11-27 17:07:02 -0500
committerYouness Alaoui <kakaroto@kakaroto.homelinux.net>2017-11-28 16:45:37 -0500
commit59fcf95d505c3995f858b826d10cd48321ed383e (patch)
tree7d73526cd1f8e71891dd67d60359bb68c97d8c06
parent17f30e4465efe9533799b02d6f95feeaf0f2748c (diff)
downloadlibnice-59fcf95d505c3995f858b826d10cd48321ed383e.tar.gz
turn: Add support for ALTERNATE_SERVER in OC2007 Compatibility
The MS Office TURN servers will always return the MS_ALTERNATE_SERVER in allocation responses, and if they are not handled, we end up using the main turn server to send allocation requests that then get sent to the alternate server which will return the XOR_MAPPED_ADDRESS containing the IP address of the turn server that proxied the message instead of our own actual external IP.
-rw-r--r--agent/conncheck.c14
-rw-r--r--stun/usages/turn.c11
-rw-r--r--stun/usages/turn.h4
3 files changed, 29 insertions, 0 deletions
diff --git a/agent/conncheck.c b/agent/conncheck.c
index beb43c3..229c8b1 100644
--- a/agent/conncheck.c
+++ b/agent/conncheck.c
@@ -3764,6 +3764,20 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage *
recv_realm = (uint8_t *) stun_message_find (resp,
STUN_ATTRIBUTE_REALM, &recv_realm_len);
+ if ((agent->compatibility == NICE_COMPATIBILITY_OC2007 ||
+ agent->compatibility == NICE_COMPATIBILITY_OC2007R2) &&
+ alternatelen != sizeof(alternate)) {
+ NiceAddress alternate_addr;
+
+ nice_address_set_from_sockaddr (&alternate_addr, &alternate.addr);
+
+ if (!nice_address_equal (&alternate_addr, &d->server)) {
+ nice_address_set_from_sockaddr (&d->server, &alternate.addr);
+ nice_address_set_from_sockaddr (&d->turn->server, &alternate.addr);
+
+ d->pending = FALSE;
+ }
+ }
/* check for unauthorized error response */
if ((agent->compatibility == NICE_COMPATIBILITY_RFC5245 ||
agent->compatibility == NICE_COMPATIBILITY_OC2007 ||
diff --git a/stun/usages/turn.c b/stun/usages/turn.c
index 3b94959..ec12642 100644
--- a/stun/usages/turn.c
+++ b/stun/usages/turn.c
@@ -300,6 +300,17 @@ StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg,
stun_debug (" STUN error message received (code: %d)", code);
/* ALTERNATE-SERVER mechanism */
+ if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_OC2007 &&
+ alternate_server && alternate_server_len &&
+ stun_message_find_addr (msg, STUN_ATTRIBUTE_MS_ALTERNATE_SERVER,
+ alternate_server,
+ alternate_server_len) == STUN_MESSAGE_RETURN_SUCCESS) {
+ stun_debug ("Found alternate server");
+ /* The ALTERNATE_SERVER will always be returned by the MS turn server.
+ * We need to check if the ALTERNATE_SERVER is the same as the current
+ * server to decide whether we need to switch servers or not.
+ */
+ }
if ((code / 100) == 3) {
if (alternate_server && alternate_server_len) {
if (stun_message_find_addr (msg, STUN_ATTRIBUTE_ALTERNATE_SERVER,
diff --git a/stun/usages/turn.h b/stun/usages/turn.h
index 7a2d4e6..83fa00a 100644
--- a/stun/usages/turn.h
+++ b/stun/usages/turn.h
@@ -256,6 +256,10 @@ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg,
* Allocate request, in case the currently used TURN server is requesting the use
* of an alternate server. This argument will only be filled if the return value
* of the function is #STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER
+ * In the case of @STUN_USAGE_TURN_COMPATIBILITY_OC2007 compatibility, the
+ * @alternate_server could be filled at any time, and should only be considered
+ * if the request was sent to a different server than the address returned
+ * in the @alternate_server field
* @alternate_server_len: The length of @alternate_server
* @bandwidth: A pointer to fill with the bandwidth the TURN server allocated us
* @lifetime: A pointer to fill with the lifetime of the allocation