Commit 90f73c50 authored by Miek Gieben's avatar Miek Gieben

Add Scrub function

This function will make the message fit for the client's buffer, or
set the TC bit.
parent a832ab69
......@@ -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() }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment