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 {
msg := dns.Msg{Compress: true}
if msg.Unpack(*packet) != nil {
return packet
}
func addEDNS0PaddingIfNoneFound(msg *dns.Msg, unpaddedPacket []byte, paddingLen int) ([]byte, error) {
edns0 := msg.IsEdns0()
if edns0 == nil {
msg.SetEdns0(uint16(MaxDNSPacketSize), false)
edns0 = msg.IsEdns0()
if edns0 == nil {
return packet
return unpaddedPacket, nil
}
}
for _, option := range edns0.Option {
if option.Option() == dns.EDNS0PADDING {
return packet
return unpaddedPacket, nil
}
}
ext := new(dns.EDNS0_PADDING)
padding := []byte("dnscrypt-proxy.padding:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno")
ext.Padding = padding[:paddingLen]
edns0.Option = append(edns0.Option, ext)
paddedPacket, err := msg.Pack()
if err != nil {
return packet
}
return &paddedPacket
return msg.Pack()
}
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
msg := dns.Msg{}
if err := msg.Unpack(packet); err != nil {
@ -280,6 +280,12 @@ func (pluginsState *PluginsState) ApplyQueryPlugins(pluginsGlobals *PluginsGloba
if err != nil {
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
}

View File

@ -435,10 +435,12 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
}
pluginsState := NewPluginsState(proxy, clientProto, clientAddr, start)
serverName := "-"
needsEDNS0Padding := false
if serverInfo != nil {
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 {
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) {
padLen := 63 - (len(body)+63)&63
dataType := "application/dns-message"
paddedBody := addEDNS0PaddingIfNoneFound(&body, padLen)
if useGet {
qs := url.Query()
qs.Add("ct", "")
encBody := base64.RawURLEncoding.EncodeToString(*paddedBody)
encBody := base64.RawURLEncoding.EncodeToString(body)
qs.Add("dns", encBody)
url2 := *url
url2.RawQuery = qs.Encode()
return xTransport.Get(&url2, dataType, timeout)
}
return xTransport.Post(url, dataType, dataType, paddedBody, timeout)
}
func (xTransport *XTransport) makePad(padLen int) *string {
padding := strings.Repeat("X", padLen)
return &padding
return xTransport.Post(url, dataType, dataType, &body, timeout)
}