[tor-commits] [pluggable-transports/snowflake-webext] branch main updated: fix: send SDP answer if ICE gathering is taking long to complete

gitolite role git at cupani.torproject.org
Tue Nov 8 21:39:44 UTC 2022


This is an automated email from the git hooks/post-receive script.

cohosh pushed a commit to branch main
in repository pluggable-transports/snowflake-webext.

The following commit(s) were added to refs/heads/main by this push:
     new 874e4ac  fix: send SDP answer if ICE gathering is taking long to complete
874e4ac is described below

commit 874e4acebf89d498db2de2e4dd6883625e0d51a6
Author: WofWca <wofwca at protonmail.com>
AuthorDate: Mon Nov 7 19:49:10 2022 +0400

    fix: send SDP answer if ICE gathering is taking long to complete
    
    Fixes #68
---
 config.js              |  6 ++++++
 proxypair.js           | 42 +++++++++++++++++++++++++++++++++++-------
 spec/proxypair.spec.js |  4 ++++
 3 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/config.js b/config.js
index 8f42176..2fc8c05 100644
--- a/config.js
+++ b/config.js
@@ -38,6 +38,12 @@ Config.prototype.datachannelTimeout = 20 * 1000;
 // Timeout to close proxypair if no messages are sent
 Config.prototype.messageTimeout = 30 * 1000;
 
+// This must be smaller than the clien't timeout (`ClientTimeout`)
+// (which is 10 seconds by default as of now), otherwise the client would be
+// gone before we send the answer.
+// And it, obviously, must be smaller than `datachannelTimeout`.
+Config.prototype.answerTimeout = 6 * 1000;
+
 Config.prototype.maxNumClients = 1;
 
 Config.prototype.proxyType = "";
diff --git a/proxypair.js b/proxypair.js
index 716aa7a..f0adba6 100644
--- a/proxypair.js
+++ b/proxypair.js
@@ -39,13 +39,6 @@ class ProxyPair {
   /** Prepare a WebRTC PeerConnection and await for an SDP offer. */
   begin() {
     this.pc = new RTCPeerConnection(this.pcConfig);
-    this.pc.onicecandidate = (evt) => {
-      // Browser sends a null candidate once the ICE gathering completes.
-      if (null === evt.candidate && this.pc.connectionState !== 'closed') {
-        dbg('Finished gathering ICE candidates.');
-        snowflake.broker.sendAnswer(this.id, this.pc.localDescription);
-      }
-    };
     // OnDataChannel triggered remotely from the client when connection succeeds.
     this.pc.ondatachannel = (dc) => {
       const channel = dc.channel;
@@ -71,6 +64,39 @@ class ProxyPair {
       return false;
     }
     dbg('SDP ' + offer.type + ' successfully received.');
+
+    // Send the answer when ready.
+    const onceSendAnswer = () => {
+      snowflake.broker.sendAnswer(this.id, this.pc.localDescription);
+
+      this.pc.onicecandidate = null;
+      clearTimeout(this.answerTimeoutId);
+    };
+    this.pc.onicecandidate = (evt) => {
+      // Browser sends a null candidate once the ICE gathering completes.
+      if (null === evt.candidate && this.pc.connectionState !== 'closed') {
+        dbg('Finished gathering ICE candidates.');
+        onceSendAnswer();
+      }
+    };
+    if (this.pc.iceGatheringState === 'complete') {
+      // This probably never happens as we've `setRemoteDescription` just now,
+      // but let's play it safe.
+      onceSendAnswer();
+    } else {
+      this.answerTimeoutId = setTimeout(() => {
+        dbg('answerTimeout');
+        // ICE gathering is taking a while to complete - send what we got so far.
+        if (!this.pc.localDescription) {
+          // We don't have anything to send yet. Sigh. The client will probably timeout waiting
+          // for us, but let's not bail and just try to wait some more in hope that it won't.
+          // Worst case scenario - `datachannelTimeout` callback will run.
+          return;
+        }
+        onceSendAnswer();
+      }, this.config.answerTimeout);
+    }
+
     return true;
   }
 
@@ -196,6 +222,7 @@ class ProxyPair {
   close() {
     clearTimeout(this.connectToRelayTimeoutId);
     clearTimeout(this.messageTimer);
+    clearTimeout(this.answerTimeoutId);
     if (this.webrtcIsReady()) {
       this.client.close();
     }
@@ -274,6 +301,7 @@ ProxyPair.prototype.relay = null; // websocket
 
 ProxyPair.prototype.connectToRelayTimeoutId = 0;
 ProxyPair.prototype.messageTimer = 0;
+ProxyPair.prototype.answerTimeoutId = 0;
 ProxyPair.prototype.flush_timeout_id = null;
 
 ProxyPair.prototype.onCleanup = null;
diff --git a/spec/proxypair.spec.js b/spec/proxypair.spec.js
index 992b4c1..8e0b330 100644
--- a/spec/proxypair.spec.js
+++ b/spec/proxypair.spec.js
@@ -80,6 +80,10 @@ describe('ProxyPair', function() {
 
   it('responds with a WebRTC answer correctly', function() {
     spyOn(snowflake.broker, 'sendAnswer');
+    pp.receiveWebRTCOffer({
+      type: 'offer',
+      sdp: 'foo'
+    });
     pp.pc.onicecandidate({
       candidate: null
     });

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list