@@ -3,6 +3,7 @@ package dns
3
3
import (
4
4
"bytes"
5
5
"context"
6
+ "crypto/tls"
6
7
"fmt"
7
8
"io"
8
9
"net/http"
@@ -23,6 +24,7 @@ import (
23
24
"github.com/xtls/xray-core/features/routing"
24
25
"github.com/xtls/xray-core/transport/internet"
25
26
"golang.org/x/net/dns/dnsmessage"
27
+ "golang.org/x/net/http2"
26
28
)
27
29
28
30
// DoHNameServer implemented DNS over HTTPS (RFC8484) Wire Format,
@@ -41,49 +43,59 @@ type DoHNameServer struct {
41
43
}
42
44
43
45
// NewDoHNameServer creates DOH server object for remote resolving.
44
- func NewDoHNameServer (url * url.URL , dispatcher routing.Dispatcher , queryStrategy QueryStrategy ) (* DoHNameServer , error ) {
45
- errors .LogInfo (context .Background (), "DNS: created Remote DOH client for " , url .String ())
46
+ func NewDoHNameServer (url * url.URL , dispatcher routing.Dispatcher , queryStrategy QueryStrategy , h2c bool ) (* DoHNameServer , error ) {
47
+ url .Scheme = "https"
48
+ errors .LogInfo (context .Background (), "DNS: created Remote DNS-over-HTTPS client for " , url .String (), ", with h2c " , h2c )
46
49
s := baseDOHNameServer (url , "DOH" , queryStrategy )
47
50
48
51
s .dispatcher = dispatcher
49
- tr := & http.Transport {
50
- MaxIdleConns : 30 ,
51
- IdleConnTimeout : 90 * time .Second ,
52
- TLSHandshakeTimeout : 30 * time .Second ,
53
- ForceAttemptHTTP2 : true ,
54
- DialContext : func (ctx context.Context , network , addr string ) (net.Conn , error ) {
55
- dest , err := net .ParseDestination (network + ":" + addr )
56
- if err != nil {
57
- return nil , err
58
- }
59
- link , err := s .dispatcher .Dispatch (toDnsContext (ctx , s .dohURL ), dest )
60
- select {
61
- case <- ctx .Done ():
62
- return nil , ctx .Err ()
63
- default :
52
+ dialContext := func (ctx context.Context , network , addr string ) (net.Conn , error ) {
53
+ dest , err := net .ParseDestination (network + ":" + addr )
54
+ if err != nil {
55
+ return nil , err
56
+ }
57
+ link , err := s .dispatcher .Dispatch (toDnsContext (ctx , s .dohURL ), dest )
58
+ select {
59
+ case <- ctx .Done ():
60
+ return nil , ctx .Err ()
61
+ default :
64
62
65
- }
66
- if err != nil {
67
- return nil , err
68
- }
63
+ }
64
+ if err != nil {
65
+ return nil , err
66
+ }
69
67
70
- cc := common.ChainedClosable {}
71
- if cw , ok := link .Writer .(common.Closable ); ok {
72
- cc = append (cc , cw )
73
- }
74
- if cr , ok := link .Reader .(common.Closable ); ok {
75
- cc = append (cc , cr )
76
- }
77
- return cnc .NewConnection (
78
- cnc .ConnectionInputMulti (link .Writer ),
79
- cnc .ConnectionOutputMulti (link .Reader ),
80
- cnc .ConnectionOnClose (cc ),
81
- ), nil
82
- },
68
+ cc := common.ChainedClosable {}
69
+ if cw , ok := link .Writer .(common.Closable ); ok {
70
+ cc = append (cc , cw )
71
+ }
72
+ if cr , ok := link .Reader .(common.Closable ); ok {
73
+ cc = append (cc , cr )
74
+ }
75
+ return cnc .NewConnection (
76
+ cnc .ConnectionInputMulti (link .Writer ),
77
+ cnc .ConnectionOutputMulti (link .Reader ),
78
+ cnc .ConnectionOnClose (cc ),
79
+ ), nil
83
80
}
81
+
84
82
s .httpClient = & http.Client {
85
- Timeout : time .Second * 180 ,
86
- Transport : tr ,
83
+ Timeout : time .Second * 180 ,
84
+ Transport : & http.Transport {
85
+ MaxIdleConns : 30 ,
86
+ IdleConnTimeout : 90 * time .Second ,
87
+ TLSHandshakeTimeout : 30 * time .Second ,
88
+ ForceAttemptHTTP2 : true ,
89
+ DialContext : dialContext ,
90
+ },
91
+ }
92
+ if h2c {
93
+ s .httpClient .Transport = & http2.Transport {
94
+ IdleConnTimeout : 90 * time .Second ,
95
+ DialTLSContext : func (ctx context.Context , network , addr string , cfg * tls.Config ) (net.Conn , error ) {
96
+ return dialContext (ctx , network , addr )
97
+ },
98
+ }
87
99
}
88
100
89
101
return s , nil
@@ -118,7 +130,7 @@ func NewDoHLocalNameServer(url *url.URL, queryStrategy QueryStrategy) *DoHNameSe
118
130
Timeout : time .Second * 180 ,
119
131
Transport : tr ,
120
132
}
121
- errors .LogInfo (context .Background (), "DNS: created Local DOH client for " , url .String ())
133
+ errors .LogInfo (context .Background (), "DNS: created Local DNS-over-HTTPS client for " , url .String ())
122
134
return s
123
135
}
124
136
0 commit comments