mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	Add Scrub function
This function will make the message fit for the client's buffer, or set the TC bit.
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