s/MeekChannel/BrokerChannel (close #14) and more informative TODOs

This commit is contained in:
Serene Han 2016-01-31 21:42:53 -08:00
parent 1cdf6a435c
commit 678cf454cd
2 changed files with 40 additions and 32 deletions

View file

@ -1,5 +1,6 @@
// Exchange WebRTC SessionDescriptions over a domain-fronted HTTP // WebRTC Rendezvous requires the exchange of SessionDescriptions between
// signaling channel. // peers. This file contains the domain-fronted HTTP signaling mechanism
// between the client and a desired Broker.
package main package main
import ( import (
@ -12,8 +13,8 @@ import (
"github.com/keroserene/go-webrtc" "github.com/keroserene/go-webrtc"
) )
// Meek Signalling Channel. // Signalling Channel to the Broker.
type MeekChannel struct { type BrokerChannel struct {
// The Host header to put in the HTTP request (optional and may be // The Host header to put in the HTTP request (optional and may be
// different from the host name in URL). // different from the host name in URL).
Host string Host string
@ -21,50 +22,50 @@ type MeekChannel struct {
transport http.Transport // Used to make all requests. transport http.Transport // Used to make all requests.
} }
// Construct a new MeekChannel, where: // Construct a new BrokerChannel, where:
// |broker| is the full URL of the facilitating program which assigns proxies // |broker| is the full URL of the facilitating program which assigns proxies
// to clients, and |front| is the option fronting domain. // to clients, and |front| is the option fronting domain.
func NewMeekChannel(broker string, front string) *MeekChannel { func NewBrokerChannel(broker string, front string) *BrokerChannel {
targetURL, err := url.Parse(broker) targetURL, err := url.Parse(broker)
if nil != err { if nil != err {
return nil return nil
} }
mc := new(MeekChannel) bc := new(BrokerChannel)
mc.url = targetURL bc.url = targetURL
if "" != front { // Optional front domain. if "" != front { // Optional front domain.
mc.Host = mc.url.Host bc.Host = bc.url.Host
mc.url.Host = front bc.url.Host = front
} }
// We make a copy of DefaultTransport because we want the default Dial // We make a copy of DefaultTransport because we want the default Dial
// and TLSHandshakeTimeout settings. But we want to disable the default // and TLSHandshakeTimeout settings. But we want to disable the default
// ProxyFromEnvironment setting. // ProxyFromEnvironment setting.
mc.transport = *http.DefaultTransport.(*http.Transport) bc.transport = *http.DefaultTransport.(*http.Transport)
mc.transport.Proxy = nil bc.transport.Proxy = nil
return mc return bc
} }
// Roundtrip HTTP POST using WebRTC SessionDescriptions. // Roundtrip HTTP POST using WebRTC SessionDescriptions.
// //
// Sends an SDP offer to the meek broker, which assigns a proxy and responds // Send an SDP offer to the broker, which assigns a proxy and responds
// with an SDP answer from a designated remote WebRTC peer. // with an SDP answer from a designated remote WebRTC peer.
func (mc *MeekChannel) Negotiate(offer *webrtc.SessionDescription) ( func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) (
*webrtc.SessionDescription, error) { *webrtc.SessionDescription, error) {
data := bytes.NewReader([]byte(offer.Serialize())) data := bytes.NewReader([]byte(offer.Serialize()))
// Suffix with broker's client registration handler. // Suffix with broker's client registration handler.
request, err := http.NewRequest("POST", mc.url.String()+"client", data) request, err := http.NewRequest("POST", bc.url.String()+"client", data)
if nil != err { if nil != err {
return nil, err return nil, err
} }
if "" != mc.Host { // Set true host if necessary. if "" != bc.Host { // Set true host if necessary.
request.Host = mc.Host request.Host = bc.Host
} }
resp, err := mc.transport.RoundTrip(request) resp, err := bc.transport.RoundTrip(request)
if nil != err { if nil != err {
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
log.Printf("MeekChannel Response:\n%s\n\n", resp.Status) log.Printf("BrokerChannel Response:\n%s\n\n", resp.Status)
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if nil != err { if nil != err {
return nil, err return nil, err

View file

@ -1,10 +1,9 @@
// Client transport plugin for the snowflake pluggable transport. // Client transport plugin for the Snowflake pluggable transport.
//
// TODO: Use meek for signalling.
package main package main
import ( import (
"bufio" "bufio"
"errors"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@ -16,10 +15,9 @@ import (
"syscall" "syscall"
"time" "time"
"git.torproject.org/pluggable-transports/goptlib.git"
"github.com/keroserene/go-webrtc" "github.com/keroserene/go-webrtc"
"github.com/keroserene/go-webrtc/data" "github.com/keroserene/go-webrtc/data"
"git.torproject.org/pluggable-transports/goptlib.git"
) )
var ptInfo pt.ClientInfo var ptInfo pt.ClientInfo
@ -93,7 +91,7 @@ func (c *webRTCConn) SetWriteDeadline(t time.Time) error {
return fmt.Errorf("SetWriteDeadline not implemented") return fmt.Errorf("SetWriteDeadline not implemented")
} }
func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) ( func dialWebRTC(config *webrtc.Configuration, broker *BrokerChannel) (
*webRTCConn, error) { *webRTCConn, error) {
offerChan := make(chan *webrtc.SessionDescription) offerChan := make(chan *webrtc.SessionDescription)
@ -131,6 +129,8 @@ func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) (
log.Printf("OnIceComplete") log.Printf("OnIceComplete")
offerChan <- pc.LocalDescription() offerChan <- pc.LocalDescription()
} }
// This callback is not expected, as the Client initiates the creation
// of the data channel, not the remote peer.
pc.OnDataChannel = func(channel *data.Channel) { pc.OnDataChannel = func(channel *data.Channel) {
log.Println("OnDataChannel") log.Println("OnDataChannel")
panic("OnDataChannel") panic("OnDataChannel")
@ -151,6 +151,7 @@ func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) (
log.Println("OnClose channel") log.Println("OnClose channel")
pw.Close() pw.Close()
close(openChan) close(openChan)
// TODO: (Issue #12) Should attempt to renegotiate at this point.
} }
dc.OnMessage = func(msg []byte) { dc.OnMessage = func(msg []byte) {
log.Printf("OnMessage <--- %d bytes", len(msg)) log.Printf("OnMessage <--- %d bytes", len(msg))
@ -173,14 +174,14 @@ func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) (
log.Printf("----------------") log.Printf("----------------")
go func() { go func() {
if "" != brokerURL { if "" != brokerURL {
log.Println("Sending offer via meek channel...\nTarget URL: ", brokerURL, log.Println("Sending offer via BrokerChannel...\nTarget URL: ", brokerURL,
"\nFront URL: ", frontDomain) "\nFront URL: ", frontDomain)
answer, err := meek.Negotiate(pc.LocalDescription()) answer, err := broker.Negotiate(pc.LocalDescription())
if nil != err { if nil != err {
log.Printf("MeekChannel signaling error: %s", err) log.Printf("BrokerChannel signaling error: %s", err)
} }
if nil == answer { if nil == answer {
log.Printf("MeekChannel: No answer received.") log.Printf("BrokerChannel: No answer received.")
} else { } else {
signalChan <- answer signalChan <- answer
} }
@ -236,10 +237,16 @@ func handler(conn *pt.SocksConn) error {
}() }()
defer conn.Close() defer conn.Close()
// TODO: [#3] Fetch ICE server information from Broker.
// TODO: [#18] Consider TURN servers here too.
config := webrtc.NewConfiguration( config := webrtc.NewConfiguration(
webrtc.OptionIceServer("stun:stun.l.google.com:19302")) webrtc.OptionIceServer("stun:stun.l.google.com:19302"))
meek := NewMeekChannel(brokerURL, frontDomain) broker := NewBrokerChannel(brokerURL, frontDomain)
remote, err := dialWebRTC(config, meek) if nil == broker {
conn.Reject()
return errors.New("Failed to prepare BrokerChannel")
}
remote, err := dialWebRTC(config, broker)
if err != nil { if err != nil {
conn.Reject() conn.Reject()
return err return err