All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.dubbo.common.utils.NetUtils Maven / Gradle / Ivy

/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.dubbo.common.utils;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Pattern;

import com.alibaba.dubbo.common.URL;

import lombok.extern.slf4j.Slf4j;

/**
 * IP and Port Helper for RPC,
 * 
 * @author shawn.qianx
 */
@Slf4j
public class NetUtils {

	public static final String LOCALHOST = "127.0.0.1";

	public static final String ANYHOST = "0.0.0.0";

	private static final int RND_PORT_START = 30000;

	private static final int RND_PORT_RANGE = 10000;

	private static final Random RANDOM = new Random(System.currentTimeMillis());

	public static int getRandomPort() {
		return RND_PORT_START + RANDOM.nextInt(RND_PORT_RANGE);
	}

	public static int getAvailablePort() {
		ServerSocket ss = null;
		try {
			ss = new ServerSocket();
			ss.bind(null);
			return ss.getLocalPort();
		} catch (IOException e) {
			return getRandomPort();
		} finally {
			if (ss != null) {
				try {
					ss.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static int getAvailablePort(int port) {
		if (port <= 0) {
			return getAvailablePort();
		}
		for (int i = port; i < MAX_PORT; i++) {
			ServerSocket ss = null;
			try {
				ss = new ServerSocket(i);
				return i;
			} catch (IOException e) {
				// continue
			} finally {
				if (ss != null) {
					try {
						ss.close();
					} catch (IOException e) {
					}
				}
			}
		}
		return port;
	}

	private static final int MIN_PORT = 0;

	private static final int MAX_PORT = 65535;

	public static boolean isInvalidPort(int port) {
		return port <= MIN_PORT || port > MAX_PORT;
	}

	private static final Pattern ADDRESS_PATTERN = Pattern.compile("^\\d{1,3}(\\.\\d{1,3}){3}\\:\\d{1,5}$");

	public static boolean isValidAddress(String address) {
		return ADDRESS_PATTERN.matcher(address).matches();
	}

	private static final Pattern LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$");

	public static boolean isLocalHost(String host) {
		return host != null && (LOCAL_IP_PATTERN.matcher(host).matches() || host.equalsIgnoreCase("localhost"));
	}

	public static boolean isAnyHost(String host) {
		return "0.0.0.0".equals(host);
	}

	public static boolean isInvalidLocalHost(String host) {
		return host == null || host.length() == 0 || host.equalsIgnoreCase("localhost") || host.equals("0.0.0.0")
				|| (LOCAL_IP_PATTERN.matcher(host).matches());
	}

	public static boolean isValidLocalHost(String host) {
		return !isInvalidLocalHost(host);
	}

	public static InetSocketAddress getLocalSocketAddress(String host, int port) {
		return isInvalidLocalHost(host) ? new InetSocketAddress(port) : new InetSocketAddress(host, port);
	}

	private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");

	private static boolean isValidAddress(InetAddress address) {
		if (address == null || address.isLoopbackAddress())
			return false;
		String name = address.getHostAddress();
		return (name != null && !ANYHOST.equals(name) && !LOCALHOST.equals(name) && IP_PATTERN.matcher(name).matches());
	}

	public static String getLocalHost() {
		InetAddress address = getLocalAddress();
		return address == null ? LOCALHOST : address.getHostAddress();
	}

	public static String filterLocalHost(String host) {
		if (host == null || host.length() == 0) {
			return host;
		}
		if (host.contains("://")) {
			URL u = URL.valueOf(host);
			if (NetUtils.isInvalidLocalHost(u.getHost())) {
				return u.setHost(NetUtils.getLocalHost()).toFullString();
			}
		} else if (host.contains(":")) {
			int i = host.lastIndexOf(':');
			if (NetUtils.isInvalidLocalHost(host.substring(0, i))) {
				return NetUtils.getLocalHost() + host.substring(i);
			}
		} else {
			if (NetUtils.isInvalidLocalHost(host)) {
				return NetUtils.getLocalHost();
			}
		}
		return host;
	}

	private static volatile InetAddress LOCAL_ADDRESS = null;

	/**
	 * 遍历本地网卡,返回第一个合理的IP。
	 * 
	 * @return 本地网卡IP
	 */
	public static InetAddress getLocalAddress() {
		if (LOCAL_ADDRESS != null)
			return LOCAL_ADDRESS;
		InetAddress localAddress = getLocalAddress0();
		LOCAL_ADDRESS = localAddress;
		return localAddress;
	}

	public static String getLogHost() {
		InetAddress address = LOCAL_ADDRESS;
		return address == null ? LOCALHOST : address.getHostAddress();
	}

	private static InetAddress getLocalAddress0() {
		InetAddress localAddress = null;
		try {
			localAddress = InetAddress.getLocalHost();
			if (isValidAddress(localAddress)) {
				return localAddress;
			}
		} catch (Throwable e) {
			log.warn("Failed to retriving ip address, " + e.getMessage(), e);
		}
		try {
			Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
			if (interfaces != null) {
				while (interfaces.hasMoreElements()) {
					try {
						NetworkInterface network = interfaces.nextElement();
						Enumeration addresses = network.getInetAddresses();
						if (addresses != null) {
							while (addresses.hasMoreElements()) {
								try {
									InetAddress address = addresses.nextElement();
									if (isValidAddress(address)) {
										return address;
									}
								} catch (Throwable e) {
									log.warn("Failed to retriving ip address, " + e.getMessage(), e);
								}
							}
						}
					} catch (Throwable e) {
						log.warn("Failed to retriving ip address, " + e.getMessage(), e);
					}
				}
			}
		} catch (Throwable e) {
			log.warn("Failed to retriving ip address, " + e.getMessage(), e);
		}
		log.error("Could not get local host ip address, will use 127.0.0.1 instead.");
		return localAddress;
	}

	private static final Map hostNameCache = new LRUCache(1000);

	public static String getHostName(String address) {
		try {
			int i = address.indexOf(':');
			if (i > -1) {
				address = address.substring(0, i);
			}
			String hostname = hostNameCache.get(address);
			if (hostname != null && hostname.length() > 0) {
				return hostname;
			}
			InetAddress inetAddress = InetAddress.getByName(address);
			if (inetAddress != null) {
				hostname = inetAddress.getHostName();
				hostNameCache.put(address, hostname);
				return hostname;
			}
		} catch (Throwable e) {
			// ignore
		}
		return address;
	}

	/**
	 * @param hostName
	 * @return ip address or hostName if UnknownHostException
	 */
	public static String getIpByHost(String hostName) {
		try {
			return InetAddress.getByName(hostName).getHostAddress();
		} catch (UnknownHostException e) {
			return hostName;
		}
	}

	public static String toAddressString(InetSocketAddress address) {
		return address.getAddress().getHostAddress() + ":" + address.getPort();
	}

	public static InetSocketAddress toAddress(String address) {
		int i = address.indexOf(':');
		String host;
		int port;
		if (i > -1) {
			host = address.substring(0, i);
			port = Integer.parseInt(address.substring(i + 1));
		} else {
			host = address;
			port = 0;
		}
		return new InetSocketAddress(host, port);
	}

	public static String toURL(String protocol, String host, int port, String path) {
		StringBuilder sb = new StringBuilder();
		sb.append(protocol).append("://");
		sb.append(host).append(':').append(port);
		if (path.charAt(0) != '/')
			sb.append('/');
		sb.append(path);
		return sb.toString();
	}

	private static Map portMapping;

	public static int getMappingPort(int containerPort) {
		if (null == portMapping) {
			portMapping = new HashMap<>();
			String portMappingsString = System.getenv("PORT_MAPPING");
			String[] portMappingS = portMappingsString.split(",");
			for (String portMappingString : portMappingS) {
				String[] split = portMappingString.split(":");
				portMapping.put(Integer.valueOf(split[1]), Integer.valueOf(split[0]));
			}
		}
		return null == portMapping.get(containerPort) ? containerPort : portMapping.get(containerPort);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy