From d641b6a97a03635a509983d077315fd1f59bf920 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Fri, 21 Mar 2014 12:58:58 +0900 Subject: [PATCH] Use the length of MAC address as the last property to compare to get the best MAC address Motivation: Some operating systems like Windows 7 uses a valid globally unique EUI-64 MAC address for a virtual device (e.g. 00:00:00:00:00:00:00:E0), and because it's usually longer than the legit MAC-48 address, we should not use the length of MAC address when two MAC addresses are of the same quality. Instead, we should compare the INET address of the NICs before comparing the length of the MAC addresses. Modification: Compare the length of MAC addresses as a last resort. Result: Correct MAC address detection in Windows with IPv6 enabled. --- .../io/netty/channel/DefaultChannelId.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/DefaultChannelId.java b/transport/src/main/java/io/netty/channel/DefaultChannelId.java index eadb8b5ef5..8b38bf7b37 100644 --- a/transport/src/main/java/io/netty/channel/DefaultChannelId.java +++ b/transport/src/main/java/io/netty/channel/DefaultChannelId.java @@ -169,15 +169,28 @@ final class DefaultChannelId implements ChannelId { continue; } + boolean replace = false; int res = compareAddresses(bestMacAddr, macAddr); if (res < 0) { + // Found a better MAC address. + replace = true; + } else if (res == 0) { + // Two MAC addresses are of pretty much same quality. + res = compareAddresses(bestInetAddr, inetAddr); + if (res < 0) { + // Found a MAC address with better INET address. + replace = true; + } else if (res == 0) { + // Cannot tell the difference. Choose the longer one. + if (bestMacAddr.length < macAddr.length) { + replace = true; + } + } + } + + if (replace) { bestMacAddr = macAddr; bestInetAddr = inetAddr; - } else if (res == 0) { - if (compareAddresses(bestInetAddr, inetAddr) < 0) { - bestMacAddr = macAddr; - bestInetAddr = inetAddr; - } } } @@ -236,18 +249,22 @@ final class DefaultChannelId implements ChannelId { return 1; } - // Prefer longer globally unique addresses. + // Prefer globally unique address. if ((current[0] & 2) == 0) { if ((candidate[0] & 2) == 0) { - return current.length - candidate.length; + // Both current and candidate are globally unique addresses. + return 0; } else { + // Only current is globally unique. return 1; } } else { if ((candidate[0] & 2) == 0) { + // Only candidate is globally unique. return -1; } else { - return current.length - candidate.length; + // Both current and candidate are non-unique. + return 0; } } }