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 e0f00904 authored by Cecylia Bocovich's avatar Cecylia Bocovich

Only extract remote address from peer SDP

We need to extract the remote address of the client to pass along to the
bridge. This adds an extra check to see whether the retrieved address is
a remote address (as opposed to local, loopback, or unspecified). It
also expands the SDP regexes to check for addresses in the ice
candidates.

This fixes issue #16
parent 14db9a23
Pipeline #1203 passed with stage
in 5 minutes and 38 seconds
......@@ -136,6 +136,15 @@ describe('Parse', function() {
sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 224.2.17.12/127\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
expected: '224.2.17.12'
},
{
// local addresses only
sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 10.47.16.5\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
expected: void 0
},
{
sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 10.47.16.5\na=candidate:3581707038 1 udp 2122260223 192.168.0.1 54653 typ host generation 0 network-id 1 network-cost 50\na=candidate:2617212910 1 tcp 1518280447 192.168.0.1 59673 typ host tcptype passive generation 0 network-id 1 network-cost 50\na=candidate:2082671819 1 udp 1686052607 1.2.3.4 54653 typ srflx raddr 192.168.0.1 rport 54653 generation 0 network-id 1 network-cost 50\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
expected: '1.2.3.4'
},
{
// Missing c= line
sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
......@@ -235,6 +244,111 @@ describe('Parse', function() {
}
});
});
describe('isRemoteIP', function() {
var testCases = [
{
ip: "127.0.0.1",
expected: false
},
{
ip: "::1",
expected: false
},
{
ip: "0::1",
expected: false
},
{
ip: "192.168.1.1",
expected: false
},
{
ip: "10.0.0.0",
expected: false
},
{
ip: "172.16.1.1",
expected: false
},
{
ip: "172.15.1.1",
expected: true
},
{
ip: "100.63.1.1",
expected: true
},
{
ip: "100.64.1.1",
expected: false
},
{
ip: "100.127.255.255",
expected: false
},
{
ip: "100.128.0.0",
expected: true
},
{
ip: "169.254.0.0",
expected: false
},
{
ip: "169.244.0.1",
expected: true
},
{
ip: "fc00::",
expected: false
},
{
ip: "fdff::0",
expected: false
},
{
ip: "ff00::0",
expected: true
},
{
ip: "0.0.0.0",
expected: false
},
{
ip: "::",
expected: false
},
{
ip: "::0",
expected: false
},
{
ip: "0::0",
expected: false
},
{
ip: "0::",
expected: false
},
{
ip: "ff15::101",
expected: true
},
{
ip: "1.2.3.4",
expected: true
}
];
it('finds local addresses', function() {
var i, len, ref, ref1, results, test;
results = [];
for (i = 0, len = testCases.length; i < len; i++) {
test = testCases[i];
expect(Parse.isRemoteIP(test.ip)).toEqual(test.expected);
}
});
});
});
describe('Params', function() {
......
......@@ -133,17 +133,26 @@ class Parse {
return count * multiplier;
}
// Parse a connection-address out of the "c=" Connection Data field of a
// session description. Return undefined if none is found.
//Parse a remote connection-address out of the "c=" Connection Data field
// or the "a=" attribute fields of the session description.
// Return undefined if none is found.
// https://tools.ietf.org/html/rfc4566#section-5.7
// https://tools.ietf.org/html/rfc5245#section-15
static ipFromSDP(sdp) {
var i, len, m, pattern, ref;
ref = [/^c=IN IP4 ([\d.]+)(?:(?:\/\d+)?\/\d+)?(:? |$)/m, /^c=IN IP6 ([0-9A-Fa-f:.]+)(?:\/\d+)?(:? |$)/m];
console.log(sdp);
ref = [
/^a=candidate:[a-zA-Z0-9+/]+ \d+ udp \d+ ([\d.]+) /mg,
/^a=candidate:[a-zA-Z0-9+/]+ \d+ udp \d+ ([0-9A-Fa-f:.]+) /mg,
/^c=IN IP4 ([\d.]+)(?:(?:\/\d+)?\/\d+)?(:? |$)/mg,
/^c=IN IP6 ([0-9A-Fa-f:.]+)(?:\/\d+)?(:? |$)/mg
];
for (i = 0, len = ref.length; i < len; i++) {
pattern = ref[i];
m = pattern.exec(sdp);
if (m != null) {
return m[1];
while (m != null) {
if(Parse.isRemoteIP(m[1])) return m[1];
m = pattern.exec(sdp);
}
}
}
......@@ -160,6 +169,30 @@ class Parse {
return null;
}
// Determine whether an IP address is a local, unspecified, or loopback address
static isRemoteIP(ip) {
if (ip.includes(":")) {
var ip6 = ip.split(':');
// Loopback address
var loopback = /^(?:0*:)*?:?0*1$/m;
// Unspecified address
var 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('.');
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) ||
// Carrier-Grade NAT as per https://tools.ietf.org/htm/rfc6598
(ip4[0] == 100 && (ip4[1]&0xc0) == 64) ||
// Dynamic Configuration as per https://tools.ietf.org/htm/rfc3927
(ip4[0] == 169 && ip4[1] == 254));
}
}
......
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