Randomly select front domain from comma-separated list

This commmit changes the command-line and Bridge line arguments to take
a comma-separated list of front domains. The change is backwards
compatible with old Bridge and ClientTransportPlugin lines. At
rendezvous time, a front domain will be randomly chosen from the list.
This commit is contained in:
Cecylia Bocovich 2023-09-23 10:46:46 -04:00
parent 5cdf52c813
commit 9fdfb3d1b5
No known key found for this signature in database
GPG key ID: 009DE379FD9B7B90
7 changed files with 65 additions and 48 deletions

View file

@ -5,8 +5,10 @@ import (
"io"
"io/ioutil"
"log"
"math/rand"
"net/http"
"net/url"
"time"
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/amp"
)
@ -17,7 +19,7 @@ import (
type ampCacheRendezvous struct {
brokerURL *url.URL
cacheURL *url.URL // Optional AMP cache URL.
front string // Optional front domain to replace url.Host in requests.
fronts []string // Optional front domains to replace url.Host in requests.
transport http.RoundTripper // Used to make all requests.
}
@ -25,7 +27,7 @@ type ampCacheRendezvous struct {
// 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) {
func newAMPCacheRendezvous(broker, cache string, fronts []string, transport http.RoundTripper) (*ampCacheRendezvous, error) {
brokerURL, err := url.Parse(broker)
if err != nil {
return nil, err
@ -41,7 +43,7 @@ func newAMPCacheRendezvous(broker, cache, front string, transport http.RoundTrip
return &ampCacheRendezvous{
brokerURL: brokerURL,
cacheURL: cacheURL,
front: front,
fronts: fronts,
transport: transport,
}, nil
}
@ -50,7 +52,6 @@ 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)
// We cannot POST a body through an AMP cache, so instead we GET and
// encode the client poll request message into the URL.
@ -72,11 +73,14 @@ func (r *ampCacheRendezvous) Exchange(encPollReq []byte) ([]byte, error) {
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.
if len(r.fronts) != 0 {
// Do domain fronting. Replace the domain in the URL's with a randomly
// selected front, and store the original domain the HTTP Host header.
rand.Seed(time.Now().UnixNano())
front := r.fronts[rand.Intn(len(r.fronts))]
log.Println("Front domain:", front)
req.Host = req.URL.Host
req.URL.Host = r.front
req.URL.Host = front
}
resp, err := r.transport.RoundTrip(req)