Skip to content

Commit

Permalink
[ISSUE #8289] Fixed network bugs and merged networkutil code (#8290)
Browse files Browse the repository at this point in the history
* [ISSUE #8289] Fixed network bugs and merged networkutil code
Fix the following three as
1,TraceBean: private static final String LOCAL_ADDRESS = UtilAll.ipToIPv4Str(UtilAll.getIP()); getIP mayby ipv6
2,NetworkUtil:if (ip.startsWith("127.0") || ip.startsWith("192.168") || ip.startsWith("0."));Check whether Intranet errors exist

* [ISSUE #8289] Fixed network bugs and merged networkutil code
Fix the following three as
1,TraceBean: private static final String LOCAL_ADDRESS = UtilAll.ipToIPv4Str(UtilAll.getIP()); getIP mayby ipv6
2,NetworkUtil:if (ip.startsWith("127.0") || ip.startsWith("192.168") || ip.startsWith("0."));Check whether Intranet errors exist
  • Loading branch information
zekai-li authored Aug 15, 2024
1 parent 7964f06 commit aa788e8
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.apache.rocketmq.common.message.MessageType;

public class TraceBean {
private static final String LOCAL_ADDRESS = UtilAll.ipToIPv4Str(UtilAll.getIP());
private static final String LOCAL_ADDRESS;
private String topic = "";
private String msgId = "";
private String offsetMsgId = "";
Expand All @@ -37,6 +37,15 @@ public class TraceBean {
private String transactionId;
private boolean fromTransactionCheck;

static {
byte[] ip = UtilAll.getIP();
if (ip.length == 4) {
LOCAL_ADDRESS = UtilAll.ipToIPv4Str(ip);
} else {
LOCAL_ADDRESS = UtilAll.ipToIPv6Str(ip);
}
}

public MessageType getMsgType() {
return msgType;
}
Expand Down
35 changes: 13 additions & 22 deletions common/src/main/java/org/apache/rocketmq/common/UtilAll.java
Original file line number Diff line number Diff line change
Expand Up @@ -326,16 +326,14 @@ public static String bytes2string(byte[] src) {
}

public static void writeInt(char[] buffer, int pos, int value) {
char[] hexArray = HEX_ARRAY;
for (int moveBits = 28; moveBits >= 0; moveBits -= 4) {
buffer[pos++] = hexArray[(value >>> moveBits) & 0x0F];
buffer[pos++] = HEX_ARRAY[(value >>> moveBits) & 0x0F];
}
}

public static void writeShort(char[] buffer, int pos, int value) {
char[] hexArray = HEX_ARRAY;
for (int moveBits = 12; moveBits >= 0; moveBits -= 4) {
buffer[pos++] = hexArray[(value >>> moveBits) & 0x0F];
buffer[pos++] = HEX_ARRAY[(value >>> moveBits) & 0x0F];
}
}

Expand Down Expand Up @@ -536,25 +534,18 @@ public static boolean isInternalIP(byte[] ip) {
} else if (ip[0] == (byte) 127) {
return true;
} else if (ip[0] == (byte) 172) {
if (ip[1] >= (byte) 16 && ip[1] <= (byte) 31) {
return true;
}
return ip[1] >= (byte) 16 && ip[1] <= (byte) 31;
} else if (ip[0] == (byte) 192) {
if (ip[1] == (byte) 168) {
return true;
}
return ip[1] == (byte) 168;
}
return false;
}

public static boolean isInternalV6IP(InetAddress inetAddr) {
if (inetAddr.isAnyLocalAddress() // Wild card ipv6
return inetAddr.isAnyLocalAddress() // Wild card ipv6
|| inetAddr.isLinkLocalAddress() // Single broadcast ipv6 address: fe80:xx:xx...
|| inetAddr.isLoopbackAddress() //Loopback ipv6 address
|| inetAddr.isSiteLocalAddress()) { // Site local ipv6 address: fec0:xx:xx...
return true;
}
return false;
|| inetAddr.isSiteLocalAddress();// Site local ipv6 address: fec0:xx:xx...
}

private static boolean ipCheck(byte[] ip) {
Expand Down Expand Up @@ -605,15 +596,15 @@ public static String ipToIPv6Str(byte[] ip) {

public static byte[] getIP() {
try {
Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip = null;
Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip;
byte[] internalIP = null;
while (allNetInterfaces.hasMoreElements()) {
NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
Enumeration addresses = netInterface.getInetAddresses();
NetworkInterface netInterface = allNetInterfaces.nextElement();
Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
while (addresses.hasMoreElements()) {
ip = (InetAddress) addresses.nextElement();
if (ip != null && ip instanceof Inet4Address) {
ip = addresses.nextElement();
if (ip instanceof Inet4Address) {
byte[] ipByte = ip.getAddress();
if (ipByte.length == 4) {
if (ipCheck(ipByte)) {
Expand All @@ -624,7 +615,7 @@ public static byte[] getIP() {
}
}
}
} else if (ip != null && ip instanceof Inet6Address) {
} else if (ip instanceof Inet6Address) {
byte[] ipByte = ip.getAddress();
if (ipByte.length == 16) {
if (ipV6Check(ipByte)) {
Expand Down
109 changes: 69 additions & 40 deletions common/src/main/java/org/apache/rocketmq/common/utils/NetworkUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,21 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.commons.validator.routines.InetAddressValidator;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.org.slf4j.Logger;
import org.apache.rocketmq.logging.org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -59,18 +65,14 @@ public static Selector openSelector() throws IOException {
if (isLinuxPlatform()) {
try {
final Class<?> providerClazz = Class.forName("sun.nio.ch.EPollSelectorProvider");
if (providerClazz != null) {
try {
final Method method = providerClazz.getMethod("provider");
if (method != null) {
final SelectorProvider selectorProvider = (SelectorProvider) method.invoke(null);
if (selectorProvider != null) {
result = selectorProvider.openSelector();
}
}
} catch (final Exception e) {
log.warn("Open ePoll Selector for linux platform exception", e);
try {
final Method method = providerClazz.getMethod("provider");
final SelectorProvider selectorProvider = (SelectorProvider) method.invoke(null);
if (selectorProvider != null) {
result = selectorProvider.openSelector();
}
} catch (final Exception e) {
log.warn("Open ePoll Selector for linux platform exception", e);
}
} catch (final Exception e) {
// ignore
Expand All @@ -88,55 +90,83 @@ public static boolean isLinuxPlatform() {
return isLinuxPlatform;
}

public static String getLocalAddress() {
try {
// Traversal Network interface to get the first non-loopback and non-private address
Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
ArrayList<String> ipv4Result = new ArrayList<>();
ArrayList<String> ipv6Result = new ArrayList<>();
while (enumeration.hasMoreElements()) {
final NetworkInterface nif = enumeration.nextElement();
if (isBridge(nif) || nif.isVirtual() || nif.isPointToPoint() || !nif.isUp()) {
continue;
}

final Enumeration<InetAddress> en = nif.getInetAddresses();
while (en.hasMoreElements()) {
final InetAddress address = en.nextElement();
if (!address.isLoopbackAddress()) {
if (address instanceof Inet6Address) {
ipv6Result.add(normalizeHostAddress(address));
} else {
ipv4Result.add(normalizeHostAddress(address));
public static List<InetAddress> getLocalInetAddressList() throws SocketException {
Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
List<InetAddress> inetAddressList = new ArrayList<>();
// Traversal Network interface to get the non-bridge and non-virtual and non-ppp and up address
while (enumeration.hasMoreElements()) {
final NetworkInterface nif = enumeration.nextElement();
if (isBridge(nif) || nif.isVirtual() || nif.isPointToPoint() || !nif.isUp()) {
continue;
}
InetAddressValidator validator = InetAddressValidator.getInstance();
final Enumeration<InetAddress> en = nif.getInetAddresses();
while (en.hasMoreElements()) {
final InetAddress address = en.nextElement();
if (address instanceof Inet4Address) {
byte[] ipByte = address.getAddress();
if (ipByte.length == 4) {
if (validator.isValidInet4Address(UtilAll.ipToIPv4Str(ipByte))) {
inetAddressList.add(address);
}
}
} else if (address instanceof Inet6Address) {
byte[] ipByte = address.getAddress();
if (ipByte.length == 16) {
if (validator.isValidInet6Address(UtilAll.ipToIPv6Str(ipByte))) {
inetAddressList.add(address);
}
}
}
}
}
return inetAddressList;
}

// prefer ipv4
public static InetAddress getLocalInetAddress() {
try {
ArrayList<InetAddress> ipv4Result = new ArrayList<>();
ArrayList<InetAddress> ipv6Result = new ArrayList<>();
List<InetAddress> localInetAddressList = getLocalInetAddressList();
for (InetAddress inetAddress : localInetAddressList) {
if (inetAddress instanceof Inet6Address) {
ipv6Result.add(inetAddress);
} else {
ipv4Result.add(inetAddress);
}
}
// prefer ipv4 and prefer external ip
if (!ipv4Result.isEmpty()) {
for (String ip : ipv4Result) {
if (ip.startsWith("127.0") || ip.startsWith("192.168") || ip.startsWith("0.")) {
for (InetAddress ip : ipv4Result) {
if (UtilAll.isInternalIP(ip.getAddress())) {
continue;
}

return ip;
}

return ipv4Result.get(ipv4Result.size() - 1);
} else if (!ipv6Result.isEmpty()) {
for (InetAddress ip : ipv6Result) {
if (UtilAll.isInternalV6IP(ip)) {
continue;
}
return ip;
}
return ipv6Result.get(0);
}
//If failed to find,fall back to localhost
final InetAddress localHost = InetAddress.getLocalHost();
return normalizeHostAddress(localHost);
return InetAddress.getLocalHost();
} catch (Exception e) {
log.error("Failed to obtain local address", e);
}

return null;
}

public static String getLocalAddress() {
InetAddress localHost = getLocalInetAddress();
return normalizeHostAddress(localHost);
}

public static String normalizeHostAddress(final InetAddress localHost) {
if (localHost instanceof Inet6Address) {
return "[" + localHost.getHostAddress() + "]";
Expand All @@ -149,8 +179,7 @@ public static SocketAddress string2SocketAddress(final String addr) {
int split = addr.lastIndexOf(":");
String host = addr.substring(0, split);
String port = addr.substring(split + 1);
InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port));
return isa;
return new InetSocketAddress(host, Integer.parseInt(port));
}

public static String socketAddress2String(final SocketAddress addr) {
Expand Down

0 comments on commit aa788e8

Please sign in to comment.