@@ -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