[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [snowflake/master] per-proxypair Snowflake ID generation instead of just one for the Broker (#11)
commit b1e76420bd7c3838d128407c9822b089c0296bc2
Author: Serene Han <keroserene+git@xxxxxxxxx>
Date: Mon Mar 14 22:12:28 2016 -0700
per-proxypair Snowflake ID generation instead of just one for the Broker (#11)
---
proxy/broker.coffee | 19 +++++++------------
proxy/proxypair.coffee | 8 ++++++--
proxy/snowflake.coffee | 30 ++++++++++++++++++++++++------
proxy/spec/broker.spec.coffee | 6 +++---
proxy/util.coffee | 4 ++++
5 files changed, 44 insertions(+), 23 deletions(-)
diff --git a/proxy/broker.coffee b/proxy/broker.coffee
index 78577e7..9eb378c 100644
--- a/proxy/broker.coffee
+++ b/proxy/broker.coffee
@@ -12,21 +12,16 @@ STATUS_GATEWAY_TIMEOUT = 504
MESSAGE_TIMEOUT = 'Timed out waiting for a client offer.'
MESSAGE_UNEXPECTED = 'Unexpected status.'
-genSnowflakeID = ->
- Math.random().toString(36).substring(2)
-
# Represents a broker running remotely.
class Broker
clients: 0
- id: null
# When interacting with the Broker, snowflake must generate a unique session
# ID so the Broker can keep track of which signalling channel it's speaking
# to.
constructor: (@url) ->
@clients = 0
- @id = genSnowflakeID()
# Ensure url has the right protocol + trailing slash.
@url = 'http://' + @url if 0 == @url.indexOf('localhost', 0)
@url = 'https://' + @url if 0 != @url.indexOf('http', 0)
@@ -37,7 +32,7 @@ class Broker
# waits for a response containing some client offer that the Broker chooses
# for this proxy..
# TODO: Actually support multiple clients.
- getClientOffer: =>
+ getClientOffer: (id) =>
new Promise (fulfill, reject) =>
xhr = new XMLHttpRequest()
xhr.onreadystatechange = ->
@@ -53,12 +48,12 @@ class Broker
snowflake.ui.setStatus ' failure. Please refresh.'
reject MESSAGE_UNEXPECTED
@_xhr = xhr # Used by spec to fake async Broker interaction
- @_postRequest xhr, 'proxy', @id
+ @_postRequest id, xhr, 'proxy', id
# 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.
- sendAnswer: (answer) ->
- dbg @id + ' - Sending answer back to broker...\n'
+ sendAnswer: (id, answer) ->
+ dbg id + ' - Sending answer back to broker...\n'
dbg answer.sdp
xhr = new XMLHttpRequest()
xhr.onreadystatechange = ->
@@ -73,14 +68,14 @@ class Broker
dbg 'Broker ERROR: Unexpected ' + xhr.status +
' - ' + xhr.statusText
snowflake.ui.setStatus ' failure. Please refresh.'
- @_postRequest xhr, 'answer', JSON.stringify(answer)
+ @_postRequest id, xhr, 'answer', JSON.stringify(answer)
# urlSuffix for the broker is different depending on what action
# is desired.
- _postRequest: (xhr, urlSuffix, payload) =>
+ _postRequest: (id, xhr, urlSuffix, payload) =>
try
xhr.open 'POST', @url + urlSuffix
- xhr.setRequestHeader('X-Session-ID', @id)
+ xhr.setRequestHeader('X-Session-ID', id)
catch err
###
An exception happens here when, for example, NoScript allows the domain
diff --git a/proxy/proxypair.coffee b/proxy/proxypair.coffee
index db53612..3a3fb01 100644
--- a/proxy/proxypair.coffee
+++ b/proxy/proxypair.coffee
@@ -3,6 +3,8 @@ Represents a single:
client <-- webrtc --> snowflake <-- websocket --> relay
+Every ProxyPair has a Snowflake ID, which is necessary when responding to the
+Broker with an WebRTC answer.
###
class ProxyPair
@@ -16,10 +18,12 @@ class ProxyPair
running: true
active: false # Whether serving a client.
flush_timeout_id: null
- onCleanup: null
+ onCleanup: null
+ id: null
constructor: (@clientAddr, @relayAddr, @rateLimit) ->
@active = false
+ @id = genSnowflakeID()
# Prepare a WebRTC PeerConnection and await for an SDP offer.
begin: ->
@@ -38,7 +42,7 @@ class ProxyPair
if COPY_PASTE_ENABLED
Signalling.send @pc.localDescription
else
- snowflake.broker.sendAnswer @pc.localDescription
+ snowflake.broker.sendAnswer @id, @pc.localDescription
# OnDataChannel triggered remotely from the client when connection succeeds.
@pc.ondatachannel = (dc) =>
channel = dc.channel
diff --git a/proxy/snowflake.coffee b/proxy/snowflake.coffee
index e8c00aa..7cc01c9 100644
--- a/proxy/snowflake.coffee
+++ b/proxy/snowflake.coffee
@@ -84,6 +84,9 @@ class Snowflake
for i in [1..CONNECTIONS_PER_CLIENT]
@makeProxyPair @relayAddr
return if COPY_PASTE_ENABLED
+ log 'ProxyPair Slots: ' + @proxyPairs.length
+ log 'Snowflake IDs: ' + (@proxyPairs.map (p) -> p.id).join ' | '
+
timer = null
# Temporary countdown.
countdown = (msg, sec) =>
@@ -99,22 +102,37 @@ class Snowflake
msg = 'polling for client... '
msg += '[retries: ' + @retries + ']' if @retries > 0
@ui.setStatus msg
- recv = @broker.getClientOffer()
- @retries++
+ # Pick an available ProxyPair to poll with.
+ pair = @nextAvailableProxyPair()
+ if !pair
+ log 'No more available ProxyPair slots.'
+ countdown(err, DEFAULT_BROKER_POLL_INTERVAL / 1000)
+ return
+ log 'Polling for ' + pair.id
+ recv = @broker.getClientOffer pair.id
recv.then (desc) =>
offer = JSON.parse desc
dbg 'Received:\n\n' + offer.sdp + '\n'
- @receiveOffer offer
+ console.log desc
+ sdp = new RTCSessionDescription offer
+ # @receiveOffer offer
+ if pair.receiveWebRTCOffer sdp
+ @sendAnswer pair if 'offer' == sdp.type
, (err) ->
countdown(err, DEFAULT_BROKER_POLL_INTERVAL / 1000)
+ @retries++
findClients()
+ # Returns the first ProxyPair that's available to connect.
+ nextAvailableProxyPair: ->
+ return @proxyPairs.find (pp, i, arr) -> return !pp.active
+
# Receive an SDP offer from some client assigned by the Broker,
+ # TODO: remove
receiveOffer: (desc) =>
sdp = new RTCSessionDescription desc
- # Use the first proxyPair that's available.
- pair = @proxyPairs.find (pp, i, arr) -> return !pp.active
+ pair = @nextAvailableProxyPair()
if pair.receiveWebRTCOffer sdp
@sendAnswer pair if 'offer' == sdp.type
@@ -190,7 +208,7 @@ init = ->
broker = new Broker brokerUrl
snowflake = new Snowflake broker, ui
- dbg 'Contacting Broker at ' + broker.url + '\nSnowflake ID: ' + broker.id
+ dbg 'Contacting Broker at ' + broker.url
log '== snowflake proxy =='
log 'Copy-Paste mode detected.' if COPY_PASTE_ENABLED
diff --git a/proxy/spec/broker.spec.coffee b/proxy/spec/broker.spec.coffee
index db936c1..aef115f 100644
--- a/proxy/spec/broker.spec.coffee
+++ b/proxy/spec/broker.spec.coffee
@@ -76,9 +76,9 @@ describe 'Broker', ->
it 'responds to the broker with answer', ->
b = new Broker 'fake'
spyOn(b, '_postRequest')
- b.sendAnswer 123
+ b.sendAnswer 'fake id', 123
expect(b._postRequest).toHaveBeenCalledWith(
- jasmine.any(Object), 'answer', '123')
+ 'fake id', jasmine.any(Object), 'answer', '123')
it 'POST XMLHttpRequests to the broker', ->
b = new Broker 'fake'
@@ -86,7 +86,7 @@ describe 'Broker', ->
spyOn(b._xhr, 'open')
spyOn(b._xhr, 'setRequestHeader')
spyOn(b._xhr, 'send')
- b._postRequest b._xhr, 'test', 'data'
+ b._postRequest 0, b._xhr, 'test', 'data'
expect(b._xhr.open).toHaveBeenCalled()
expect(b._xhr.setRequestHeader).toHaveBeenCalled()
expect(b._xhr.send).toHaveBeenCalled()
diff --git a/proxy/util.coffee b/proxy/util.coffee
index ea65e63..a5b247c 100644
--- a/proxy/util.coffee
+++ b/proxy/util.coffee
@@ -5,6 +5,10 @@ Contains helpers for parsing query strings and other utilities.
###
+genSnowflakeID = ->
+ Math.random().toString(36).substring(2)
+
+
Query =
###
Parse a URL query string or application/x-www-form-urlencoded body. The
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits