From ae3def254743947a8849a5e7edaac0ebf0b062b0 Mon Sep 17 00:00:00 2001 From: "David M. Lee" Date: Wed, 2 Dec 2015 17:32:36 -0600 Subject: [PATCH] Learn peer reflexive candidates from all STUN reqs This patch allows ice4j to learn peer reflexive candidates from all STUN requests, even if it will respond with a 487 Role Conflict. This allows peer reflexive candidates to be learned sooner, instead of waiting for conflict resolution to finish before learning the candidate. This is necessary for interop with buggy peers that do not switch roles when they receives the Role Conflict error. Chrome 46.0.2490.86 (current version) appears to have this problem, which this patch alleviates. I've looked at the relevant section of the spec (RFC 5244 section 7.2.1), and it appears that this behavior is not prohibited. --- .../ice4j/ice/ConnectivityCheckServer.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/ice4j/ice/ConnectivityCheckServer.java b/src/main/java/org/ice4j/ice/ConnectivityCheckServer.java index fdcaa59e..8d3fa713 100644 --- a/src/main/java/org/ice4j/ice/ConnectivityCheckServer.java +++ b/src/main/java/org/ice4j/ice/ConnectivityCheckServer.java @@ -150,16 +150,10 @@ public void processRequest(StunMessageEvent evt) return; } - //detect role conflicts - if( ( parentAgent.isControlling() - && request.containsAttribute(Attribute.ICE_CONTROLLING)) - || ( ! parentAgent.isControlling() - && request.containsAttribute(Attribute.ICE_CONTROLLED))) - { - if (!repairRoleConflict(evt)) - return; - } - + // Learn the peer reflexive candidate, even if we are going to send a + // role conflict error. This allows us to learn faster, and compensates + // for a buggy peer that doesn't switch roles when it gets a role + // conflict error. long priority = 0; boolean useCandidate = request.containsAttribute(Attribute.USE_CANDIDATE); @@ -177,6 +171,16 @@ public void processRequest(StunMessageEvent evt) evt.getLocalAddress(), priority, remoteUfrag, localUFrag, useCandidate); + //detect role conflicts + if( ( parentAgent.isControlling() + && request.containsAttribute(Attribute.ICE_CONTROLLING)) + || ( ! parentAgent.isControlling() + && request.containsAttribute(Attribute.ICE_CONTROLLED))) + { + if (!repairRoleConflict(evt)) + return; + } + Response response = MessageFactory.createBindingResponse( request, evt.getRemoteAddress());