mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-14 05:11:19 -04:00
Snowflake proxy successfully reset and bootstrap a new client (#15)
This commit is contained in:
parent
133f657928
commit
77fbfe0e66
4 changed files with 33 additions and 25 deletions
|
@ -171,7 +171,9 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write(offer)
|
w.Write(offer)
|
||||||
|
|
||||||
case <-time.After(time.Second * 10):
|
case <-time.After(time.Second * 10):
|
||||||
|
// This snowflake is no longer available to serve clients.
|
||||||
heap.Remove(snowflakes, snowflake.index)
|
heap.Remove(snowflakes, snowflake.index)
|
||||||
|
delete(snowflakeMap, snowflake.id)
|
||||||
w.WriteHeader(http.StatusGatewayTimeout)
|
w.WriteHeader(http.StatusGatewayTimeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,6 @@ class Broker
|
||||||
return
|
return
|
||||||
xhr.onreadystatechange = ->
|
xhr.onreadystatechange = ->
|
||||||
return if xhr.DONE != xhr.readyState
|
return if xhr.DONE != xhr.readyState
|
||||||
log xhr
|
|
||||||
switch xhr.status
|
switch xhr.status
|
||||||
when STATUS_OK
|
when STATUS_OK
|
||||||
log 'Broker: Successfully replied with answer.'
|
log 'Broker: Successfully replied with answer.'
|
||||||
|
|
|
@ -19,7 +19,8 @@ class ProxyPair
|
||||||
|
|
||||||
constructor: (@clientAddr, @relayAddr, @rateLimit) ->
|
constructor: (@clientAddr, @relayAddr, @rateLimit) ->
|
||||||
|
|
||||||
connectClient: =>
|
# Prepare a WebRTC PeerConnection and await for an SDP offer.
|
||||||
|
begin: ->
|
||||||
@pc = new PeerConnection config, {
|
@pc = new PeerConnection config, {
|
||||||
optional: [
|
optional: [
|
||||||
{ DtlsSrtpKeyAgreement: true }
|
{ DtlsSrtpKeyAgreement: true }
|
||||||
|
@ -44,6 +45,16 @@ class ProxyPair
|
||||||
@prepareDataChannel channel
|
@prepareDataChannel channel
|
||||||
@client = channel
|
@client = channel
|
||||||
|
|
||||||
|
receiveWebRTCOffer: (offer) ->
|
||||||
|
console.assert 'offer' == offer.type
|
||||||
|
try
|
||||||
|
err = @pc.setRemoteDescription offer
|
||||||
|
catch e
|
||||||
|
log 'Invalid SDP message.'
|
||||||
|
return false
|
||||||
|
log 'SDP ' + offer.type + ' successfully received.'
|
||||||
|
true
|
||||||
|
|
||||||
prepareDataChannel: (channel) =>
|
prepareDataChannel: (channel) =>
|
||||||
channel.onopen = =>
|
channel.onopen = =>
|
||||||
log 'Data channel opened!'
|
log 'Data channel opened!'
|
||||||
|
@ -56,8 +67,9 @@ class ProxyPair
|
||||||
log 'Data channel closed.'
|
log 'Data channel closed.'
|
||||||
snowflake.state = MODE.INIT
|
snowflake.state = MODE.INIT
|
||||||
$msglog.className = ''
|
$msglog.className = ''
|
||||||
channel.onerror = ->
|
# Change this for multiplexing.
|
||||||
log 'Data channel error!'
|
snowflake.reset()
|
||||||
|
channel.onerror = -> log 'Data channel error!'
|
||||||
channel.onmessage = @onClientToRelayMessage
|
channel.onmessage = @onClientToRelayMessage
|
||||||
|
|
||||||
# Assumes WebRTC datachannel is connected.
|
# Assumes WebRTC datachannel is connected.
|
||||||
|
|
|
@ -87,21 +87,17 @@ class Snowflake
|
||||||
return false
|
return false
|
||||||
@relayAddr = addr
|
@relayAddr = addr
|
||||||
log 'Using ' + relayAddr + ' as Relay.'
|
log 'Using ' + relayAddr + ' as Relay.'
|
||||||
@beginWebRTC()
|
log 'Input offer from the snowflake client:' if COPY_PASTE_ENABLED
|
||||||
log 'Input offer from the snowflake client:'
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
# Initialize WebRTC PeerConnection
|
# Initialize WebRTC PeerConnection
|
||||||
beginWebRTC: ->
|
beginWebRTC: ->
|
||||||
log 'Starting up Snowflake...\n'
|
|
||||||
@state = MODE.WEBRTC_CONNECTING
|
@state = MODE.WEBRTC_CONNECTING
|
||||||
for i in [1..CONNECTIONS_PER_CLIENT]
|
for i in [1..CONNECTIONS_PER_CLIENT]
|
||||||
@makeProxyPair @relayAddr
|
@makeProxyPair @relayAddr
|
||||||
@proxyPair = @proxyPairs[0]
|
@proxyPair = @proxyPairs[0]
|
||||||
|
|
||||||
# Poll broker for clients.
|
# Poll broker for clients.
|
||||||
findClients: ->
|
findClients = =>
|
||||||
poll = =>
|
|
||||||
recv = broker.getClientOffer()
|
recv = broker.getClientOffer()
|
||||||
recv.then((desc) =>
|
recv.then((desc) =>
|
||||||
offer = JSON.parse desc
|
offer = JSON.parse desc
|
||||||
|
@ -109,21 +105,15 @@ class Snowflake
|
||||||
@receiveOffer offer
|
@receiveOffer offer
|
||||||
, (err) ->
|
, (err) ->
|
||||||
log err
|
log err
|
||||||
setTimeout(poll, 1000)
|
setTimeout(findClients, 1000)
|
||||||
)
|
)
|
||||||
poll()
|
findClients()
|
||||||
|
|
||||||
# Receive an SDP offer from client plugin.
|
# Receive an SDP offer from some client assigned by the Broker.
|
||||||
receiveOffer: (desc) =>
|
receiveOffer: (desc) =>
|
||||||
sdp = new RTCSessionDescription desc
|
sdp = new RTCSessionDescription desc
|
||||||
try
|
if @proxyPair.receiveWebRTCOffer sdp
|
||||||
err = @proxyPair.pc.setRemoteDescription sdp
|
|
||||||
catch e
|
|
||||||
log 'Invalid SDP message.'
|
|
||||||
return false
|
|
||||||
log 'SDP ' + sdp.type + ' successfully received.'
|
|
||||||
@sendAnswer() if 'offer' == sdp.type
|
@sendAnswer() if 'offer' == sdp.type
|
||||||
true
|
|
||||||
|
|
||||||
sendAnswer: =>
|
sendAnswer: =>
|
||||||
next = (sdp) =>
|
next = (sdp) =>
|
||||||
|
@ -132,7 +122,6 @@ class Snowflake
|
||||||
promise = @proxyPair.pc.createAnswer next
|
promise = @proxyPair.pc.createAnswer next
|
||||||
promise.then next if promise
|
promise.then next if promise
|
||||||
|
|
||||||
|
|
||||||
makeProxyPair: (relay) ->
|
makeProxyPair: (relay) ->
|
||||||
pair = new ProxyPair null, relay, @rateLimit
|
pair = new ProxyPair null, relay, @rateLimit
|
||||||
@proxyPairs.push pair
|
@proxyPairs.push pair
|
||||||
|
@ -141,7 +130,7 @@ class Snowflake
|
||||||
@proxyPairs.splice(@proxyPairs.indexOf(pair), 1)
|
@proxyPairs.splice(@proxyPairs.indexOf(pair), 1)
|
||||||
@badge.endProxy() if @badge
|
@badge.endProxy() if @badge
|
||||||
try
|
try
|
||||||
pair.connectClient()
|
pair.begin()
|
||||||
catch err
|
catch err
|
||||||
log 'ERROR: ProxyPair exception while connecting.'
|
log 'ERROR: ProxyPair exception while connecting.'
|
||||||
log err
|
log err
|
||||||
|
@ -162,6 +151,12 @@ class Snowflake
|
||||||
@cease()
|
@cease()
|
||||||
@badge.die() if @badge
|
@badge.die() if @badge
|
||||||
|
|
||||||
|
# Close all existing ProxyPairs and begin finding new clients from scratch.
|
||||||
|
reset: ->
|
||||||
|
@cease()
|
||||||
|
log '\nSnowflake resetting...'
|
||||||
|
@beginWebRTC()
|
||||||
|
|
||||||
snowflake = null
|
snowflake = null
|
||||||
broker = null
|
broker = null
|
||||||
|
|
||||||
|
@ -241,6 +236,6 @@ init = ->
|
||||||
log 'Input desired relay address:'
|
log 'Input desired relay address:'
|
||||||
else
|
else
|
||||||
snowflake.setRelayAddr DEFAULT_WEBSOCKET
|
snowflake.setRelayAddr DEFAULT_WEBSOCKET
|
||||||
snowflake.findClients()
|
snowflake.beginWebRTC()
|
||||||
|
|
||||||
window.onload = init if window
|
window.onload = init if window
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue