snowflake/client/meek-webrtc.go

84 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Exchange WebRTC SessionDescriptions over meek.
// Much of this source is extracted from meek-client.go.
package main
import (
"bytes"
"io/ioutil"
"net/http"
"net/url"
"github.com/keroserene/go-webrtc"
)
// RequestInfo encapsulates all the configuration used for a requestresponse
// roundtrip, including variables that may come from SOCKS args or from the
// command line.
type RequestInfo struct {
// What to put in the X-Session-ID header.
// SessionID string
// The URL to request.
URL *url.URL
// The Host header to put in the HTTP request (optional and may be
// different from the host name in URL).
Host string
}
func NewRequestInfo(meekUrl string, front string) *RequestInfo {
info := new(RequestInfo)
requestUrl, err := url.Parse(meekUrl)
if nil != err {
return nil
}
info.URL = requestUrl
info.Host = info.URL.Host
info.URL.Host = front
return info
}
// Meek Signalling Channel
type MeekChannel struct {
info *RequestInfo
// Used to make all requests.
transport http.Transport
}
func NewMeekChannel(info *RequestInfo) *MeekChannel {
m := new(MeekChannel)
// We make a copy of DefaultTransport because we want the default Dial
// and TLSHandshakeTimeout settings. But we want to disable the default
// ProxyFromEnvironment setting. Proxy is overridden below if
// options.ProxyURL is set.
m.transport = *http.DefaultTransport.(*http.Transport)
m.transport.Proxy = nil
m.info = info
return m
}
// Do an HTTP roundtrip using the payload data in buf.
func (m *MeekChannel) roundTripHTTP(buf []byte) (*http.Response, error) {
req, err := http.NewRequest("POST", m.info.URL.String(), bytes.NewReader(buf))
if nil != err {
return nil, err
}
if "" != m.info.Host {
req.Host = m.info.Host
}
// req.Header.Set("X-Session-Id", m.info.SessionID)
return m.transport.RoundTrip(req)
}
// Send an SDP offer to the meek facilitator, and wait for an SDP answer from
// the assigned proxy in the response.
func (m *MeekChannel) Negotiate(offer *webrtc.SessionDescription) (
*webrtc.SessionDescription, error) {
buf := []byte(offer.Serialize())
resp, err := m.roundTripHTTP(buf)
if nil != err {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
answer := webrtc.DeserializeSessionDescription(string(body))
return answer, nil
}