Skip to content

Commit 33c8027

Browse files
committed
Use a custom dialer for HTTP/3
1 parent 11e824b commit 33c8027

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

dnscrypt-proxy/xtransport.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ import (
2222

2323
"github.com/jedisct1/dlog"
2424
stamps "github.com/jedisct1/go-dnsstamps"
25-
"github.com/quic-go/quic-go/http3"
2625
"github.com/miekg/dns"
26+
"github.com/quic-go/quic-go"
27+
"github.com/quic-go/quic-go/http3"
2728
"golang.org/x/net/http2"
2829
netproxy "golang.org/x/net/proxy"
2930
)
@@ -155,7 +156,7 @@ func (xTransport *XTransport) rebuildTransport() {
155156
ipOnly = "[" + cachedIP.String() + "]"
156157
}
157158
} else {
158-
dlog.Debugf("[%s] IP address was not cached", host)
159+
dlog.Debugf("[%s] IP address was not cached in DialContext", host)
159160
}
160161
addrStr = ipOnly + ":" + strconv.Itoa(port)
161162
if xTransport.proxyDialer == nil {
@@ -223,7 +224,31 @@ func (xTransport *XTransport) rebuildTransport() {
223224
}
224225
xTransport.transport = transport
225226
if xTransport.http3 {
226-
h3Transport := &http3.RoundTripper{DisableCompression: true, TLSClientConfig: &tlsClientConfig}
227+
h3Transport := &http3.RoundTripper{DisableCompression: true, TLSClientConfig: &tlsClientConfig, Dial: func(ctx context.Context, addrStr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
228+
dlog.Debugf("Dialing for H3: [%v]", addrStr)
229+
host, port := ExtractHostAndPort(addrStr, stamps.DefaultPort)
230+
ipOnly := host
231+
cachedIP, _ := xTransport.loadCachedIP(host)
232+
if cachedIP != nil {
233+
if ipv4 := cachedIP.To4(); ipv4 != nil {
234+
ipOnly = ipv4.String()
235+
} else {
236+
ipOnly = "[" + cachedIP.String() + "]"
237+
}
238+
} else {
239+
dlog.Debugf("[%s] IP address was not cached in H3 DialContext", host)
240+
}
241+
addrStr = ipOnly + ":" + strconv.Itoa(port)
242+
udpAddr, err := net.ResolveUDPAddr("udp", addrStr)
243+
if err != nil {
244+
return nil, err
245+
}
246+
udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
247+
if err != nil {
248+
return nil, err
249+
}
250+
return quic.DialEarlyContext(ctx, udpConn, udpAddr, host, tlsCfg, cfg)
251+
}}
227252
xTransport.h3Transport = h3Transport
228253
}
229254
}
@@ -401,7 +426,8 @@ func (xTransport *XTransport) Fetch(
401426
hasAltSupport := false
402427
if xTransport.h3Transport != nil {
403428
xTransport.altSupport.RLock()
404-
altPort, hasAltSupport := xTransport.altSupport.cache[url.Host]
429+
var altPort uint16
430+
altPort, hasAltSupport = xTransport.altSupport.cache[url.Host]
405431
xTransport.altSupport.RUnlock()
406432
if hasAltSupport {
407433
if int(altPort) == port {
@@ -456,6 +482,7 @@ func (xTransport *XTransport) Fetch(
456482
err = errors.New(resp.Status)
457483
}
458484
} else {
485+
dlog.Debugf("HTTP client error: [%v] - closing idle H3 connections", err)
459486
(*xTransport.transport).CloseIdleConnections()
460487
}
461488
statusCode := 503
@@ -496,6 +523,7 @@ func (xTransport *XTransport) Fetch(
496523
}
497524
xTransport.altSupport.Lock()
498525
xTransport.altSupport.cache[url.Host] = altPort
526+
dlog.Debugf("Caching altPort for [%v]", url.Host)
499527
xTransport.altSupport.Unlock()
500528
}
501529
}

0 commit comments

Comments
 (0)