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:
parent
a832ab696a
commit
90f73c50cf
3 changed files with 40 additions and 5 deletions
|
@ -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() }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue