[tor-commits] [meek/main] Only lock the assignment to rt.rt, not the whole RoundTrip.

dcf at torproject.org dcf at torproject.org
Thu Dec 30 04:40:02 UTC 2021


commit 88fd7233036450e0d3278f3afe0a9995974ae120
Author: David Fifield <david at bamsoftware.com>
Date:   Wed Dec 29 21:35:06 2021 -0700

    Only lock the assignment to rt.rt, not the whole RoundTrip.
    
    We need to guard against concurrent modification of rt.rt, but once it
    is set, we many concurrently call rt.rt.RoundTrip. The way this was
    written before, it was preventing more than one RoundTrip from happening
    at once. (Which was not noticeable, because the protocol serialized all
    RoundTrips.)
---
 meek-client/utls.go | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/meek-client/utls.go b/meek-client/utls.go
index bcd386f..1f3effb 100644
--- a/meek-client/utls.go
+++ b/meek-client/utls.go
@@ -94,11 +94,10 @@ func dialUTLS(network, addr string, cfg *utls.Config, clientHelloID *utls.Client
 //
 // Can only be reused among servers which negotiate the same ALPN.
 type UTLSRoundTripper struct {
-	sync.Mutex
-
 	clientHelloID *utls.ClientHelloID
 	config        *utls.Config
 	proxyDialer   proxy.Dialer
+	rtOnce        sync.Once
 	rt            http.RoundTripper
 
 	// Transport for HTTP requests, which don't use uTLS.
@@ -115,18 +114,16 @@ func (rt *UTLSRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
 		return nil, fmt.Errorf("unsupported URL scheme %q", req.URL.Scheme)
 	}
 
-	rt.Lock()
-	defer rt.Unlock()
-
-	if rt.rt == nil {
-		// On the first call, make an http.Transport or http2.Transport
-		// as appropriate.
-		var err error
+	// On the first call, make an http.Transport or http2.Transport as
+	// appropriate.
+	var err error
+	rt.rtOnce.Do(func() {
 		rt.rt, err = makeRoundTripper(req.URL, rt.clientHelloID, rt.config, rt.proxyDialer)
-		if err != nil {
-			return nil, err
-		}
+	})
+	if err != nil {
+		return nil, err
 	}
+
 	// Forward the request to the internal http.Transport or http2.Transport.
 	return rt.rt.RoundTrip(req)
 }



More information about the tor-commits mailing list