Avoid unneeded DNS packet unpacking

This commit is contained in:
Frank Denis 2019-12-23 11:37:45 +01:00
parent adb6dac420
commit c27d41faa0
4 changed files with 16 additions and 23 deletions

View file

@ -209,33 +209,25 @@ func updateTTL(msg *dns.Msg, expiration time.Time) {
} }
} }
func addEDNS0PaddingIfNoneFound(packet *[]byte, paddingLen int) *[]byte { func addEDNS0PaddingIfNoneFound(msg *dns.Msg, unpaddedPacket []byte, paddingLen int) ([]byte, error) {
msg := dns.Msg{Compress: true}
if msg.Unpack(*packet) != nil {
return packet
}
edns0 := msg.IsEdns0() edns0 := msg.IsEdns0()
if edns0 == nil { if edns0 == nil {
msg.SetEdns0(uint16(MaxDNSPacketSize), false) msg.SetEdns0(uint16(MaxDNSPacketSize), false)
edns0 = msg.IsEdns0() edns0 = msg.IsEdns0()
if edns0 == nil { if edns0 == nil {
return packet return unpaddedPacket, nil
} }
} }
for _, option := range edns0.Option { for _, option := range edns0.Option {
if option.Option() == dns.EDNS0PADDING { if option.Option() == dns.EDNS0PADDING {
return packet return unpaddedPacket, nil
} }
} }
ext := new(dns.EDNS0_PADDING) ext := new(dns.EDNS0_PADDING)
padding := []byte("dnscrypt-proxy.padding:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno") padding := []byte("dnscrypt-proxy.padding:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno")
ext.Padding = padding[:paddingLen] ext.Padding = padding[:paddingLen]
edns0.Option = append(edns0.Option, ext) edns0.Option = append(edns0.Option, ext)
paddedPacket, err := msg.Pack() return msg.Pack()
if err != nil {
return packet
}
return &paddedPacket
} }
func removeEDNS0Options(msg *dns.Msg) bool { func removeEDNS0Options(msg *dns.Msg) bool {

View file

@ -243,7 +243,7 @@ func NewPluginsState(proxy *Proxy, clientProto string, clientAddr *net.Addr, sta
} }
} }
func (pluginsState *PluginsState) ApplyQueryPlugins(pluginsGlobals *PluginsGlobals, packet []byte, serverName string) ([]byte, error) { func (pluginsState *PluginsState) ApplyQueryPlugins(pluginsGlobals *PluginsGlobals, packet []byte, serverName string, needsEDNS0Padding bool) ([]byte, error) {
pluginsState.serverName = serverName pluginsState.serverName = serverName
msg := dns.Msg{} msg := dns.Msg{}
if err := msg.Unpack(packet); err != nil { if err := msg.Unpack(packet); err != nil {
@ -280,6 +280,12 @@ func (pluginsState *PluginsState) ApplyQueryPlugins(pluginsGlobals *PluginsGloba
if err != nil { if err != nil {
return packet, err return packet, err
} }
if needsEDNS0Padding && pluginsState.action == PluginsActionContinue {
padLen := 63 - (len(packet2)+63)&63
if paddedPacket2, _ := addEDNS0PaddingIfNoneFound(&msg, packet2, padLen); paddedPacket2 != nil {
return paddedPacket2, nil
}
}
return packet2, nil return packet2, nil
} }

View file

@ -435,10 +435,12 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
} }
pluginsState := NewPluginsState(proxy, clientProto, clientAddr, start) pluginsState := NewPluginsState(proxy, clientProto, clientAddr, start)
serverName := "-" serverName := "-"
needsEDNS0Padding := false
if serverInfo != nil { if serverInfo != nil {
serverName = serverInfo.Name serverName = serverInfo.Name
needsEDNS0Padding = (serverInfo.Proto == stamps.StampProtoTypeDoH || serverInfo.Proto == stamps.StampProtoTypeTLS)
} }
query, _ = pluginsState.ApplyQueryPlugins(&proxy.pluginsGlobals, query, serverName) query, _ = pluginsState.ApplyQueryPlugins(&proxy.pluginsGlobals, query, serverName, needsEDNS0Padding)
if len(query) < MinDNSPacketSize || len(query) > MaxDNSPacketSize { if len(query) < MinDNSPacketSize || len(query) > MaxDNSPacketSize {
return return
} }

View file

@ -371,22 +371,15 @@ func (xTransport *XTransport) Post(url *url.URL, accept string, contentType stri
} }
func (xTransport *XTransport) DoHQuery(useGet bool, url *url.URL, body []byte, timeout time.Duration) (*http.Response, time.Duration, error) { func (xTransport *XTransport) DoHQuery(useGet bool, url *url.URL, body []byte, timeout time.Duration) (*http.Response, time.Duration, error) {
padLen := 63 - (len(body)+63)&63
dataType := "application/dns-message" dataType := "application/dns-message"
paddedBody := addEDNS0PaddingIfNoneFound(&body, padLen)
if useGet { if useGet {
qs := url.Query() qs := url.Query()
qs.Add("ct", "") qs.Add("ct", "")
encBody := base64.RawURLEncoding.EncodeToString(*paddedBody) encBody := base64.RawURLEncoding.EncodeToString(body)
qs.Add("dns", encBody) qs.Add("dns", encBody)
url2 := *url url2 := *url
url2.RawQuery = qs.Encode() url2.RawQuery = qs.Encode()
return xTransport.Get(&url2, dataType, timeout) return xTransport.Get(&url2, dataType, timeout)
} }
return xTransport.Post(url, dataType, dataType, paddedBody, timeout) return xTransport.Post(url, dataType, dataType, &body, timeout)
}
func (xTransport *XTransport) makePad(padLen int) *string {
padding := strings.Repeat("X", padLen)
return &padding
} }