This is an automated email from the git hooks/post-receive script.
meskio pushed a change to branch main in repository pluggable-transports/snowflake-webext.
from 27c95cf too many mentions of Snowflake in this paragraph. new c5e810e refactor: replace some `var` with `const` new 4b56f7a refactor: add some more JSDoc
The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference.
Summary of changes: broker.js | 16 +++++++++++----- init-badge.js | 27 ++++++++++++++++++++++++++- init-testing.js | 20 +++++++++++++++++++- init-webext.js | 26 +++++++++++++++++++++++++- proxypair.js | 29 +++++++++++++++++++++++++---- snowflake.js | 17 +++++++++++++++-- util.js | 22 ++++++++++++++-------- websocket.js | 14 ++++++-------- 8 files changed, 141 insertions(+), 30 deletions(-)
This is an automated email from the git hooks/post-receive script.
meskio pushed a commit to branch main in repository pluggable-transports/snowflake-webext.
commit c5e810efb96c72511cbcf4983a81b89d861741c4 Author: WofWca wofwca@protonmail.com AuthorDate: Wed Jul 13 14:14:31 2022 +0300
refactor: replace some `var` with `const`
Follow-up to 31deee3 --- broker.js | 9 +++++---- proxypair.js | 2 +- snowflake.js | 2 +- util.js | 15 ++++++++------- websocket.js | 10 ++++------ 5 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/broker.js b/broker.js index 2431630..36ca3f8 100644 --- a/broker.js +++ b/broker.js @@ -51,8 +51,8 @@ class Broker { return; } switch (xhr.status) { - case Broker.CODE.OK: - var response = JSON.parse(xhr.responseText); + case Broker.CODE.OK: { + const response = JSON.parse(xhr.responseText); if (response.Status == Broker.STATUS.MATCH) { return fulfill(response); // Should contain offer. } else if (response.Status == Broker.STATUS.TIMEOUT) { @@ -61,6 +61,7 @@ class Broker { log('Broker ERROR: Unexpected ' + response.Status); return reject(Broker.MESSAGE.UNEXPECTED); } + } default: log('Broker ERROR: Unexpected ' + xhr.status + ' - ' + xhr.statusText); snowflake.ui.setStatus(' failure. Please refresh.'); @@ -69,7 +70,7 @@ class Broker { }; this._xhr = xhr; // Used by spec to fake async Broker interaction const clients = Math.floor(numClientsConnected / 8) * 8; - var data = { + const data = { Version: "1.3", Sid: id, Type: this.config.proxyType, @@ -104,7 +105,7 @@ class Broker { break; } }; - var data = {"Version": "1.0", "Sid": id, "Answer": JSON.stringify(answer)}; + const data = {"Version": "1.0", "Sid": id, "Answer": JSON.stringify(answer)}; this._postRequest(xhr, 'answer', JSON.stringify(data)); }
diff --git a/proxypair.js b/proxypair.js index 94d792a..a5b7823 100644 --- a/proxypair.js +++ b/proxypair.js @@ -111,7 +111,7 @@ class ProxyPair { if (peer_ip != null) { params.push(["client_ip", peer_ip]); } - var relay = this.relay = + const relay = this.relay = (this.relayURL === undefined) ? WS.makeWebsocket(this.relayAddr, params) : WS.makeWebsocketFromURL(this.relayURL, params); diff --git a/snowflake.js b/snowflake.js index bfa89c0..19d8992 100644 --- a/snowflake.js +++ b/snowflake.js @@ -76,7 +76,7 @@ class Snowflake { this.broker.setNATType(this.ui.natType); const recv = this.broker.getClientOffer(pair.id, this.proxyPairs.length); recv.then((resp) => { - var clientNAT = resp.NAT; + const clientNAT = resp.NAT; if (!this.receiveOffer(pair, resp.Offer, resp.RelayURL)) { pair.close(); return; diff --git a/util.js b/util.js index 58d6512..73d67be 100644 --- a/util.js +++ b/util.js @@ -80,15 +80,16 @@ class Util { return; } switch (xhr.status) { - case 200: - var response = JSON.parse(xhr.responseText); + case 200: { + const response = JSON.parse(xhr.responseText); return fulfill(response.Answer); // Should contain offer. + } default: console.log('Probe ERROR: Unexpected ' + xhr.status + ' - ' + xhr.statusText); return reject('Failed to get answer from probe service'); } }; - var data = {"Status": "client match", "Offer": JSON.stringify(offer)}; + const data = {"Status": "client match", "Offer": JSON.stringify(offer)}; try { xhr.open('POST', Config.PROBEURL); } catch (error) { @@ -223,18 +224,18 @@ class Parse { /** Determine whether an IP address is a local, unspecified, or loopback address */ static isRemoteIP(ip) { if (ip.includes(":")) { - var ip6 = ip.split(':'); + const ip6 = ip.split(':'); // Loopback address - var loopback = /^(?:0*:)*?:?0*1$/m; + const loopback = /^(?:0*:)*?:?0*1$/m; // Unspecified address - var unspecified = /^(?:0*:)*?:?0*$/m; + const unspecified = /^(?:0*:)*?:?0*$/m; // Local IPv6 addresses are defined in https://tools.ietf.org/html/rfc4193 return !((loopback.exec(ip) != null) || (unspecified.exec(ip) != null) || (parseInt(ip6[0],16)&0xfe00) == 0xfc00); }
// Local IPv4 addresses are defined in https://tools.ietf.org/html/rfc1918 - var ip4 = ip.split('.'); + const ip4 = ip.split('.'); return !(ip4[0] == 10 || ip4[0] == 127 || ip == "0.0.0.0" || (ip4[0] == 172 && (ip4[1]&0xf0) == 16) || (ip4[0] == 192 && ip4[1] == 168) || diff --git a/websocket.js b/websocket.js index 7164577..4a27ef4 100644 --- a/websocket.js +++ b/websocket.js @@ -9,8 +9,7 @@ class WS { * are required. See RFC 3986, section 3. */ static buildUrl(scheme, host, port, path, params) { - var parts; - parts = []; + const parts = []; parts.push(encodeURIComponent(scheme)); parts.push('://'); // If it contains a colon but no square brackets, treat it as IPv6. @@ -42,10 +41,9 @@ class WS { }
static makeWebsocket(addr, params) { - var url, ws, wsProtocol; - wsProtocol = this.WSS_ENABLED ? 'wss' : 'ws'; - url = this.buildUrl(wsProtocol, addr.host, addr.port, '/', params); - ws = new WebSocket(url); + const wsProtocol = this.WSS_ENABLED ? 'wss' : 'ws'; + const url = this.buildUrl(wsProtocol, addr.host, addr.port, '/', params); + const ws = new WebSocket(url); /* 'User agents can use this as a hint for how to handle incoming binary data: if the attribute is set to 'blob', it is safe to spool it to disk, and if it
This is an automated email from the git hooks/post-receive script.
meskio pushed a commit to branch main in repository pluggable-transports/snowflake-webext.
commit 4b56f7a350ef78ac2f8888cdd15d529dada30f72 Author: WofWca wofwca@protonmail.com AuthorDate: Wed Jul 13 15:34:22 2022 +0300
refactor: add some more JSDoc --- broker.js | 7 ++++++- init-badge.js | 27 ++++++++++++++++++++++++++- init-testing.js | 20 +++++++++++++++++++- init-webext.js | 26 +++++++++++++++++++++++++- proxypair.js | 27 ++++++++++++++++++++++++--- snowflake.js | 15 ++++++++++++++- util.js | 7 ++++++- websocket.js | 4 ++-- 8 files changed, 122 insertions(+), 11 deletions(-)
diff --git a/broker.js b/broker.js index 36ca3f8..761efcf 100644 --- a/broker.js +++ b/broker.js @@ -15,6 +15,7 @@ class Broker { * ID so the Broker can keep track of each proxy's signalling channels. * On construction, this Broker object does not do anything until * `getClientOffer` is called. + * @param {Config} config */ constructor(config) { this.getClientOffer = this.getClientOffer.bind(this); @@ -85,6 +86,8 @@ class Broker { /** * Assumes getClientOffer happened, and a WebRTC SDP answer has been generated. * Sends it back to the broker, which passes it to back to the original client. + * @param {string} id + * @param {RTCSessionDescription} answer */ sendAnswer(id, answer) { dbg(id + ' - Sending answer back to broker...\n'); @@ -114,8 +117,10 @@ class Broker { }
/** - * urlSuffix for the broker is different depending on what action + * @param {XMLHttpRequest} xhr + * @param {string} urlSuffix for the broker is different depending on what action * is desired. + * @param {string} payload */ _postRequest(xhr, urlSuffix, payload) { try { diff --git a/init-badge.js b/init-badge.js index ec62b5d..a4305a2 100644 --- a/init-badge.js +++ b/init-badge.js @@ -122,7 +122,32 @@ function getLang() { return defaultLang; }
-var debug, snowflake, config, broker, ui, log, dbg, init, update, silenceNotifications, query, tryProbe; +/** @typedef {BadgeUI} UIOfThisContext */ +var + /** @type {boolean} */ + debug, + /** @type {Snowflake | null} */ + snowflake, + /** @type {Config | null} */ + config, + /** @type {Broker | null} */ + broker, + /** @type {UIOfThisContext | null} */ + ui, + /** @type {(msg: unknown) => void} */ + log, + /** @type {(msg: unknown) => void} */ + dbg, + /** @type {() => void} */ + init, + /** @type {() => void} */ + update, + /** @type {boolean} */ + silenceNotifications, + /** @type {URLSearchParams} */ + query, + /** @type {() => void} */ + tryProbe;
(function() {
diff --git a/init-testing.js b/init-testing.js index 6bc86ef..8333065 100644 --- a/init-testing.js +++ b/init-testing.js @@ -50,7 +50,25 @@ DebugUI.prototype.$status = null; Entry point. */
-var snowflake, query, debug, ui, silenceNotifications, log, dbg, init; +/** @typedef {DebugUI | UI} UIOfThisContext */ +var + /** @type {boolean} */ + debug, + /** @type {Snowflake | null} */ + snowflake, + /** @type {URLSearchParams} */ + query, + /** @type {UIOfThisContext} */ + ui, + /** @type {(msg: unknown) => void} */ + log, + /** @type {(msg: unknown) => void} */ + dbg, + /** @type {() => void} */ + init, + /** @type {boolean} */ + silenceNotifications; +
(function() {
diff --git a/init-webext.js b/init-webext.js index 0bba740..cde7d5f 100644 --- a/init-webext.js +++ b/init-webext.js @@ -109,6 +109,9 @@ class WebExtUI extends UI { this.port = null; }
+ /** + * @param {boolean} enabled + */ setEnabled(enabled) { this.enabled = enabled; this.postActive(); @@ -148,7 +151,28 @@ WebExtUI.prototype.enabled = true; Entry point. */
-var debug, snowflake, config, broker, ui, log, dbg, init, update, silenceNotifications; +/** @typedef {WebExtUI} UIOfThisContext */ +var + /** @type {boolean} */ + debug, + /** @type {Snowflake | null} */ + snowflake, + /** @type {Config | null} */ + config, + /** @type {Broker | null} */ + broker, + /** @type {UIOfThisContext | null} */ + ui, + /** @type {(msg: unknown) => void} */ + log, + /** @type {(msg: unknown) => void} */ + dbg, + /** @type {() => void} */ + init, + /** @type {() => void} */ + update, + /** @type {boolean} */ + silenceNotifications;
(function () {
diff --git a/proxypair.js b/proxypair.js index a5b7823..41e6291 100644 --- a/proxypair.js +++ b/proxypair.js @@ -14,6 +14,7 @@ class ProxyPair { /** * @param relayAddr the destination relay * @param {*} rateLimit specifies a rate limit on traffic + * @param {Config} config */ constructor(relayAddr, rateLimit, config) { this.prepareDataChannel = this.prepareDataChannel.bind(this); @@ -23,6 +24,7 @@ class ProxyPair { this.onError = this.onError.bind(this); this.flush = this.flush.bind(this);
+ /** @type {string | undefined} */ this.relayURL = undefined; this.relayAddr = relayAddr; this.rateLimit = rateLimit; @@ -53,6 +55,10 @@ class ProxyPair { }; }
+ /** + * @param {RTCSessionDescription} offer + * @returns {boolean} `true` on success, `false` on fail. + */ receiveWebRTCOffer(offer) { if ('offer' !== offer.type) { log('Invalid SDP received -- was not an offer.'); @@ -68,7 +74,10 @@ class ProxyPair { return true; }
- /** Given a WebRTC DataChannel, prepare callbacks. */ + /** + * Given a WebRTC DataChannel, prepare callbacks. + * @param {RTCDataChannel} channel + */ prepareDataChannel(channel) { channel.onopen = () => { log('WebRTC DataChannel opened!'); @@ -146,7 +155,10 @@ class ProxyPair { }), 5000); }
- /** WebRTC --> websocket */ + /** + * WebRTC --> websocket + * @param {MessageEvent} msg + */ onClientToRelayMessage(msg) { if (this.messageTimer) { clearTimeout(this.messageTimer); @@ -164,7 +176,10 @@ class ProxyPair { this.flush(); }
- /** websocket --> WebRTC */ + /** + * websocket --> WebRTC + * @param {MessageEvent} event + */ onRelayToClientMessage(event) { dbg('websocket --> WebRTC data: ' + event.data.byteLength + ' bytes'); this.r2cSchedule.push(event.data); @@ -239,6 +254,9 @@ class ProxyPair { return (null !== this.relay) && (WebSocket.OPEN === this.relay.readyState); }
+ /** + * @param {WebSocket} ws + */ isClosed(ws) { return undefined === ws || WebSocket.CLOSED === ws.readyState; } @@ -247,6 +265,9 @@ class ProxyPair { return (null !== this.pc) && ('closed' !== this.pc.connectionState); }
+ /** + * @param {typeof this.relayURL} relayURL + */ setRelayURL(relayURL) { this.relayURL = relayURL; } diff --git a/snowflake.js b/snowflake.js index 19d8992..b55a3bd 100644 --- a/snowflake.js +++ b/snowflake.js @@ -13,7 +13,12 @@ TODO: More documentation
class Snowflake {
- // Prepare the Snowflake with a Broker (to find clients) and optional UI. + /** + * Prepare the Snowflake with a Broker (to find clients) and optional UI. + * @param {Config} config + * @param {WebExtUI | BadgeUI | DebugUI} ui + * @param {Broker} broker + */ constructor(config, ui, broker) { this.receiveOffer = this.receiveOffer.bind(this);
@@ -36,6 +41,7 @@ class Snowflake { * Set the target relay address spec, which is expected to be websocket. * TODO: Should potentially fetch the target from broker later, or modify * entirely for the Tor-independent version. + * @param {{ host: string; port: string; }} relayAddr */ setRelayAddr(relayAddr) { this.relayAddr = relayAddr; @@ -119,6 +125,8 @@ class Snowflake { /** * Receive an SDP offer from some client assigned by the Broker * @param {ProxyPair} pair an available ProxyPair. + * @param {string} desc + * @param {string | undefined} relayURL * @returns {boolean} `true` on success, `false` on fail. */ receiveOffer(pair, desc, relayURL) { @@ -137,6 +145,7 @@ class Snowflake { } pair.setRelayURL(relayURL); } + /** @type {RTCSessionDescriptionInit} */ const offer = JSON.parse(desc); dbg('Received:\n\n' + offer.sdp + '\n'); const sdp = new RTCSessionDescription(offer); @@ -152,7 +161,11 @@ class Snowflake { } }
+ /** + * @param {ProxyPair} pair + */ sendAnswer(pair) { + /** @param {RTCLocalSessionDescriptionInit} sdp */ const next = function (sdp) { dbg('webrtc: Answer ready.'); pair.pc.setLocalDescription(sdp).catch(fail); diff --git a/util.js b/util.js index 73d67be..7c865e8 100644 --- a/util.js +++ b/util.js @@ -22,10 +22,12 @@ class Util { }
/** - * returns a promise that resolves to "restricted" if we + * @returns {Promise<"restricted" | "unrestricted">} + * resolves to "restricted" if we * fail to make a test connection to a known restricted * NAT, "unrestricted" if the test connection succeeds, and * "unknown" if we fail to reach the probe test server + * @param {number} timeout */ static checkNATType(timeout) { let pc = new RTCPeerConnection({iceServers: [ @@ -70,6 +72,7 @@ class Util { /** * Assumes getClientOffer happened, and a WebRTC SDP answer has been generated. * Sends it back to the broker, which passes it back to the original client. + * @param {RTCSessionDescription} offer */ static sendOffer(offer) { return new Promise((fulfill, reject) => { @@ -105,6 +108,7 @@ class Util { class Parse {
/** + * @param {typeof document.cookie} cookies * Parse a cookie data string (usually document.cookie). The return type is an * object mapping cookies names to values. Returns null on error. * http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-8747038 @@ -128,6 +132,7 @@ class Parse { }
/** + * @param {string} spec * Parse an address in the form 'host:port'. Returns an Object with keys 'host' * (String) and 'port' (int). Returns null on error. */ diff --git a/websocket.js b/websocket.js index 4a27ef4..ed236c3 100644 --- a/websocket.js +++ b/websocket.js @@ -79,7 +79,7 @@ class WS { }
static probeWebsocket(addr) { - return new Promise((resolve, reject) => { + return /** @type {Promise<void>} */(new Promise((resolve, reject) => { const ws = WS.makeWebsocket(addr); ws.onopen = () => { resolve(); @@ -89,7 +89,7 @@ class WS { reject(); ws.close(); }; - }); + })); }
}
tor-commits@lists.torproject.org