Do not prefer empty MAC address
Motivation: When comparing MAC addresses searching for the best MAC address, if locally-administered address (e.g., from a Docker container) is compared against an empty MAC address, the empty MAC address will be marked as preferred. In cases this is the only available MAC address, this leaves Netty using a random machine ID instead of using a perfectly valid machine ID from the locally-adminstered address. Modifications: This commit modifies the MAC address logic so that the empty MAC address is not preferred over a locally-administered address. This commit also simplifies the comparison logic here. Result: Empty MAC addresses will not be preferred over locally-administered addresses thus permitting the default machine ID to be the locally-adminstered MAC address if it is the only available MAC address.
This commit is contained in:
parent
661ff2538e
commit
42c0359820
@ -203,7 +203,8 @@ public final class MacAddressUtil {
|
|||||||
/**
|
/**
|
||||||
* @return positive - current is better, 0 - cannot tell from MAC addr, negative - candidate is better.
|
* @return positive - current is better, 0 - cannot tell from MAC addr, negative - candidate is better.
|
||||||
*/
|
*/
|
||||||
private static int compareAddresses(byte[] current, byte[] candidate) {
|
// visible for testing
|
||||||
|
static int compareAddresses(byte[] current, byte[] candidate) {
|
||||||
if (candidate == null || candidate.length < EUI48_MAC_ADDRESS_LENGTH) {
|
if (candidate == null || candidate.length < EUI48_MAC_ADDRESS_LENGTH) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -227,20 +228,23 @@ public final class MacAddressUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prefer globally unique address.
|
// Prefer globally unique address.
|
||||||
if (current.length == 0 || (current[0] & 2) == 0) {
|
if ((candidate[0] & 2) == 0) {
|
||||||
if ((candidate[0] & 2) == 0) {
|
if (current.length != 0 && (current[0] & 2) == 0) {
|
||||||
// Both current and candidate are globally unique addresses.
|
// Both current and candidate are globally unique addresses.
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
// Only candidate is globally unique.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (current.length != 0 && (current[0] & 2) == 0) {
|
||||||
// Only current is globally unique.
|
// Only current is globally unique.
|
||||||
return 1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
// Both current and candidate are non-unique.
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
} else if ((candidate[0] & 2) == 0) {
|
|
||||||
// Only candidate is globally unique.
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
// Both current and candidate are non-unique.
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,10 +17,57 @@ package io.netty.util.internal;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static io.netty.util.internal.EmptyArrays.EMPTY_BYTES;
|
||||||
import static io.netty.util.internal.MacAddressUtil.parseMAC;
|
import static io.netty.util.internal.MacAddressUtil.parseMAC;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class MacAddressUtilTest {
|
public class MacAddressUtilTest {
|
||||||
|
@Test
|
||||||
|
public void testCompareAddresses() {
|
||||||
|
// should not prefer empty address when candidate is not globally unique
|
||||||
|
assertEquals(
|
||||||
|
0,
|
||||||
|
MacAddressUtil.compareAddresses(
|
||||||
|
EMPTY_BYTES,
|
||||||
|
new byte[]{(byte) 0x52, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd}));
|
||||||
|
|
||||||
|
// only candidate is globally unique
|
||||||
|
assertEquals(
|
||||||
|
-1,
|
||||||
|
MacAddressUtil.compareAddresses(
|
||||||
|
EMPTY_BYTES,
|
||||||
|
new byte[]{(byte) 0x50, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd}));
|
||||||
|
|
||||||
|
// only candidate is globally unique
|
||||||
|
assertEquals(
|
||||||
|
-1,
|
||||||
|
MacAddressUtil.compareAddresses(
|
||||||
|
new byte[]{(byte) 0x52, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd},
|
||||||
|
new byte[]{(byte) 0x50, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd}));
|
||||||
|
|
||||||
|
// only current is globally unique
|
||||||
|
assertEquals(
|
||||||
|
1,
|
||||||
|
MacAddressUtil.compareAddresses(
|
||||||
|
new byte[]{(byte) 0x52, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd},
|
||||||
|
EMPTY_BYTES));
|
||||||
|
|
||||||
|
// only current is globally unique
|
||||||
|
assertEquals(
|
||||||
|
1,
|
||||||
|
MacAddressUtil.compareAddresses(
|
||||||
|
new byte[]{(byte) 0x50, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd},
|
||||||
|
new byte[]{(byte) 0x52, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd}));
|
||||||
|
|
||||||
|
// both are globally unique
|
||||||
|
assertEquals(
|
||||||
|
0,
|
||||||
|
MacAddressUtil.compareAddresses(
|
||||||
|
new byte[]{(byte) 0x50, (byte) 0x54, (byte) 0x00, (byte) 0xf9, (byte) 0x32, (byte) 0xbd},
|
||||||
|
new byte[]{(byte) 0x50, (byte) 0x55, (byte) 0x01, (byte) 0xfa, (byte) 0x33, (byte) 0xbe}));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseMacEUI48() {
|
public void testParseMacEUI48() {
|
||||||
assertArrayEquals(new byte[]{0, (byte) 0xaa, 0x11, (byte) 0xbb, 0x22, (byte) 0xcc},
|
assertArrayEquals(new byte[]{0, (byte) 0xaa, 0x11, (byte) 0xbb, 0x22, (byte) 0xcc},
|
||||||
|
Loading…
Reference in New Issue
Block a user