Skip to content

utls RoundTripper does not work when it is supposed to use HTTP/1

Try setting utls=hellorandomizednoalpn in the bridge line. snowflake-client's rendezvous will fail with:

WebRTC: incorrect ALPN negotiated  Retrying...

Lack of ALPN should cause a fallback to HTTP/1, and the connection should still work. What's going wrong.

The problem is the internal connectWithH1 map, which is inconsistently keyed. Entries are written to the map with host:port keys. Entries are read from the map using sometimes host:port keys, and sometimes host keys.

  • RoundTrip calls gets its domain name from req.URL.Host; i.e., it uses a key like "cdn.sstatic.net".
  • dialOrGetTLSWithExpectedALPN gets its domain name from an addr argument to DialTLS; i.e., it uses a key like "cdn.sstatic.net:443".

Adding a few debugging logs makes it clear what is going wrong:

2022/10/21 23:26:48 Target URL:  snowflake-broker.torproject.net.global.prod.fastly.net
2022/10/21 23:26:48 Front URL:   cdn.sstatic.net
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net") -> false
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net:443") -> false
2022/10/21 23:26:48 setShouldConnectWithH1("cdn.sstatic.net:443")
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net") -> false
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net:443") -> true
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net") -> false
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net:443") -> true
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net") -> false
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net:443") -> true
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net") -> false
2022/10/21 23:26:48 getShouldConnectWithH1("cdn.sstatic.net:443") -> true
2022/10/21 23:26:48 WebRTC: closing DataChannel
2022/10/21 23:26:48 WebRTC: closing PeerConnection
2022/10/21 23:26:48 WebRTC: Closing
2022/10/21 23:26:48 WebRTC: incorrect ALPN negotiated  Retrying...