diff --git a/client/meek-webrtc.go b/client/rendezvous.go similarity index 57% rename from client/meek-webrtc.go rename to client/rendezvous.go index 34ff185..ea0b338 100644 --- a/client/meek-webrtc.go +++ b/client/rendezvous.go @@ -1,5 +1,6 @@ -// Exchange WebRTC SessionDescriptions over a domain-fronted HTTP -// signaling channel. +// WebRTC Rendezvous requires the exchange of SessionDescriptions between +// peers. This file contains the domain-fronted HTTP signaling mechanism +// between the client and a desired Broker. package main import ( @@ -12,8 +13,8 @@ import ( "github.com/keroserene/go-webrtc" ) -// Meek Signalling Channel. -type MeekChannel struct { +// Signalling Channel to the Broker. +type BrokerChannel struct { // The Host header to put in the HTTP request (optional and may be // different from the host name in URL). Host string @@ -21,50 +22,50 @@ type MeekChannel struct { 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 // 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) if nil != err { return nil } - mc := new(MeekChannel) - mc.url = targetURL + bc := new(BrokerChannel) + bc.url = targetURL if "" != front { // Optional front domain. - mc.Host = mc.url.Host - mc.url.Host = front + bc.Host = bc.url.Host + bc.url.Host = front } // We make a copy of DefaultTransport because we want the default Dial // and TLSHandshakeTimeout settings. But we want to disable the default // ProxyFromEnvironment setting. - mc.transport = *http.DefaultTransport.(*http.Transport) - mc.transport.Proxy = nil - return mc + bc.transport = *http.DefaultTransport.(*http.Transport) + bc.transport.Proxy = nil + return bc } // 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. -func (mc *MeekChannel) Negotiate(offer *webrtc.SessionDescription) ( +func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) ( *webrtc.SessionDescription, error) { data := bytes.NewReader([]byte(offer.Serialize())) // 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 { return nil, err } - if "" != mc.Host { // Set true host if necessary. - request.Host = mc.Host + if "" != bc.Host { // Set true host if necessary. + request.Host = bc.Host } - resp, err := mc.transport.RoundTrip(request) + resp, err := bc.transport.RoundTrip(request) if nil != err { return nil, err } 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) if nil != err { return nil, err diff --git a/client/snowflake.go b/client/snowflake.go index 83179a3..486e602 100644 --- a/client/snowflake.go +++ b/client/snowflake.go @@ -1,10 +1,9 @@ -// Client transport plugin for the snowflake pluggable transport. -// -// TODO: Use meek for signalling. +// Client transport plugin for the Snowflake pluggable transport. package main import ( "bufio" + "errors" "flag" "fmt" "io" @@ -16,10 +15,9 @@ import ( "syscall" "time" + "git.torproject.org/pluggable-transports/goptlib.git" "github.com/keroserene/go-webrtc" "github.com/keroserene/go-webrtc/data" - - "git.torproject.org/pluggable-transports/goptlib.git" ) var ptInfo pt.ClientInfo @@ -93,7 +91,7 @@ func (c *webRTCConn) SetWriteDeadline(t time.Time) error { return fmt.Errorf("SetWriteDeadline not implemented") } -func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) ( +func dialWebRTC(config *webrtc.Configuration, broker *BrokerChannel) ( *webRTCConn, error) { offerChan := make(chan *webrtc.SessionDescription) @@ -131,6 +129,8 @@ func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) ( log.Printf("OnIceComplete") 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) { log.Println("OnDataChannel") panic("OnDataChannel") @@ -151,6 +151,7 @@ func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) ( log.Println("OnClose channel") pw.Close() close(openChan) + // TODO: (Issue #12) Should attempt to renegotiate at this point. } dc.OnMessage = func(msg []byte) { log.Printf("OnMessage <--- %d bytes", len(msg)) @@ -173,14 +174,14 @@ func dialWebRTC(config *webrtc.Configuration, meek *MeekChannel) ( log.Printf("----------------") go func() { if "" != brokerURL { - log.Println("Sending offer via meek channel...\nTarget URL: ", brokerURL, + log.Println("Sending offer via BrokerChannel...\nTarget URL: ", brokerURL, "\nFront URL: ", frontDomain) - answer, err := meek.Negotiate(pc.LocalDescription()) + answer, err := broker.Negotiate(pc.LocalDescription()) if nil != err { - log.Printf("MeekChannel signaling error: %s", err) + log.Printf("BrokerChannel signaling error: %s", err) } if nil == answer { - log.Printf("MeekChannel: No answer received.") + log.Printf("BrokerChannel: No answer received.") } else { signalChan <- answer } @@ -236,10 +237,16 @@ func handler(conn *pt.SocksConn) error { }() defer conn.Close() + // TODO: [#3] Fetch ICE server information from Broker. + // TODO: [#18] Consider TURN servers here too. config := webrtc.NewConfiguration( webrtc.OptionIceServer("stun:stun.l.google.com:19302")) - meek := NewMeekChannel(brokerURL, frontDomain) - remote, err := dialWebRTC(config, meek) + broker := NewBrokerChannel(brokerURL, frontDomain) + if nil == broker { + conn.Reject() + return errors.New("Failed to prepare BrokerChannel") + } + remote, err := dialWebRTC(config, broker) if err != nil { conn.Reject() return err