GitLab is used only for code review, issue tracking and project management. Canonical locations for source code are still https://gitweb.torproject.org/ https://git.torproject.org/ and git-rw.torproject.org.

Commit a2aa6acf authored by Cecylia Bocovich's avatar Cecylia Bocovich

Perform a test for symmetric NATs on startup

parent c2c3bdb2
Pipeline #826 passed with stage
in 42 seconds
......@@ -105,7 +105,7 @@ function getLang() {
return defaultLang;
}
var debug, snowflake, config, broker, ui, log, dbg, init, update, silenceNotifications, query, tryProbe;
var debug, snowflake, config, broker, ui, log, dbg, init, update, initNATType, silenceNotifications, query, tryProbe;
(function() {
......@@ -147,6 +147,18 @@ var debug, snowflake, config, broker, ui, log, dbg, init, update, silenceNotific
);
};
initNATType = function() {
this.natType = "unknown";
(function loop(_this) {
Util.checkNATType().then((type) => {
console.log("Setting NAT type: " + type);
_this.natType = type;
}).catch((e) => console.log(e));
// reset NAT type every 24 hours in case proxy location changed
setTimeout(_this.initNATType, 24 * 60 * 60 * 1000);
})(this);
};
update = function() {
const cookies = Parse.cookie(document.cookie);
if (cookies[COOKIE_NAME] !== '1') {
......@@ -181,6 +193,8 @@ var debug, snowflake, config, broker, ui, log, dbg, init, update, silenceNotific
snowflake = new Snowflake(config, ui, broker);
log('== snowflake proxy ==');
update();
initNATType();
};
// Notification of closing tab with active proxy.
......
......@@ -28,10 +28,14 @@ class WebExtUI extends UI {
initNATType() {
this.natType = "unknown";
// reset NAT type every 24 hours in case proxy location changed
setInterval((() => {
this.natType = "unknown";
}), 24 * 60 * 60 * 1000);
(function loop(_this) {
Util.checkNATType().then((type) => {
console.log("Setting NAT type: " + type);
_this.natType = type;
}).catch((e) => console.log(e));
// reset NAT type every 24 hours in case proxy location changed
setTimeout(_this.initNATType, 24 * 60 * 60 * 1000);
})(this);
}
tryProbe() {
......
......@@ -32,4 +32,4 @@
"ws": "^3.3.1",
"xmlhttprequest": "^1.8.0"
}
}
\ No newline at end of file
}
......@@ -210,7 +210,31 @@ describe('Parse', function() {
});
});
describe('portFromCandidate', function() {
var testCases = [
{
candidate: "candidate:0 1 UDP 2122252543 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa.local 54297 typ host",
expected: null
},
{
candidate: "candidate:1 1 UDP 1686052863 1.2.3.4 54297 typ srflx raddr 0.0.0.0 rport 0",
expected: "54297"
},
{
candidate: "candidate:1 1 UDP 1686052863 2a07:2e47:ffff:ffff:ffff:ffff:ffff:ffff 54297 typ srflx raddr 0.0.0.0 rport 0",
expected: "54297"
}
];
it('parses port', function() {
var i, len, ref, ref1, results, test;
results = [];
for (i = 0, len = testCases.length; i < len; i++) {
test = testCases[i];
expect(Parse.portFromCandidate(test.candidate)).toEqual(test.expected);
}
});
});
});
describe('Params', function() {
......
/* exported Util, Params, DummyRateLimit */
/* global PeerConnection */
/*
A JavaScript WebRTC snowflake proxy
......@@ -20,6 +21,35 @@ class Util {
return navigator.cookieEnabled;
}
// returns a promise that fullfills to "restricted" if the
// mapping is symmetric, and we know it's a restrictive NAT,
// and fullfills to "unknown" if the mapping is not
// symmetric.
static checkNATType() {
return new Promise((fulfill, reject) => {
let port = null;
let pc = new PeerConnection({iceServers: [
{urls: 'stun:stun1.l.google.com:19302'},
{urls: 'stun:stun2.l.google.com:19302'}
]});
pc.createDataChannel("NAT test");
pc.onicecandidate = function(e) {
if (e.candidate) {
let p = Parse.portFromCandidate(e.candidate.candidate);
if (port == null) port = p;
else if (p != null && p != port) fulfill("restricted");
} else { // done parsing candidates
fulfill("unknown");
}
};
pc.createOffer().then((offer) => {
pc.setLocalDescription(offer);
}).catch((e) => {
console.log(e);
reject("Error checking NAT type");
});
});
}
}
......@@ -118,6 +148,18 @@ class Parse {
}
}
// Parse the mapped port out of an ice candidate returned from the
// onicecandidate callback
static portFromCandidate(c) {
var m, pattern;
pattern = /(?:[\d.]+|[0-9A-Fa-f:.]+) (\d+) typ srflx/m;
m = pattern.exec(c);
if (m != null) {
return m[1];
}
return null;
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment