mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-14 05:11:19 -04:00
Skeleton of ampCacheRendezvous.
Currently the same as httpRendezvous, but activated using the -ampcache command-line option.
This commit is contained in:
parent
c9e0dd287f
commit
c13810192d
4 changed files with 95 additions and 6 deletions
|
@ -59,13 +59,22 @@ func CreateBrokerTransport() http.RoundTripper {
|
||||||
// Construct a new BrokerChannel, 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 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)
|
log.Println("Rendezvous using Broker at:", broker)
|
||||||
|
if ampCache != "" {
|
||||||
|
log.Println("Through AMP cache at:", ampCache)
|
||||||
|
}
|
||||||
if front != "" {
|
if front != "" {
|
||||||
log.Println("Domain fronting using:", 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
78
client/lib/rendezvous_ampcache.go
Normal file
78
client/lib/rendezvous_ampcache.go
Normal 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 &CacheRendezvous{
|
||||||
|
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)
|
||||||
|
}
|
|
@ -39,7 +39,8 @@ type Transport struct {
|
||||||
// iceAddresses are the STUN/TURN urls needed for WebRTC negotiation
|
// iceAddresses are the STUN/TURN urls needed for WebRTC negotiation
|
||||||
// keepLocalAddresses is a flag to enable sending local network addresses (for testing purposes)
|
// 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
|
// 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 ---")
|
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, " "))
|
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(
|
broker, err := NewBrokerChannel(
|
||||||
brokerURL, frontDomain, CreateBrokerTransport(),
|
brokerURL, ampCacheURL, frontDomain, CreateBrokerTransport(),
|
||||||
keepLocalAddresses)
|
keepLocalAddresses)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -94,6 +94,7 @@ func main() {
|
||||||
iceServersCommas := flag.String("ice", "", "comma-separated list of ICE servers")
|
iceServersCommas := flag.String("ice", "", "comma-separated list of ICE servers")
|
||||||
brokerURL := flag.String("url", "", "URL of signaling broker")
|
brokerURL := flag.String("url", "", "URL of signaling broker")
|
||||||
frontDomain := flag.String("front", "", "front domain")
|
frontDomain := flag.String("front", "", "front domain")
|
||||||
|
ampCacheURL := flag.String("ampcache", "", "URL of AMP cache to use as a proxy for signaling")
|
||||||
logFilename := flag.String("log", "", "name of log file")
|
logFilename := flag.String("log", "", "name of log file")
|
||||||
logToStateDir := flag.Bool("log-to-state-dir", false, "resolve the log file relative to tor's pt state dir")
|
logToStateDir := flag.Bool("log-to-state-dir", false, "resolve the log file relative to tor's pt state dir")
|
||||||
keepLocalAddresses := flag.Bool("keep-local-addresses", false, "keep local LAN address ICE candidates")
|
keepLocalAddresses := flag.Bool("keep-local-addresses", false, "keep local LAN address ICE candidates")
|
||||||
|
@ -140,7 +141,7 @@ func main() {
|
||||||
|
|
||||||
iceAddresses := strings.Split(strings.TrimSpace(*iceServersCommas), ",")
|
iceAddresses := strings.Split(strings.TrimSpace(*iceServersCommas), ",")
|
||||||
|
|
||||||
transport, err := sf.NewSnowflakeClient(*brokerURL, *frontDomain, iceAddresses,
|
transport, err := sf.NewSnowflakeClient(*brokerURL, *ampCacheURL, *frontDomain, iceAddresses,
|
||||||
*keepLocalAddresses || *oldKeepLocalAddresses, *max)
|
*keepLocalAddresses || *oldKeepLocalAddresses, *max)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to start snowflake transport: ", err)
|
log.Fatal("Failed to start snowflake transport: ", err)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue