mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-10-10 04:03:11 +08:00
fix: truncate udp dns replies to the client's advertised buffer size (#3043)
This commit is contained in:
@@ -17,6 +17,15 @@ const DefaultDnsRelayTimeout = time.Second * 5
|
||||
|
||||
const SafeDnsPacketSize = 2 * 1024 // safe size which is 1232 from https://dnsflagday.net/2020/, so 2048 is enough
|
||||
|
||||
// RequestUDPSize returns the UDP payload size a reply to msg may occupy:
|
||||
// the client's advertised EDNS0 buffer size, or 512 (D.MinMsgSize) without an OPT record.
|
||||
func RequestUDPSize(msg *D.Msg) int {
|
||||
if opt := msg.IsEdns0(); opt != nil {
|
||||
return int(opt.UDPSize())
|
||||
}
|
||||
return D.MinMsgSize
|
||||
}
|
||||
|
||||
func RelayDnsConn(ctx context.Context, conn net.Conn, readTimeout time.Duration) error {
|
||||
buff := pool.Get(pool.UDPBufferSize)
|
||||
defer func() {
|
||||
@@ -90,7 +99,10 @@ func relayDnsPacket(ctx context.Context, payload []byte, target []byte, maxSize
|
||||
}
|
||||
|
||||
r.SetRcode(msg, r.Rcode)
|
||||
if maxSize > 0 {
|
||||
if maxSize > 0 { // udp
|
||||
if size := RequestUDPSize(msg); size < maxSize {
|
||||
maxSize = size
|
||||
}
|
||||
r.Truncate(maxSize)
|
||||
}
|
||||
r.Compress = true
|
||||
|
||||
@@ -35,6 +35,11 @@ func (s *Server) ServeDNS(w D.ResponseWriter, r *D.Msg) {
|
||||
w.WriteMsg(m)
|
||||
return
|
||||
}
|
||||
if _, isUDP := w.RemoteAddr().(*net.UDPAddr); isUDP {
|
||||
// RFC 6891: fit the reply into the client's advertised buffer size,
|
||||
// setting the TC bit if records must be dropped; 512 when no OPT present
|
||||
msg.Truncate(resolver.RequestUDPSize(r))
|
||||
}
|
||||
msg.Compress = true
|
||||
w.WriteMsg(msg)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user