Use EDNS0 padding when using DoH over POST

This mechanism is horrible, slow (requires re-unpacking and re-packing
the query), should be done at transport layer and not at content layer, and
of course, it is incompatible with some resolvers.

However, in spite of https://go-review.googlesource.com/c/go/+/114316/2/src/net/http/transfer.go ,
we may still end up sending the header and the content in distinct packets.

So, use that horror for POST queries only. For GET, this is not needed.
This commit is contained in:
Frank Denis 2019-12-22 15:31:02 +01:00
parent 0454463539
commit 1585ede954
2 changed files with 31 additions and 3 deletions

View File

@ -208,3 +208,31 @@ func updateTTL(msg *dns.Msg, expiration time.Time) {
}
}
}
func addPaddingIfNoneFound(packet *[]byte, paddingLen int) *[]byte {
msg := dns.Msg{Compress: true}
if msg.Unpack(*packet) != nil {
return packet
}
edns0 := msg.IsEdns0()
if edns0 == nil {
msg.SetEdns0(uint16(MaxDNSPacketSize), false)
edns0 = msg.IsEdns0()
if edns0 == nil {
return packet
}
}
for _, option := range edns0.Option {
if option.Option() == dns.EDNS0PADDING {
return packet
}
}
ext := new(dns.EDNS0_PADDING)
ext.Padding = make([]byte, paddingLen)
edns0.Option = append(edns0.Option, ext)
paddedPacket, err := msg.Pack()
if err != nil {
return packet
}
return &paddedPacket
}

View File

@ -313,9 +313,6 @@ func (xTransport *XTransport) Fetch(method string, url *url.URL, accept string,
if len(contentType) > 0 {
header["Content-Type"] = []string{contentType}
}
if padding != nil {
header["X-Pad"] = []string{*padding}
}
if body != nil {
h := sha512.Sum512(*body)
qs := url.Query()
@ -323,6 +320,9 @@ func (xTransport *XTransport) Fetch(method string, url *url.URL, accept string,
url2 := *url
url2.RawQuery = qs.Encode()
url = &url2
if padding != nil {
body = addPaddingIfNoneFound(body, len(*padding))
}
}
host, _ := ExtractHostAndPort(url.Host, 0)
if xTransport.proxyDialer == nil && strings.HasSuffix(host, ".onion") {