@@ -16,7 +16,8 @@ import (
1616)
1717
1818type localDNSRequest struct {
19- packet []byte
19+ buffer []byte
20+ size int
2021 addr * net.UDPAddr
2122}
2223
@@ -44,12 +45,18 @@ func (c *Client) RunLocalDNSListener(ctx context.Context) error {
4445 )
4546
4647 queue := make (chan localDNSRequest , c .cfg .LocalDNSQueueSize )
48+ packetPool := sync.Pool {
49+ New : func () any {
50+ return make ([]byte , EDnsSafeUDPSize )
51+ },
52+ }
53+
4754 var workerWG sync.WaitGroup
4855 for range c .cfg .LocalDNSWorkers {
4956 workerWG .Add (1 )
5057 go func () {
5158 defer workerWG .Done ()
52- c .localDNSWorker (ctx , conn , queue )
59+ c .localDNSWorker (ctx , conn , queue , & packetPool )
5360 }()
5461 }
5562
@@ -59,28 +66,30 @@ func (c *Client) RunLocalDNSListener(ctx context.Context) error {
5966 }()
6067 go c .runLocalDNSCacheFlushLoop (ctx )
6168
62- buffer := make ([]byte , EDnsSafeUDPSize )
6369 for {
70+ buffer := packetPool .Get ().([]byte )
6471 n , addr , err := conn .ReadFromUDP (buffer )
6572 if err != nil {
73+ packetPool .Put (buffer )
6674 if ctx .Err () != nil {
6775 break
6876 }
6977 return err
7078 }
7179
72- packet := append ([]byte (nil ), buffer [:n ]... )
7380 select {
74- case queue <- localDNSRequest {packet : packet , addr : addr }:
81+ case queue <- localDNSRequest {buffer : buffer , size : n , addr : addr }:
7582 case <- ctx .Done ():
83+ packetPool .Put (buffer )
7684 close (queue )
7785 workerWG .Wait ()
7886 return nil
7987 default :
80- response , _ := DnsParser .BuildServerFailureResponse (packet )
88+ response , _ := DnsParser .BuildServerFailureResponse (buffer [: n ] )
8189 if len (response ) != 0 {
8290 _ , _ = conn .WriteToUDP (response , addr )
8391 }
92+ packetPool .Put (buffer )
8493 }
8594 }
8695
@@ -89,7 +98,7 @@ func (c *Client) RunLocalDNSListener(ctx context.Context) error {
8998 return nil
9099}
91100
92- func (c * Client ) localDNSWorker (ctx context.Context , conn * net.UDPConn , queue <- chan localDNSRequest ) {
101+ func (c * Client ) localDNSWorker (ctx context.Context , conn * net.UDPConn , queue <- chan localDNSRequest , packetPool * sync. Pool ) {
93102 for {
94103 select {
95104 case <- ctx .Done ():
@@ -100,11 +109,18 @@ func (c *Client) localDNSWorker(ctx context.Context, conn *net.UDPConn, queue <-
100109 }
101110 func () {
102111 defer func () {
103- if recover () != nil {
104- return
112+ if packetPool != nil && req .buffer != nil {
113+ packetPool .Put (req .buffer )
114+ }
115+ if recovered := recover (); recovered != nil && c != nil && c .log != nil {
116+ c .log .Errorf (
117+ "💥 <red>Local DNS Handler Panic Recovered</red> <magenta>|</magenta> <yellow>%v</yellow>" ,
118+ recovered ,
119+ )
105120 }
106121 }()
107- response , _ := c .handleDNSQueryPacket (req .packet )
122+
123+ response , _ := c .handleDNSQueryPacket (req .buffer [:req .size ])
108124 if len (response ) != 0 {
109125 _ , _ = conn .WriteToUDP (response , req .addr )
110126 }
0 commit comments