mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 18:53:13 -05:00 
			
		
		
		
	Merge pull request #47 from miekg/edns0-client-bufsize
Add Scrub function
This commit is contained in:
		@@ -72,7 +72,7 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m = dedup(m)
 | 
			
		||||
 | 
			
		||||
	m, _ = state.Scrub(m)
 | 
			
		||||
	state.W.WriteMsg(m)
 | 
			
		||||
	return 0, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package proxy
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/miekg/coredns/middleware"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -18,7 +19,7 @@ func (p ReverseProxy) ServeDNS(w dns.ResponseWriter, r *dns.Msg, extra []dns.RR)
 | 
			
		||||
	)
 | 
			
		||||
	state := middleware.State{W: w, Req: r}
 | 
			
		||||
 | 
			
		||||
	// tls+tcp ?
 | 
			
		||||
	// We forward the original request, no need to fiddle with EDNS0 opt sizes.
 | 
			
		||||
	if state.Proto() == "tcp" {
 | 
			
		||||
		reply, err = middleware.Exchange(p.Client.TCP, r, p.Host)
 | 
			
		||||
	} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -102,9 +102,9 @@ func (s State) Size() int {
 | 
			
		||||
	return dns.MinMsgSize
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SizeAndDo returns a ready made OPT record that the reflects the intent
 | 
			
		||||
// from the state. This can be added to upstream requests that will then
 | 
			
		||||
// hopefully return a message that is understandable by the original client.
 | 
			
		||||
// SizeAndDo returns a ready made OPT record that the reflects the intent from
 | 
			
		||||
// state. This can be added to upstream requests that will then hopefully
 | 
			
		||||
// return a message that is fits the buffer in the client.
 | 
			
		||||
func (s State) SizeAndDo() *dns.OPT {
 | 
			
		||||
	size := s.Size()
 | 
			
		||||
	Do := s.Do()
 | 
			
		||||
@@ -119,6 +119,40 @@ func (s State) SizeAndDo() *dns.OPT {
 | 
			
		||||
	return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Result is the result of Fit.
 | 
			
		||||
type Result int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// ScrubIgnored is returned when Scrub did nothing to the message.
 | 
			
		||||
	ScrubIgnored Result = iota
 | 
			
		||||
	// ScrubDone is returned when the reply has been scrubbed.
 | 
			
		||||
	ScrubDone
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Scrub scrubs the reply message so that it will fit the client's buffer. If even after dropping
 | 
			
		||||
// the additional section, it still does not fit the TC bit will be set on the message. Note,
 | 
			
		||||
// the TC bit will be set regardless of protocol, even TCP message will get the bit, the client
 | 
			
		||||
// should then retry with pigeons.
 | 
			
		||||
// TODO(referral).
 | 
			
		||||
func (s State) Scrub(reply *dns.Msg) (*dns.Msg, Result) {
 | 
			
		||||
	size := s.Size()
 | 
			
		||||
	l := reply.Len()
 | 
			
		||||
	if size >= l {
 | 
			
		||||
		return reply, ScrubIgnored
 | 
			
		||||
	}
 | 
			
		||||
	// If not delegation, drop additional section.
 | 
			
		||||
	// TODO(miek): check for delegation
 | 
			
		||||
	reply.Extra = nil
 | 
			
		||||
	l = reply.Len()
 | 
			
		||||
	if size >= l {
 | 
			
		||||
		return reply, ScrubDone
 | 
			
		||||
	}
 | 
			
		||||
	// Still?!! does not fit.
 | 
			
		||||
	reply.Truncated = true
 | 
			
		||||
	return reply, ScrubDone
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Type returns the type of the question as a string.
 | 
			
		||||
func (s State) Type() string { return dns.Type(s.Req.Question[0].Qtype).String() }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user