You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So I was investigating a failed update to a BIND nameserver that returned FORMERR. Looking with the debugger, I've noticed that the generated wire format was > 65535 here.
After more investigation, I think I identified the issue: I am using a resolver with tsig with algorithm HMAC_SHA384, and the calculation that is made in TSIG.recordLength() is wrong. More specifically, it considers a MAC size of 16 bytes. While this is true for MD5, it doesn't work for other algorithms such as HMAC_SHA384, where the hash is greater in length.
This is a small repro (in Kotlin) showing the generated message is higher than the allowed DNS message size of 65535:
importorg.xbill.DNS.DClassimportorg.xbill.DNS.Messageimportorg.xbill.DNS.Nameimportorg.xbill.DNS.SimpleResolverimportorg.xbill.DNS.TSIGimportorg.xbill.DNS.TXTRecordimportorg.xbill.DNS.Updateimportorg.xbill.DNS.io.IoClientFactoryimportorg.xbill.DNS.io.TcpIoClientimportorg.xbill.DNS.io.UdpIoClientimportjava.util.concurrent.CompletableFuturefunmain() {
val update =Update(Name.fromConstantString("zone.example.com."))
repeat(2000) { i ->val record =TXTRecord(
Name.fromConstantString("name-$i.zone.example.com."),
DClass.IN,
900,
"a",
)
update.absent(record.name, record.type)
update.add(record)
}
val resolver =SimpleResolver().apply {
tsigKey =TSIG(TSIG.HMAC_SHA384, "zone.example.com.", "c2VjcmU=")
ioClientFactory =object:IoClientFactory {
overridefuncreateOrGetTcpClient(): TcpIoClient {
returnTcpIoClient { local, remote, query, data, timeout ->println("Sending data of length: ${data.size}")
println("Is data > max message size (${Message.MAXLENGTH})? ${data.size >Message.MAXLENGTH}")
CompletableFuture.failedFuture(Exception())
}
}
overridefuncreateOrGetUdpClient(): UdpIoClient {
TODO("Not yet implemented")
}
}
}
resolver.send(update)
}
This outputs:
Sending data of length: 65544
Is data > max message size (65535)? true
The FORMERR we got is because the data of 65544 bytes exceeds what can be stored in two bytes so this computation rolls over, so the message gets truncated at a random point and cannot be interpreted by the receiver.
I believe an easy fix for this would be to either give more slack in the calculation and put the max of all supported algorithms, or put the correct number based on the algorithm used.
The text was updated successfully, but these errors were encountered:
Uh oh!
There was an error while loading. Please reload this page.
Hello!
So I was investigating a failed update to a BIND nameserver that returned FORMERR. Looking with the debugger, I've noticed that the generated wire format was > 65535 here.
After more investigation, I think I identified the issue: I am using a resolver with tsig with algorithm
HMAC_SHA384
, and the calculation that is made in TSIG.recordLength() is wrong. More specifically, it considers a MAC size of 16 bytes. While this is true for MD5, it doesn't work for other algorithms such asHMAC_SHA384
, where the hash is greater in length.This is a small repro (in Kotlin) showing the generated message is higher than the allowed DNS message size of 65535:
This outputs:
The FORMERR we got is because the data of 65544 bytes exceeds what can be stored in two bytes so this computation rolls over, so the message gets truncated at a random point and cannot be interpreted by the receiver.
I believe an easy fix for this would be to either give more slack in the calculation and put the max of all supported algorithms, or put the correct number based on the algorithm used.
The text was updated successfully, but these errors were encountered: