EDNS Client Subnet is not encoded correctly when source prefix length is not a multiple of 8.

Motivation:
When the ECS source prefix length is not a mutiple of 8, the last byte the address inside the
ECS OPT record is not padded properly.

Modifications:
DefaultDnsRecordEncoder.padWithZeros(...) was modified to add padding from the least
significant bits.

Result:
ECS encoding bug fixed.
This commit is contained in:
Thomas Devanneaux 2017-11-28 10:20:42 -08:00 committed by Norman Maurer
parent 3c8f4b81d7
commit 32746c53c1
2 changed files with 12 additions and 10 deletions

View File

@ -162,25 +162,24 @@ public class DefaultDnsRecordEncoder implements DnsRecordEncoder {
buf.writeByte(0); // marks end of name field
}
// Package private so it can be reused in the test.
static byte padWithZeros(byte b, int lowOrderBitsToPreserve) {
private static byte padWithZeros(byte b, int lowOrderBitsToPreserve) {
switch (lowOrderBitsToPreserve) {
case 0:
return 0;
case 1:
return (byte) (0x01 & b);
return (byte) (0x80 & b);
case 2:
return (byte) (0x03 & b);
return (byte) (0xC0 & b);
case 3:
return (byte) (0x07 & b);
return (byte) (0xE0 & b);
case 4:
return (byte) (0x0F & b);
return (byte) (0xF0 & b);
case 5:
return (byte) (0x1F & b);
return (byte) (0xF8 & b);
case 6:
return (byte) (0x3F & b);
return (byte) (0xFC & b);
case 7:
return (byte) (0x7F & b);
return (byte) (0xFE & b);
case 8:
return b;
default:

View File

@ -71,11 +71,13 @@ public class DefaultDnsRecordEncoderTest {
@Test
public void testOptEcsRecordIpv4() throws Exception {
testOptEcsRecordIp(SocketUtils.addressByName("1.2.3.4"));
testOptEcsRecordIp(SocketUtils.addressByName("1.2.3.255"));
}
@Test
public void testOptEcsRecordIpv6() throws Exception {
testOptEcsRecordIp(SocketUtils.addressByName("::0"));
testOptEcsRecordIp(SocketUtils.addressByName("::FF"));
}
private static void testOptEcsRecordIp(InetAddress address) throws Exception {
@ -95,7 +97,8 @@ public class DefaultDnsRecordEncoderTest {
// Pad the leftover of the last byte with zeros.
int idx = addressPart.writerIndex() - 1;
byte lastByte = addressPart.getByte(idx);
addressPart.setByte(idx, DefaultDnsRecordEncoder.padWithZeros(lastByte, lowOrderBitsToPreserve));
int paddingMask = ~((1 << (8 - lowOrderBitsToPreserve)) - 1);
addressPart.setByte(idx, lastByte & paddingMask);
}
int payloadSize = nextInt(Short.MAX_VALUE);