@@ -9,7 +9,10 @@ import (
99 go_errors "errors"
1010 "io"
1111 "net"
12+ "strconv"
13+ "strings"
1214 "sync"
15+ "sync/atomic"
1316 "time"
1417
1518 "github.com/xtls/xray-core/common"
@@ -34,10 +37,14 @@ type packet struct {
3437}
3538
3639type xdnsConnClient struct {
37- net.PacketConn
40+ conn net.PacketConn
41+ resolverConns []net.PacketConn
42+ resolverAddrs []* net.UDPAddr
43+ resolverIdx uint32
44+ resolverSend []atomic.Uint32
3845
3946 clientID []byte
40- domain Name
47+ domains [] Name
4148
4249 pollChan chan struct {}
4350 readQueue chan * packet
@@ -48,16 +55,66 @@ type xdnsConnClient struct {
4855}
4956
5057func NewConnClient (c * Config , raw net.PacketConn ) (net.PacketConn , error ) {
51- domain , err := ParseName (c .Domain )
52- if err != nil {
53- return nil , err
58+ if len (c .Resolvers ) == 0 {
59+ return nil , errors .New ("empty resolvers" )
60+ }
61+
62+ var domains []Name
63+ var servers []string
64+ for _ , rs := range c .Resolvers {
65+ parts := strings .Split (rs , "+udp://" )
66+ if len (parts ) != 2 {
67+ return nil , errors .New ("invalid resolvers" )
68+ }
69+ domain , err := ParseName (parts [0 ])
70+ if err != nil {
71+ return nil , err
72+ }
73+ domains = append (domains , domain )
74+ servers = append (servers , parts [1 ])
75+ }
76+
77+ var resolverConns []net.PacketConn
78+ var resolverAddrs []* net.UDPAddr
79+ var resolverSend []atomic.Uint32
80+ for _ , rs := range servers {
81+ h , p , err := net .SplitHostPort (rs )
82+ if err != nil {
83+ return nil , err
84+ }
85+ ip := net .ParseIP (h )
86+ if ip == nil {
87+ return nil , errors .New ("invalid ip address" )
88+ }
89+ port , _ := strconv .Atoi (p )
90+ if port == 0 {
91+ return nil , errors .New ("invalid port" )
92+ }
93+ var uc net.PacketConn
94+ if ip .To4 () != nil {
95+ uc , err = net .ListenPacket ("udp4" , ":0" )
96+ } else {
97+ uc , err = net .ListenPacket ("udp6" , ":0" )
98+ }
99+ if err != nil {
100+ for _ , rc := range resolverConns {
101+ rc .Close ()
102+ }
103+ return nil , errors .New ("failed to create resolver socket: " , err )
104+ }
105+ resolverConns = append (resolverConns , uc )
106+ resolverAddrs = append (resolverAddrs , & net.UDPAddr {IP : ip , Port : port })
54107 }
108+ resolverSend = make ([]atomic.Uint32 , len (resolverConns ))
55109
56110 conn := & xdnsConnClient {
57- PacketConn : raw ,
111+ conn : raw ,
112+ resolverConns : resolverConns ,
113+ resolverAddrs : resolverAddrs ,
114+ resolverSend : resolverSend ,
58115
59116 clientID : make ([]byte , 8 ),
60- domain : domain ,
117+ domains : domains ,
61118
62119 pollChan : make (chan struct {}, pollLimit ),
63120 readQueue : make (chan * packet , 256 ),
@@ -73,58 +130,70 @@ func NewConnClient(c *Config, raw net.PacketConn) (net.PacketConn, error) {
73130}
74131
75132func (c * xdnsConnClient ) recvLoop () {
76- var buf [finalmask .UDPSize ]byte
77-
78- for {
79- if c .closed {
80- break
81- }
82-
83- n , addr , err := c .PacketConn .ReadFrom (buf [:])
84- if err != nil || n == 0 {
85- if go_errors .Is (err , net .ErrClosed ) || go_errors .Is (err , io .EOF ) {
86- break
87- }
88- continue
89- }
90-
91- resp , err := MessageFromWireFormat (buf [:n ])
92- if err != nil {
93- errors .LogDebug (context .Background (), addr , " xdns from wireformat err " , err )
94- continue
95- }
96-
97- payload := dnsResponsePayload (& resp , c .domain )
98-
99- r := bytes .NewReader (payload )
100- anyPacket := false
101- for {
102- p , err := nextPacket (r )
103- if err != nil {
104- break
133+ var wg sync.WaitGroup
134+
135+ for i , rc := range c .resolverConns {
136+ wg .Add (1 )
137+ go func () {
138+ defer wg .Done ()
139+
140+ var buf [finalmask .UDPSize ]byte
141+
142+ for {
143+ if c .closed {
144+ break
145+ }
146+
147+ n , addr , err := rc .ReadFrom (buf [:])
148+ if err != nil {
149+ if go_errors .Is (err , net .ErrClosed ) {
150+ break
151+ }
152+ continue
153+ }
154+
155+ resp , err := MessageFromWireFormat (buf [:n ])
156+ if err != nil {
157+ errors .LogDebug (context .Background (), addr , " xdns from wireformat err " , err )
158+ continue
159+ }
160+
161+ payload := dnsResponsePayload (& resp , c .domains )
162+
163+ r := bytes .NewReader (payload )
164+ anyPacket := false
165+ for {
166+ p , err := nextPacket (r )
167+ if err != nil {
168+ break
169+ }
170+ anyPacket = true
171+
172+ buf := make ([]byte , len (p ))
173+ copy (buf , p )
174+ select {
175+ case c .readQueue <- & packet {
176+ p : buf ,
177+ addr : addr ,
178+ }:
179+ default :
180+ errors .LogDebug (context .Background (), addr , " mask read err queue full" )
181+ }
182+ }
183+
184+ if anyPacket {
185+ c .resolverSend [i ].Store (0 )
186+ select {
187+ case c .pollChan <- struct {}{}:
188+ default :
189+ }
190+ }
105191 }
106- anyPacket = true
107-
108- buf := make ([]byte , len (p ))
109- copy (buf , p )
110- select {
111- case c .readQueue <- & packet {
112- p : buf ,
113- addr : addr ,
114- }:
115- default :
116- errors .LogDebug (context .Background (), addr , " mask read err queue full" )
117- }
118- }
119-
120- if anyPacket {
121- select {
122- case c .pollChan <- struct {}{}:
123- default :
124- }
125- }
192+ }()
126193 }
127194
195+ wg .Wait ()
196+
128197 errors .LogDebug (context .Background (), "xdns closed" )
129198
130199 close (c .pollChan )
@@ -138,8 +207,6 @@ func (c *xdnsConnClient) recvLoop() {
138207}
139208
140209func (c * xdnsConnClient ) sendLoop () {
141- var addr net.Addr
142-
143210 pollDelay := initPollDelay
144211 pollTimer := time .NewTimer (pollDelay )
145212 for {
@@ -158,17 +225,14 @@ func (c *xdnsConnClient) sendLoop() {
158225 }
159226
160227 if p != nil {
161- addr = p .addr
162-
163228 select {
164229 case <- c .pollChan :
165230 default :
166231 }
167- } else if addr != nil {
168- encoded , _ := encode (nil , c .clientID , c .domain )
232+ } else {
233+ encoded , _ := encode (nil , c .clientID , c .domains [ c . resolverIdx ] )
169234 p = & packet {
170- p : encoded ,
171- addr : addr ,
235+ p : encoded ,
172236 }
173237 }
174238
@@ -189,10 +253,16 @@ func (c *xdnsConnClient) sendLoop() {
189253 return
190254 }
191255
192- if p != nil {
193- _ , err := c .PacketConn .WriteTo (p .p , p .addr )
194- if go_errors .Is (err , net .ErrClosed ) || go_errors .Is (err , io .ErrClosedPipe ) {
195- c .closed = true
256+ cur := c .resolverIdx
257+ curSend := c .resolverSend [c .resolverIdx ].Add (1 )
258+ _ , _ = c .resolverConns [c .resolverIdx ].WriteTo (p .p , c .resolverAddrs [c .resolverIdx ])
259+ for {
260+ c .resolverIdx += 1
261+ c .resolverIdx %= uint32 (len (c .resolverConns ))
262+ if c .resolverIdx == cur {
263+ break
264+ }
265+ if c .resolverSend [c .resolverIdx ].Load () < curSend {
196266 break
197267 }
198268 }
@@ -220,7 +290,7 @@ func (c *xdnsConnClient) WriteTo(p []byte, addr net.Addr) (n int, err error) {
220290 return 0 , io .ErrClosedPipe
221291 }
222292
223- encoded , err := encode (p , c .clientID , c .domain )
293+ encoded , err := encode (p , c .clientID , c .domains [ c . resolverIdx % uint32 ( len ( c . resolverConns ))] )
224294 if err != nil {
225295 errors .LogDebug (context .Background (), addr , " xdns wireformat err " , err , " " , len (p ))
226296 return 0 , nil
@@ -240,7 +310,35 @@ func (c *xdnsConnClient) WriteTo(p []byte, addr net.Addr) (n int, err error) {
240310
241311func (c * xdnsConnClient ) Close () error {
242312 c .closed = true
243- return c .PacketConn .Close ()
313+ for _ , rc := range c .resolverConns {
314+ rc .Close ()
315+ }
316+ return c .conn .Close ()
317+ }
318+
319+ func (c * xdnsConnClient ) LocalAddr () net.Addr {
320+ return c .conn .LocalAddr ()
321+ }
322+
323+ func (c * xdnsConnClient ) SetDeadline (t time.Time ) error {
324+ for _ , rc := range c .resolverConns {
325+ rc .SetDeadline (t )
326+ }
327+ return c .conn .SetDeadline (t )
328+ }
329+
330+ func (c * xdnsConnClient ) SetReadDeadline (t time.Time ) error {
331+ for _ , rc := range c .resolverConns {
332+ rc .SetReadDeadline (t )
333+ }
334+ return c .conn .SetReadDeadline (t )
335+ }
336+
337+ func (c * xdnsConnClient ) SetWriteDeadline (t time.Time ) error {
338+ for _ , rc := range c .resolverConns {
339+ rc .SetWriteDeadline (t )
340+ }
341+ return c .conn .SetWriteDeadline (t )
244342}
245343
246344func encode (p []byte , clientID []byte , domain Name ) ([]byte , error ) {
@@ -332,7 +430,7 @@ func nextPacket(r *bytes.Reader) ([]byte, error) {
332430 return p , err
333431}
334432
335- func dnsResponsePayload (resp * Message , domain Name ) []byte {
433+ func dnsResponsePayload (resp * Message , domains [] Name ) []byte {
336434 if resp .Flags & 0x8000 != 0x8000 {
337435 return nil
338436 }
@@ -345,7 +443,13 @@ func dnsResponsePayload(resp *Message, domain Name) []byte {
345443 }
346444 answer := resp .Answer [0 ]
347445
348- _ , ok := answer .Name .TrimSuffix (domain )
446+ var ok bool
447+ for _ , domain := range domains {
448+ _ , ok = answer .Name .TrimSuffix (domain )
449+ if ok {
450+ break
451+ }
452+ }
349453 if ! ok {
350454 return nil
351455 }
0 commit comments