Pad queries to 1472 bytes for implementations with broken padding

Quad9 doesn't return TC when responses are larger than the question;
it doesn't return anything instead :(
This commit is contained in:
Frank Denis 2020-03-25 18:06:02 +01:00
parent dd37eaed7c
commit 81c8d68462
2 changed files with 10 additions and 7 deletions

View File

@ -79,18 +79,20 @@ func (proxy *Proxy) Encrypt(serverInfo *ServerInfo, packet []byte, proto string)
publicKey = &proxy.proxyPublicKey publicKey = &proxy.proxyPublicKey
} }
minQuestionSize := QueryOverhead + len(packet) minQuestionSize := QueryOverhead + len(packet)
if !serverInfo.knownBugs.incorrectPadding { if proto == "udp" {
if proto == "udp" { if serverInfo.knownBugs.incorrectPadding {
minQuestionSize = Max(proxy.questionSizeEstimator.MinQuestionSize(), minQuestionSize) // XXX - Note: Cisco's broken implementation doesn't accept more than 1472 bytes
minQuestionSize = Max(1472, minQuestionSize)
} else { } else {
var xpad [1]byte minQuestionSize = Max(proxy.questionSizeEstimator.MinQuestionSize(), minQuestionSize)
rand.Read(xpad[:])
minQuestionSize += int(xpad[0])
} }
} else {
var xpad [1]byte
rand.Read(xpad[:])
minQuestionSize += int(xpad[0])
} }
paddedLength := Min(MaxDNSUDPPacketSize, (Max(minQuestionSize, QueryOverhead)+1+63) & ^63) paddedLength := Min(MaxDNSUDPPacketSize, (Max(minQuestionSize, QueryOverhead)+1+63) & ^63)
if serverInfo.RelayUDPAddr != nil && proto == "tcp" { if serverInfo.RelayUDPAddr != nil && proto == "tcp" {
// XXX - Note: Cisco's broken implementation doesn't accept more than 1472 bytes
paddedLength = MaxDNSPacketSize paddedLength = MaxDNSPacketSize
} }
if QueryOverhead+len(packet)+1 > paddedLength { if QueryOverhead+len(packet)+1 > paddedLength {

View File

@ -485,6 +485,7 @@ func (proxy *Proxy) processIncomingQuery(clientProto string, serverProto string,
if err == nil && len(response) >= MinDNSPacketSize && response[2]&0x02 == 0x02 { if err == nil && len(response) >= MinDNSPacketSize && response[2]&0x02 == 0x02 {
retryOverTCP = true retryOverTCP = true
} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() { } else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
dlog.Debug("Retry over TCP after UDP timeouts")
retryOverTCP = true retryOverTCP = true
} }
if retryOverTCP { if retryOverTCP {