@@ -124,7 +124,7 @@ func (c *xdnsConnServer) ensureQueue(addr net.Addr) *queue {
124124 q , ok := c .writeQueueMap [addr .String ()]
125125 if ! ok {
126126 q = & queue {
127- queue : make (chan []byte , 512 ),
127+ queue : make (chan []byte , 4096 ),
128128 stash : make (chan []byte , 1 ),
129129 }
130130 c .writeQueueMap [addr .String ()] = q
@@ -225,17 +225,50 @@ func (c *xdnsConnServer) recvLoop() {
225225 }
226226}
227227
228+ func (c * xdnsConnServer ) sendEmptyResponse (rec * record ) {
229+ if rec .Resp .Rcode () == RcodeNoError && len (rec .Resp .Question ) == 1 {
230+ rec .Resp .Answer = []RR {
231+ {
232+ Name : rec .Resp .Question [0 ].Name ,
233+ Type : rec .Resp .Question [0 ].Type ,
234+ Class : rec .Resp .Question [0 ].Class ,
235+ TTL : responseTTL ,
236+ Data : EncodeRDataTXT (nil ),
237+ },
238+ }
239+ }
240+ buf , err := rec .Resp .WireFormat ()
241+ if err != nil {
242+ return
243+ }
244+ if len (buf ) > maxUDPPayload {
245+ buf = buf [:maxUDPPayload ]
246+ buf [2 ] |= 0x02
247+ }
248+ c .PacketConn .WriteTo (buf , rec .Addr )
249+ }
250+
228251func (c * xdnsConnServer ) sendLoop () {
229- var nextRec * record
230252 for {
231- rec := nextRec
232- nextRec = nil
253+ rec , ok := <- c .ch
254+ if ! ok {
255+ break
256+ }
233257
234- if rec == nil {
235- var ok bool
236- rec , ok = <- c .ch
237- if ! ok {
238- break
258+ errors .LogWarning (context .Background (), "xdns sendLoop: got record from " , rec .Addr , " client=" , rec .ClientAddr , " chLen=" , len (c .ch ))
259+
260+ // Drain excess records, keeping the latest. mKCP floods retransmissions
261+ // that fill c.ch with hundreds of queries. Process only the latest one.
262+ drain:
263+ for {
264+ select {
265+ case newer , ok2 := <- c .ch :
266+ if ! ok2 {
267+ break drain
268+ }
269+ rec = newer
270+ default :
271+ break drain
239272 }
240273 }
241274
@@ -252,56 +285,72 @@ func (c *xdnsConnServer) sendLoop() {
252285
253286 var payload bytes.Buffer
254287 limit := maxEncodedPayload
255- timer := time .NewTimer (maxResponseDelay )
256288
257- for {
258- c .mutex .Lock ()
259- q := c .ensureQueue (rec .ClientAddr )
260- if q == nil {
261- c .mutex .Unlock ()
262- return
263- }
289+ c .mutex .Lock ()
290+ q := c .ensureQueue (rec .ClientAddr )
291+ if q == nil {
264292 c .mutex .Unlock ()
265-
266- var p []byte
267-
293+ return
294+ }
295+ c .mutex .Unlock ()
296+
297+ // Try to get data immediately (non-blocking). If no data is
298+ // available, wait briefly (50ms) for data to arrive. This is much
299+ // shorter than the original 1s maxResponseDelay. DNS tunneling needs
300+ // fast turnaround because the client can only receive data in
301+ // responses to its queries.
302+ var p []byte
303+ select {
304+ case p = <- q .stash :
305+ default :
268306 select {
269307 case p = <- q .stash :
308+ case p = <- q .queue :
270309 default :
310+ timer := time .NewTimer (50 * time .Millisecond )
271311 select {
272312 case p = <- q .stash :
313+ timer .Stop ()
273314 case p = <- q .queue :
274- default :
275- select {
276- case p = <- q .stash :
277- case p = <- q .queue :
278- case <- timer .C :
279- case nextRec = <- c .ch :
280- }
315+ timer .Stop ()
316+ case <- timer .C :
281317 }
282318 }
319+ }
283320
284- timer .Reset (0 )
285-
286- if len (p ) == 0 {
287- break
288- }
321+ errors .LogWarning (context .Background (), "xdns sendLoop: data fetch result len=" , len (p ), " qLen=" , len (q .queue ), " stashLen=" , len (q .stash ))
289322
323+ // Pack first packet
324+ if len (p ) > 0 {
290325 limit -= 2 + len (p )
291- if payload .Len () > 0 && limit < 0 {
292- c .stash (q , p )
293- break
294- }
295-
296- // if len(p) > 65535 {
297- // panic(len(p))
298- // }
299-
300326 _ = binary .Write (& payload , binary .BigEndian , uint16 (len (p )))
301327 payload .Write (p )
328+
329+ // Try to batch more packets immediately (non-blocking)
330+ for {
331+ var p2 []byte
332+ select {
333+ case p2 = <- q .stash :
334+ default :
335+ select {
336+ case p2 = <- q .stash :
337+ case p2 = <- q .queue :
338+ default :
339+ }
340+ }
341+ if len (p2 ) == 0 {
342+ break
343+ }
344+ limit -= 2 + len (p2 )
345+ if limit < 0 {
346+ c .stash (q , p2 )
347+ break
348+ }
349+ _ = binary .Write (& payload , binary .BigEndian , uint16 (len (p2 )))
350+ payload .Write (p2 )
351+ }
302352 }
303353
304- timer .Stop ()
305354 rec .Resp .Answer [0 ].Data = EncodeRDataTXT (payload .Bytes ())
306355 }
307356
@@ -363,7 +412,6 @@ func (c *xdnsConnServer) WriteTo(p []byte, addr net.Addr) (n int, err error) {
363412 case q .queue <- buf :
364413 return len (p ), nil
365414 default :
366- // errors.LogDebug(context.Background(), addr, " mask write err queue full")
367415 return 0 , nil
368416 }
369417}
0 commit comments