Skeleton of ampCacheRendezvous.

Currently the same as httpRendezvous, but activated using the -ampcache
command-line option.
This commit is contained in:
David Fifield 2021-07-18 14:18:32 -06:00
parent c9e0dd287f
commit c13810192d
4 changed files with 95 additions and 6 deletions

View file

@ -59,13 +59,22 @@ func CreateBrokerTransport() http.RoundTripper {
// 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 NewBrokerChannel(broker string, front string, transport http.RoundTripper, keepLocalAddresses bool) (*BrokerChannel, error) {
func NewBrokerChannel(broker, ampCache, front string, transport http.RoundTripper, keepLocalAddresses bool) (*BrokerChannel, error) {
log.Println("Rendezvous using Broker at:", broker)
if ampCache != "" {
log.Println("Through AMP cache at:", ampCache)
}
if front != "" {
log.Println("Domain fronting using:", front)
}
rendezvous, err := newHTTPRendezvous(broker, front, transport)
var rendezvous rendezvousMethod
var err error
if ampCache != "" {
rendezvous, err = newAMPCacheRendezvous(broker, ampCache, front, transport)
} else {
rendezvous, err = newHTTPRendezvous(broker, front, transport)
}
if err != nil {
return nil, err
}

View file

@ -0,0 +1,78 @@
package lib
import (
"bytes"
"errors"
"log"
"net/http"
"net/url"
)
// ampCacheRendezvous is a rendezvousMethod that communicates with the
// .../amp/client route of the broker, optionally over an AMP cache proxy, and
// with optional domain fronting.
type ampCacheRendezvous struct {
brokerURL *url.URL
cacheURL *url.URL // Optional AMP cache URL.
front string // Optional front domain to replace url.Host in requests.
transport http.RoundTripper // Used to make all requests.
}
// newAMPCacheRendezvous creates a new ampCacheRendezvous that contacts the
// broker at the given URL, optionally proxying through an AMP cache, and with
// an optional front domain. transport is the http.RoundTripper used to make all
// requests.
func newAMPCacheRendezvous(broker, cache, front string, transport http.RoundTripper) (*ampCacheRendezvous, error) {
brokerURL, err := url.Parse(broker)
if err != nil {
return nil, err
}
var cacheURL *url.URL
if cache != "" {
var err error
cacheURL, err = url.Parse(cache)
if err != nil {
return nil, err
}
}
return &ampCacheRendezvous{
brokerURL: brokerURL,
cacheURL: cacheURL,
front: front,
transport: transport,
}, nil
}
func (r *ampCacheRendezvous) Exchange(encPollReq []byte) ([]byte, error) {
log.Println("Negotiating via AMP cache rendezvous...")
log.Println("Broker URL:", r.brokerURL)
log.Println("AMP cache URL:", r.cacheURL)
log.Println("Front domain:", r.front)
// Suffix the path with the broker's client registration handler.
reqURL := r.brokerURL.ResolveReference(&url.URL{Path: "client"})
req, err := http.NewRequest("POST", reqURL.String(), bytes.NewReader(encPollReq))
if err != nil {
return nil, err
}
if r.front != "" {
// Do domain fronting. Replace the domain in the URL's with the
// front, and store the original domain the HTTP Host header.
req.Host = req.URL.Host
req.URL.Host = r.front
}
resp, err := r.transport.RoundTrip(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
log.Printf("AMP cache rendezvous response: %s", resp.Status)
if resp.StatusCode != http.StatusOK {
return nil, errors.New(BrokerErrorUnexpected)
}
return limitedRead(resp.Body, readLimit)
}

View file

@ -39,7 +39,8 @@ type Transport struct {
// iceAddresses are the STUN/TURN urls needed for WebRTC negotiation
// keepLocalAddresses is a flag to enable sending local network addresses (for testing purposes)
// max is the maximum number of snowflakes the client should gather for each SOCKS connection
func NewSnowflakeClient(brokerURL, frontDomain string, iceAddresses []string, keepLocalAddresses bool, max int) (*Transport, error) {
func NewSnowflakeClient(brokerURL, ampCacheURL, frontDomain string,
iceAddresses []string, keepLocalAddresses bool, max int) (*Transport, error) {
log.Println("\n\n\n --- Starting Snowflake Client ---")
@ -57,9 +58,9 @@ func NewSnowflakeClient(brokerURL, frontDomain string, iceAddresses []string, ke
log.Printf("url: %v", strings.Join(server.URLs, " "))
}
// Use potentially domain-fronting broker to rendezvous.
// Rendezvous with broker using the given parameters.
broker, err := NewBrokerChannel(
brokerURL, frontDomain, CreateBrokerTransport(),
brokerURL, ampCacheURL, frontDomain, CreateBrokerTransport(),
keepLocalAddresses)
if err != nil {
return nil, err