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 = dedup(m)
 | 
				
			||||||
 | 
						m, _ = state.Scrub(m)
 | 
				
			||||||
	state.W.WriteMsg(m)
 | 
						state.W.WriteMsg(m)
 | 
				
			||||||
	return 0, nil
 | 
						return 0, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package proxy
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/miekg/coredns/middleware"
 | 
						"github.com/miekg/coredns/middleware"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/miekg/dns"
 | 
						"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}
 | 
						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" {
 | 
						if state.Proto() == "tcp" {
 | 
				
			||||||
		reply, err = middleware.Exchange(p.Client.TCP, r, p.Host)
 | 
							reply, err = middleware.Exchange(p.Client.TCP, r, p.Host)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,9 +102,9 @@ func (s State) Size() int {
 | 
				
			|||||||
	return dns.MinMsgSize
 | 
						return dns.MinMsgSize
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SizeAndDo returns a ready made OPT record that the reflects the intent
 | 
					// SizeAndDo returns a ready made OPT record that the reflects the intent from
 | 
				
			||||||
// from the state. This can be added to upstream requests that will then
 | 
					// state. This can be added to upstream requests that will then hopefully
 | 
				
			||||||
// hopefully return a message that is understandable by the original client.
 | 
					// return a message that is fits the buffer in the client.
 | 
				
			||||||
func (s State) SizeAndDo() *dns.OPT {
 | 
					func (s State) SizeAndDo() *dns.OPT {
 | 
				
			||||||
	size := s.Size()
 | 
						size := s.Size()
 | 
				
			||||||
	Do := s.Do()
 | 
						Do := s.Do()
 | 
				
			||||||
@@ -119,6 +119,40 @@ func (s State) SizeAndDo() *dns.OPT {
 | 
				
			|||||||
	return o
 | 
						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.
 | 
					// Type returns the type of the question as a string.
 | 
				
			||||||
func (s State) Type() string { return dns.Type(s.Req.Question[0].Qtype).String() }
 | 
					func (s State) Type() string { return dns.Type(s.Req.Question[0].Qtype).String() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user