http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/com/cloud/utils/net/NetUtils.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java deleted file mode 100644 index 883129b..0000000 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ /dev/null @@ -1,1550 +0,0 @@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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.cloud.utils.net; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.math.BigInteger; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.URI; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Formatter; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.SortedSet; -import java.util.StringTokenizer; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.lang.SystemUtils; -import org.apache.commons.net.util.SubnetUtils; -import org.apache.commons.validator.routines.InetAddressValidator; -import org.apache.log4j.Logger; - -import com.cloud.utils.IteratorUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.script.Script; -import com.googlecode.ipv6.IPv6Address; -import com.googlecode.ipv6.IPv6AddressRange; -import com.googlecode.ipv6.IPv6Network; - -public class NetUtils { - protected final static Logger s_logger = Logger.getLogger(NetUtils.class); - - private static final int MAX_CIDR = 32; - private static final int RFC_3021_31_BIT_CIDR = 31; - - public final static String HTTP_PORT = "80"; - public final static String HTTPS_PORT = "443"; - public final static int VPN_PORT = 500; - public final static int VPN_NATT_PORT = 4500; - public final static int VPN_L2TP_PORT = 1701; - public final static int HAPROXY_STATS_PORT = 8081; - - public final static String UDP_PROTO = "udp"; - public final static String TCP_PROTO = "tcp"; - public final static String ANY_PROTO = "any"; - public final static String ICMP_PROTO = "icmp"; - public final static String ALL_PROTO = "all"; - public final static String HTTP_PROTO = "http"; - public final static String SSL_PROTO = "ssl"; - - public final static String ALL_CIDRS = "0.0.0.0/0"; - public final static int PORT_RANGE_MIN = 0; - public final static int PORT_RANGE_MAX = 65535; - - public final static int DEFAULT_AUTOSCALE_VM_DESTROY_TIME = 2 * 60; // Grace period before Vm is destroyed - public final static int DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME = 30; - public final static int DEFAULT_AUTOSCALE_POLICY_QUIET_TIME = 5 * 60; - private final static Random s_rand = new Random(System.currentTimeMillis()); - - public static long createSequenceBasedMacAddress(final long macAddress) { - return macAddress | 0x060000000000l | (long)s_rand.nextInt(32768) << 25 & 0x00fffe000000l; - } - - public static String getHostName() { - try { - final InetAddress localAddr = InetAddress.getLocalHost(); - if (localAddr != null) { - return localAddr.getHostName(); - } - } catch (final UnknownHostException e) { - s_logger.warn("UnknownHostException when trying to get host name. ", e); - } - return "localhost"; - } - - public static InetAddress getLocalInetAddress() { - try { - return InetAddress.getLocalHost(); - } catch (final UnknownHostException e) { - s_logger.warn("UnknownHostException in getLocalInetAddress().", e); - return null; - } - } - - public static String resolveToIp(final String host) { - try { - final InetAddress addr = InetAddress.getByName(host); - return ipFromInetAddress(addr); - } catch (final UnknownHostException e) { - s_logger.warn("Unable to resolve " + host + " to IP due to UnknownHostException"); - return null; - } - } - - public static InetAddress[] getAllLocalInetAddresses() { - final List<InetAddress> addrList = new ArrayList<InetAddress>(); - try { - for (final NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { - if (ifc.isUp() && !ifc.isVirtual()) { - for (final InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) { - addrList.add(addr); - } - } - } - } catch (final SocketException e) { - s_logger.warn("SocketException in getAllLocalInetAddresses().", e); - } - - final InetAddress[] addrs = new InetAddress[addrList.size()]; - if (addrList.size() > 0) { - System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size()); - } - return addrs; - } - - public static String[] getLocalCidrs() { - final String defaultHostIp = getDefaultHostIp(); - - final List<String> cidrList = new ArrayList<String>(); - try { - for (final NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { - if (ifc.isUp() && !ifc.isVirtual() && !ifc.isLoopback()) { - for (final InterfaceAddress address : ifc.getInterfaceAddresses()) { - final InetAddress addr = address.getAddress(); - final int prefixLength = address.getNetworkPrefixLength(); - if (prefixLength < MAX_CIDR && prefixLength > 0) { - final String ip = ipFromInetAddress(addr); - if (ip.equalsIgnoreCase(defaultHostIp)) { - cidrList.add(ipAndNetMaskToCidr(ip, getCidrNetmask(prefixLength))); - } - } - } - } - } - } catch (final SocketException e) { - s_logger.warn("UnknownHostException in getLocalCidrs().", e); - } - - return cidrList.toArray(new String[0]); - } - - public static String getDefaultHostIp() { - if (SystemUtils.IS_OS_WINDOWS) { - final Pattern pattern = Pattern.compile("\\s*0.0.0.0\\s*0.0.0.0\\s*(\\S*)\\s*(\\S*)\\s*"); - try { - final Process result = Runtime.getRuntime().exec("route print -4"); - final BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream())); - - String line = output.readLine(); - while (line != null) { - final Matcher matcher = pattern.matcher(line); - if (matcher.find()) { - return matcher.group(2); - } - line = output.readLine(); - } - } catch (final IOException e) { - s_logger.debug("Caught IOException", e); - } - return null; - } else { - NetworkInterface nic = null; - final String pubNic = getDefaultEthDevice(); - - if (pubNic == null) { - return null; - } - - try { - nic = NetworkInterface.getByName(pubNic); - } catch (final SocketException e) { - return null; - } - - String[] info = null; - try { - info = NetUtils.getNetworkParams(nic); - } catch (final NullPointerException ignored) { - s_logger.debug("Caught NullPointerException when trying to getDefaultHostIp"); - } - if (info != null) { - return info[0]; - } - return null; - } - } - - public static String getDefaultEthDevice() { - if (SystemUtils.IS_OS_MAC) { - final String defDev = Script.runSimpleBashScript("/sbin/route -n get default 2> /dev/null | grep interface | awk '{print $2}'"); - return defDev; - } - final String defaultRoute = Script.runSimpleBashScript("/sbin/route | grep default"); - - if (defaultRoute == null) { - return null; - } - - final String[] defaultRouteList = defaultRoute.split("\\s+"); - - if (defaultRouteList.length != 8) { - return null; - } - - return defaultRouteList[7]; - } - - public static InetAddress getFirstNonLoopbackLocalInetAddress() { - final InetAddress[] addrs = getAllLocalInetAddresses(); - if (addrs != null) { - for (final InetAddress addr : addrs) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Check local InetAddress : " + addr.toString() + ", total count :" + addrs.length); - } - - if (!addr.isLoopbackAddress()) { - return addr; - } - } - } - - s_logger.warn("Unable to determine a non-loopback address, local inet address count :" + addrs.length); - return null; - } - - public static InetAddress[] getInterfaceInetAddresses(final String ifName) { - final List<InetAddress> addrList = new ArrayList<InetAddress>(); - try { - for (final NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { - if (ifc.isUp() && !ifc.isVirtual() && ifc.getName().equals(ifName)) { - for (final InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) { - addrList.add(addr); - } - } - } - } catch (final SocketException e) { - s_logger.warn("SocketException in getAllLocalInetAddresses().", e); - } - - final InetAddress[] addrs = new InetAddress[addrList.size()]; - if (addrList.size() > 0) { - System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size()); - } - return addrs; - } - - public static String getLocalIPString() { - final InetAddress addr = getLocalInetAddress(); - if (addr != null) { - return ipFromInetAddress(addr); - } - - return "127.0.0.1"; - } - - public static String ipFromInetAddress(final InetAddress addr) { - assert addr != null; - - final byte[] ipBytes = addr.getAddress(); - final StringBuffer sb = new StringBuffer(); - sb.append(ipBytes[0] & 0xff).append("."); - sb.append(ipBytes[1] & 0xff).append("."); - sb.append(ipBytes[2] & 0xff).append("."); - sb.append(ipBytes[3] & 0xff); - - return sb.toString(); - } - - public static boolean isLocalAddress(final InetAddress addr) { - final InetAddress[] addrs = getAllLocalInetAddresses(); - - if (addrs != null) { - for (final InetAddress self : addrs) { - if (self.equals(addr)) { - return true; - } - } - } - return false; - } - - public static boolean isLocalAddress(final String strAddress) { - - InetAddress addr; - try { - addr = InetAddress.getByName(strAddress); - return isLocalAddress(addr); - } catch (final UnknownHostException e) { - } - return false; - } - - public static String getMacAddress(final InetAddress address) { - final StringBuffer sb = new StringBuffer(); - final Formatter formatter = new Formatter(sb); - try { - final NetworkInterface ni = NetworkInterface.getByInetAddress(address); - final byte[] mac = ni.getHardwareAddress(); - - for (int i = 0; i < mac.length; i++) { - formatter.format("%02X%s", mac[i], i < mac.length - 1 ? ":" : ""); - } - } catch (final SocketException e) { - s_logger.error("SocketException when trying to retrieve MAC address", e); - } finally { - formatter.close(); - } - return sb.toString(); - } - - public static long getMacAddressAsLong(final InetAddress address) { - long macAddressAsLong = 0; - try { - final NetworkInterface ni = NetworkInterface.getByInetAddress(address); - final byte[] mac = ni.getHardwareAddress(); - - for (int i = 0; i < mac.length; i++) { - macAddressAsLong |= (long)(mac[i] & 0xff) << (mac.length - i - 1) * 8; - } - - } catch (final SocketException e) { - s_logger.error("SocketException when trying to retrieve MAC address", e); - } - - return macAddressAsLong; - } - - /** - * This method will fail in case we have a 31 Bit prefix network - * See RFC 3021. - * - * In order to avoid calling this method, please check the <code>NetUtils.is31PrefixCidr(cidr)</code> first. - */ - public static boolean ipRangesOverlap(final String startIp1, final String endIp1, final String startIp2, final String endIp2) { - final long startIp1Long = ip2Long(startIp1); - long endIp1Long = startIp1Long; - if (endIp1 != null) { - endIp1Long = ip2Long(endIp1); - } - final long startIp2Long = ip2Long(startIp2); - long endIp2Long = startIp2Long; - if (endIp2 != null) { - endIp2Long = ip2Long(endIp2); - } - - if (startIp1Long == startIp2Long || startIp1Long == endIp2Long || endIp1Long == startIp2Long || endIp1Long == endIp2Long) { - return true; - } else if (startIp1Long > startIp2Long && startIp1Long < endIp2Long) { - return true; - } else if (endIp1Long > startIp2Long && endIp1Long < endIp2Long) { - return true; - } else if (startIp2Long > startIp1Long && startIp2Long < endIp1Long) { - return true; - } else if (endIp2Long > startIp1Long && endIp2Long < endIp1Long) { - return true; - } else { - return false; - } - } - - public static long ip2Long(final String ip) { - final String[] tokens = ip.split("[.]"); - assert tokens.length == 4; - long result = 0; - for (int i = 0; i < tokens.length; i++) { - try { - result = result << 8 | Integer.parseInt(tokens[i]); - } catch (final NumberFormatException e) { - throw new RuntimeException("Incorrect number", e); - } - } - - return result; - } - - public static String long2Ip(final long ip) { - final StringBuilder result = new StringBuilder(15); - result.append(ip >> 24 & 0xff).append("."); - result.append(ip >> 16 & 0xff).append("."); - result.append(ip >> 8 & 0xff).append("."); - result.append(ip & 0xff); - - return result.toString(); - } - - public static long mac2Long(final String macAddress) { - final String[] tokens = macAddress.split(":"); - assert tokens.length == 6; - long result = 0; - for (int i = 0; i < tokens.length; i++) { - result = result << 8; - result |= Integer.parseInt(tokens[i], 16); - } - return result; - } - - public static String[] getNicParams(final String nicName) { - try { - final NetworkInterface nic = NetworkInterface.getByName(nicName); - return getNetworkParams(nic); - } catch (final SocketException e) { - return null; - } - } - - public static String[] getNetworkParams(final NetworkInterface nic) { - final List<InterfaceAddress> addrs = nic.getInterfaceAddresses(); - if (addrs == null || addrs.size() == 0) { - return null; - } - InterfaceAddress addr = null; - for (final InterfaceAddress iaddr : addrs) { - final InetAddress inet = iaddr.getAddress(); - if (!inet.isLinkLocalAddress() && !inet.isLoopbackAddress() && !inet.isMulticastAddress() && inet.getAddress().length == 4) { - addr = iaddr; - break; - } - } - if (addr == null) { - return null; - } - final String[] result = new String[3]; - result[0] = addr.getAddress().getHostAddress(); - try { - final byte[] mac = nic.getHardwareAddress(); - result[1] = byte2Mac(mac); - } catch (final SocketException e) { - s_logger.debug("Caught exception when trying to get the mac address ", e); - } - - result[2] = prefix2Netmask(addr.getNetworkPrefixLength()); - return result; - } - - public static String prefix2Netmask(final short prefix) { - long addr = 0; - for (int i = 0; i < prefix; i++) { - addr = addr | 1 << 31 - i; - } - - return long2Ip(addr); - } - - public static String byte2Mac(final byte[] m) { - final StringBuilder result = new StringBuilder(17); - final Formatter formatter = new Formatter(result); - formatter.format("%02x:%02x:%02x:%02x:%02x:%02x", m[0], m[1], m[2], m[3], m[4], m[5]); - formatter.close(); - return result.toString(); - } - - public static String long2Mac(final long macAddress) { - final StringBuilder result = new StringBuilder(17); - try (Formatter formatter = new Formatter(result)) { - formatter.format("%02x:%02x:%02x:%02x:%02x:%02x", - macAddress >> 40 & 0xff, macAddress >> 32 & 0xff, - macAddress >> 24 & 0xff, macAddress >> 16 & 0xff, - macAddress >> 8 & 0xff, macAddress & 0xff); - } - return result.toString(); - } - - public static boolean isValidPrivateIp(final String ipAddress, final String guestIPAddress) { - - final InetAddress privIp = parseIpAddress(ipAddress); - if (privIp == null) { - return false; - } - if (!privIp.isSiteLocalAddress()) { - return false; - } - - String firstGuestOctet = "10"; - if (guestIPAddress != null && !guestIPAddress.isEmpty()) { - final String[] guestIPList = guestIPAddress.split("\\."); - firstGuestOctet = guestIPList[0]; - } - - final String[] ipList = ipAddress.split("\\."); - if (!ipList[0].equals(firstGuestOctet)) { - return false; - } - - return true; - } - - public static boolean isSiteLocalAddress(final String ipAddress) { - if (ipAddress == null) { - return false; - } else { - final InetAddress ip = parseIpAddress(ipAddress); - if(ip != null) { - return ip.isSiteLocalAddress(); - } - return false; - } - } - - public static boolean validIpRange(final String startIP, final String endIP) { - if (endIP == null || endIP.isEmpty()) { - return true; - } - - final long startIPLong = NetUtils.ip2Long(startIP); - final long endIPLong = NetUtils.ip2Long(endIP); - return startIPLong <= endIPLong; - } - - public static boolean isValidIp(final String ip) { - final InetAddressValidator validator = InetAddressValidator.getInstance(); - - return validator.isValidInet4Address(ip); - } - - public static boolean is31PrefixCidr(final String cidr) { - final boolean isValidCird = isValidCIDR(cidr); - if (isValidCird){ - final String[] cidrPair = cidr.split("\\/"); - final String cidrSize = cidrPair[1]; - - final int cidrSizeNum = Integer.parseInt(cidrSize); - if (cidrSizeNum == RFC_3021_31_BIT_CIDR) { - return true; - } - } - return false; - } - - public static boolean isValidCIDR(final String cidr) { - if (cidr == null || cidr.isEmpty()) { - return false; - } - final String[] cidrPair = cidr.split("\\/"); - if (cidrPair.length != 2) { - return false; - } - final String cidrAddress = cidrPair[0]; - final String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { - return false; - } - int cidrSizeNum = -1; - - try { - cidrSizeNum = Integer.parseInt(cidrSize); - } catch (final Exception e) { - return false; - } - - if (cidrSizeNum < 0 || cidrSizeNum > MAX_CIDR) { - return false; - } - - return true; - } - - public static boolean isValidNetmask(final String netmask) { - if (!isValidIp(netmask)) { - return false; - } - - final long ip = ip2Long(netmask); - int count = 0; - boolean finished = false; - for (int i = 31; i >= 0; i--) { - if ((ip >> i & 0x1) == 0) { - finished = true; - } else { - if (finished) { - return false; - } - count += 1; - } - } - - if (count == 0) { - return false; - } - - return true; - } - - private static InetAddress parseIpAddress(final String address) { - final StringTokenizer st = new StringTokenizer(address, "."); - final byte[] bytes = new byte[4]; - - if (st.countTokens() == 4) { - try { - for (int i = 0; i < 4; i++) { - bytes[i] = (byte)Integer.parseInt(st.nextToken()); - } - return InetAddress.getByAddress(address, bytes); - } catch (final NumberFormatException nfe) { - return null; - } catch (final UnknownHostException uhe) { - return null; - } - } - return null; - } - - public static String getCidrFromGatewayAndNetmask(final String gatewayStr, final String netmaskStr) { - final long netmask = ip2Long(netmaskStr); - final long gateway = ip2Long(gatewayStr); - final long firstPart = gateway & netmask; - final long size = getCidrSize(netmaskStr); - return long2Ip(firstPart) + "/" + size; - } - - public static String[] getIpRangeFromCidr(final String cidr, final long size) { - assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; - final String[] result = new String[2]; - final long ip = ip2Long(cidr); - final long startNetMask = ip2Long(getCidrNetmask(size)); - final long start = (ip & startNetMask) + 1; - long end = start; - - end = end >> MAX_CIDR - size; - - end++; - end = (end << MAX_CIDR - size) - 2; - - result[0] = long2Ip(start); - result[1] = long2Ip(end); - - return result; - } - - public static Set<Long> getAllIpsFromCidr(final String cidr, final long size, final Set<Long> usedIps) { - assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; - final Set<Long> result = new TreeSet<Long>(); - final long ip = ip2Long(cidr); - final long startNetMask = ip2Long(getCidrNetmask(size)); - long start = (ip & startNetMask) + 1; - long end = start; - - end = end >> MAX_CIDR - size; - - end++; - end = (end << MAX_CIDR - size) - 2; - int maxIps = 255; // get 255 ips as maximum - while (start <= end && maxIps > 0) { - if (!usedIps.contains(start)) { - result.add(start); - maxIps--; - } - start++; - } - - return result; - } - - /** - * Given a cidr, this method returns an ip address within the range but - * is not in the avoid list. - * - * @param startIp ip that the cidr starts with - * @param size size of the cidr - * @param avoid set of ips to avoid - * @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one. - */ - public static long getRandomIpFromCidr(final String startIp, final int size, final SortedSet<Long> avoid) { - return getRandomIpFromCidr(ip2Long(startIp), size, avoid); - - } - - /** - * Given a cidr, this method returns an ip address within the range but - * is not in the avoid list. - * Note: the gateway address has to be specified in the avoid list - * - * @param cidr ip that the cidr starts with - * @param size size of the cidr - * @param avoid set of ips to avoid - * @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one. - */ - public static long getRandomIpFromCidr(final long cidr, final int size, final SortedSet<Long> avoid) { - assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; - - final long startNetMask = ip2Long(getCidrNetmask(size)); - final long startIp = (cidr & startNetMask) + 1; //exclude the first ip since it isnt valid, e.g., 192.168.10.0 - int range = 1 << MAX_CIDR - size; //e.g., /24 = 2^8 = 256 - range = range - 1; //exclude end of the range since that is the broadcast address, e.g., 192.168.10.255 - - if (avoid.size() >= range) { - return -1; - } - - //Reduce the range by the size of the avoid set - //e.g., cidr = 192.168.10.0, size = /24, avoid = 192.168.10.1, 192.168.10.20, 192.168.10.254 - // range = 2^8 - 1 - 3 = 252 - range = range - avoid.size(); - final int next = s_rand.nextInt(range); //note: nextInt excludes last value - long ip = startIp + next; - for (final Long avoidable : avoid) { - if (ip >= avoidable) { - ip++; - } else { - break; - } - } - - return ip; - } - - public static String getIpRangeStartIpFromCidr(final String cidr, final long size) { - final long ip = ip2Long(cidr); - final long startNetMask = ip2Long(getCidrNetmask(size)); - final long start = (ip & startNetMask) + 1; - return long2Ip(start); - } - - public static String getIpRangeEndIpFromCidr(final String cidr, final long size) { - final long ip = ip2Long(cidr); - final long startNetMask = ip2Long(getCidrNetmask(size)); - final long start = (ip & startNetMask) + 1; - long end = start; - end = end >> MAX_CIDR - size; - - end++; - end = (end << MAX_CIDR - size) - 2; - return long2Ip(end); - } - - public static boolean sameSubnet(final String ip1, final String ip2, final String netmask) { - if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) { - return true; - } - final String subnet1 = NetUtils.getSubNet(ip1, netmask); - final String subnet2 = NetUtils.getSubNet(ip2, netmask); - - return subnet1.equals(subnet2); - } - - public static boolean sameSubnetCIDR(final String ip1, final String ip2, final long cidrSize) { - if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) { - return true; - } - final String subnet1 = NetUtils.getCidrSubNet(ip1, cidrSize); - final String subnet2 = NetUtils.getCidrSubNet(ip2, cidrSize); - - return subnet1.equals(subnet2); - } - - public static String getSubNet(final String ip, final String netmask) { - final long ipAddr = ip2Long(ip); - final long subnet = ip2Long(netmask); - final long result = ipAddr & subnet; - return long2Ip(result); - } - - public static String getCidrSubNet(final String ip, final long cidrSize) { - final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSize << MAX_CIDR - cidrSize; - final String netmask = NetUtils.long2Ip(numericNetmask); - return getSubNet(ip, netmask); - } - - public static String ipAndNetMaskToCidr(final String ip, final String netmask) { - if (!isValidIp(ip)) { - return null; - } - - if (!isValidNetmask(netmask)) { - return null; - } - - final long ipAddr = ip2Long(ip); - final long subnet = ip2Long(netmask); - final long result = ipAddr & subnet; - int bits = subnet == 0 ? 0 : 1; - long subnet2 = subnet; - while ((subnet2 = subnet2 >> 1 & subnet) != 0) { - bits++; - } - - return long2Ip(result) + "/" + Integer.toString(bits); - } - - public static String[] ipAndNetMaskToRange(final String ip, final String netmask) { - final long ipAddr = ip2Long(ip); - long subnet = ip2Long(netmask); - final long start = (ipAddr & subnet) + 1; - long end = start; - int bits = subnet == 0 ? 0 : 1; - while ((subnet = subnet >> 1 & subnet) != 0) { - bits++; - } - end = end >> MAX_CIDR - bits; - - end++; - end = (end << MAX_CIDR - bits) - 2; - - return new String[] {long2Ip(start), long2Ip(end)}; - - } - - public static Pair<String, Integer> getCidr(final String cidr) { - final String[] tokens = cidr.split("/"); - return new Pair<String, Integer>(tokens[0], Integer.parseInt(tokens[1])); - } - - public static enum SupersetOrSubset { - isSuperset, isSubset, neitherSubetNorSuperset, sameSubnet, errorInCidrFormat - } - - public static SupersetOrSubset isNetowrkASubsetOrSupersetOfNetworkB(final String cidrA, final String cidrB) { - final Long[] cidrALong = cidrToLong(cidrA); - final Long[] cidrBLong = cidrToLong(cidrB); - long shift = 0; - if (cidrALong == null || cidrBLong == null) { - //implies error in the cidr format - return SupersetOrSubset.errorInCidrFormat; - } - if (cidrALong[1] >= cidrBLong[1]) { - shift = MAX_CIDR - cidrBLong[1]; - } else { - shift = MAX_CIDR - cidrALong[1]; - } - final long result = (cidrALong[0] >> shift) - (cidrBLong[0] >> shift); - if (result == 0) { - if (cidrALong[1] < cidrBLong[1]) { - //this implies cidrA is super set of cidrB - return SupersetOrSubset.isSuperset; - } else if (cidrALong[1].equals(cidrBLong[1])) { - //this implies both the cidrs are equal - return SupersetOrSubset.sameSubnet; - } - // implies cidrA is subset of cidrB - return SupersetOrSubset.isSubset; - } - //this implies no overlap. - return SupersetOrSubset.neitherSubetNorSuperset; - } - - public static boolean isNetworkAWithinNetworkB(final String cidrA, final String cidrB) { - final Long[] cidrALong = cidrToLong(cidrA); - final Long[] cidrBLong = cidrToLong(cidrB); - if (cidrALong == null || cidrBLong == null) { - return false; - } - final long shift = MAX_CIDR - cidrBLong[1]; - return cidrALong[0] >> shift == cidrBLong[0] >> shift; - } - - public static Long[] cidrToLong(final String cidr) { - if (cidr == null || cidr.isEmpty()) { - return null; - } - final String[] cidrPair = cidr.split("\\/"); - if (cidrPair.length != 2) { - return null; - } - final String cidrAddress = cidrPair[0]; - final String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { - return null; - } - int cidrSizeNum = -1; - - try { - cidrSizeNum = Integer.parseInt(cidrSize); - } catch (final Exception e) { - return null; - } - final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSizeNum << MAX_CIDR - cidrSizeNum; - final long ipAddr = ip2Long(cidrAddress); - final Long[] cidrlong = {ipAddr & numericNetmask, (long)cidrSizeNum}; - return cidrlong; - - } - - public static String getCidrSubNet(final String cidr) { - if (cidr == null || cidr.isEmpty()) { - return null; - } - final String[] cidrPair = cidr.split("\\/"); - if (cidrPair.length != 2) { - return null; - } - final String cidrAddress = cidrPair[0]; - final String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { - return null; - } - int cidrSizeNum = -1; - - try { - cidrSizeNum = Integer.parseInt(cidrSize); - } catch (final Exception e) { - return null; - } - final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSizeNum << MAX_CIDR - cidrSizeNum; - final String netmask = NetUtils.long2Ip(numericNetmask); - return getSubNet(cidrAddress, netmask); - } - - public static String getCidrNetmask(final long cidrSize) { - final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSize << MAX_CIDR - cidrSize; - return long2Ip(numericNetmask); - } - - public static String getCidrNetmask(final String cidr) { - final String[] cidrPair = cidr.split("\\/"); - final long guestCidrSize = Long.parseLong(cidrPair[1]); - return getCidrNetmask(guestCidrSize); - } - - public static String cidr2Netmask(final String cidr) { - final String[] tokens = cidr.split("\\/"); - return getCidrNetmask(Integer.parseInt(tokens[1])); - } - - public static long getCidrSize(final String netmask) { - final long ip = ip2Long(netmask); - int count = 0; - for (int i = 0; i < MAX_CIDR; i++) { - if ((ip >> i & 0x1) == 0) { - count++; - } else { - break; - } - } - - return MAX_CIDR - count; - } - - public static boolean isValidPort(final String p) { - try { - final int port = Integer.parseInt(p); - return !(port > 65535 || port < 1); - } catch (final NumberFormatException e) { - return false; - } - } - - public static boolean isValidPort(final int p) { - return !(p > 65535 || p < 1); - } - - public static boolean isValidLBPort(final String p) { - try { - final int port = Integer.parseInt(p); - return !(port > 65535 || port < 1); - } catch (final NumberFormatException e) { - return false; - } - } - - public static boolean isValidProto(final String p) { - final String proto = p.toLowerCase(); - return proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO); - } - - public static boolean isValidSecurityGroupProto(final String p) { - final String proto = p.toLowerCase(); - return proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO) || proto.equals(ALL_PROTO); - } - - public static boolean isValidAlgorithm(final String p) { - final String algo = p.toLowerCase(); - return algo.equals("roundrobin") || algo.equals("leastconn") || algo.equals("source"); - } - - public static boolean isValidAutoScaleAction(final String p) { - final String action = p.toLowerCase(); - return action.equals("scaleup") || action.equals("scaledown"); - } - - public static String getLinkLocalNetMask() { - return "255.255.0.0"; - } - - public static String getLinkLocalGateway() { - return "169.254.0.1"; - } - - public static String getLinkLocalCIDR() { - return "169.254.0.0/16"; - } - - public static String[] getLinkLocalIPRange(final int size) { - if (size > 16 || size <= 0) { - return null; - } - /* reserve gateway */ - final String[] range = getIpRangeFromCidr(getLinkLocalGateway(), MAX_CIDR - size); - - if (range[0].equalsIgnoreCase(getLinkLocalGateway())) { - /* remove the gateway */ - long ip = ip2Long(range[0]); - ip += 1; - range[0] = long2Ip(ip); - } - return range; - } - - public static String getLinkLocalIpEnd() { - final String[] cidrPair = getLinkLocalCIDR().split("\\/"); - final String cidr = cidrPair[0]; - - return getIpRangeEndIpFromCidr(cidr, MAX_CIDR - Long.parseLong(cidrPair[1])); - } - - public static String portRangeToString(final int portRange[]) { - return Integer.toString(portRange[0]) + ":" + Integer.toString(portRange[1]); - } - - public static boolean verifyDomainNameLabel(final String hostName, final boolean isHostName) { - // must be between 1 and 63 characters long and may contain only the ASCII letters 'a' through 'z' (in a - // case-insensitive manner), - // the digits '0' through '9', and the hyphen ('-'). - // Can not start with a hyphen and digit, and must not end with a hyphen - // If it's a host name, don't allow to start with digit - - if (hostName.length() > 63 || hostName.length() < 1) { - s_logger.warn("Domain name label must be between 1 and 63 characters long"); - return false; - } else if (!hostName.toLowerCase().matches("[a-z0-9-]*")) { - s_logger.warn("Domain name label may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner)"); - return false; - } else if (hostName.startsWith("-") || hostName.endsWith("-")) { - s_logger.warn("Domain name label can not start with a hyphen and digit, and must not end with a hyphen"); - return false; - } else if (isHostName && hostName.matches("^[0-9-].*")) { - s_logger.warn("Host name can't start with digit"); - return false; - } - - return true; - } - - public static boolean verifyDomainName(final String domainName) { - // don't allow domain name length to exceed 190 chars (190 + 63 (max host name length) = 253 = max domainName length - if (domainName.length() < 1 || domainName.length() > 190) { - s_logger.trace("Domain name must be between 1 and 190 characters long"); - return false; - } - - if (domainName.startsWith(".") || domainName.endsWith(".")) { - s_logger.trace("Domain name can't start or end with ."); - return false; - } - - final String[] domainNameLabels = domainName.split("\\."); - - for (int i = 0; i < domainNameLabels.length; i++) { - if (!verifyDomainNameLabel(domainNameLabels[i], false)) { - s_logger.warn("Domain name label " + domainNameLabels[i] + " is incorrect"); - return false; - } - } - - return true; - } - - public static String getDhcpRange(final String cidr) { - final String[] splitResult = cidr.split("\\/"); - final long size = Long.parseLong(splitResult[1]); - return NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size); - } - - // Check if 2 CIDRs have exactly same IP Range - public static boolean isSameIpRange(final String cidrA, final String cidrB) { - - if (!NetUtils.isValidCIDR(cidrA)) { - s_logger.info("Invalid value of cidr " + cidrA); - return false; - } - if (!NetUtils.isValidCIDR(cidrB)) { - s_logger.info("Invalid value of cidr " + cidrB); - return false; - } - final String[] cidrPairFirst = cidrA.split("\\/"); - final String[] cidrPairSecond = cidrB.split("\\/"); - - final Long networkSizeFirst = Long.valueOf(cidrPairFirst[1]); - final Long networkSizeSecond = Long.valueOf(cidrPairSecond[1]); - final String ipRangeFirst[] = NetUtils.getIpRangeFromCidr(cidrPairFirst[0], networkSizeFirst); - final String ipRangeSecond[] = NetUtils.getIpRangeFromCidr(cidrPairFirst[0], networkSizeSecond); - - final long startIpFirst = NetUtils.ip2Long(ipRangeFirst[0]); - final long endIpFirst = NetUtils.ip2Long(ipRangeFirst[1]); - final long startIpSecond = NetUtils.ip2Long(ipRangeSecond[0]); - final long endIpSecond = NetUtils.ip2Long(ipRangeSecond[1]); - if (startIpFirst == startIpSecond && endIpFirst == endIpSecond) { - return true; - } - return false; - } - - public static boolean validateGuestCidr(final String cidr) { - // RFC 1918 - The Internet Assigned Numbers Authority (IANA) has reserved the - // following three blocks of the IP address space for private internets: - // 10.0.0.0 - 10.255.255.255 (10/8 prefix) - // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) - // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) - - final String cidr1 = "10.0.0.0/8"; - final String cidr2 = "172.16.0.0/12"; - final String cidr3 = "192.168.0.0/16"; - - if (!isValidCIDR(cidr)) { - s_logger.warn("Cidr " + cidr + " is not valid"); - return false; - } - - if (isNetworkAWithinNetworkB(cidr, cidr1) || isNetworkAWithinNetworkB(cidr, cidr2) || isNetworkAWithinNetworkB(cidr, cidr3)) { - return true; - } else { - s_logger.warn("cidr " + cidr + " is not RFC 1918 compliant"); - return false; - } - } - - public static boolean verifyInstanceName(final String instanceName) { - //instance name for cloudstack vms shouldn't contain - and spaces - if (instanceName.contains("-") || instanceName.contains(" ") || instanceName.contains("+")) { - s_logger.warn("Instance name can not contain hyphen, spaces and \"+\" char"); - return false; - } - - return true; - } - - public static boolean isNetworksOverlap(final String cidrA, final String cidrB) { - final Long[] cidrALong = cidrToLong(cidrA); - final Long[] cidrBLong = cidrToLong(cidrB); - if (cidrALong == null || cidrBLong == null) { - return false; - } - final long shift = MAX_CIDR - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]); - return cidrALong[0] >> shift == cidrBLong[0] >> shift; - } - - public static boolean isValidS2SVpnPolicy(final String policys) { - if (policys == null || policys.isEmpty()) { - return false; - } - for (final String policy : policys.split(",")) { - if (policy.isEmpty()) { - return false; - } - final String cipherHash = policy.split(";")[0]; - if (cipherHash.isEmpty()) { - return false; - } - final String[] list = cipherHash.split("-"); - if (list.length != 2) { - return false; - } - final String cipher = list[0]; - final String hash = list[1]; - if (!cipher.matches("3des|aes128|aes192|aes256")) { - return false; - } - if (!hash.matches("md5|sha1")) { - return false; - } - String pfsGroup = null; - if (!policy.equals(cipherHash)) { - pfsGroup = policy.split(";")[1]; - } - if (pfsGroup != null && !pfsGroup.matches("modp1024|modp1536")) { - return false; - } - } - return true; - } - - public static boolean isValidCidrList(final String cidrList) { - for (final String guestCidr : cidrList.split(",")) { - if (!isValidCIDR(guestCidr)) { - return false; - } - } - return true; - } - - public static boolean validateGuestCidrList(final String guestCidrList) { - for (final String guestCidr : guestCidrList.split(",")) { - if (!validateGuestCidr(guestCidr)) { - return false; - } - } - return true; - } - - public static boolean validateIcmpType(final long icmpType) { - //Source - http://www.erg.abdn.ac.uk/~gorry/course/inet-pages/icmp-code.html - if (!(icmpType >= 0 && icmpType <= 255)) { - s_logger.warn("impcType is not within 0-255 range"); - return false; - } - return true; - } - - public static boolean validateIcmpCode(final long icmpCode) { - - //Source - http://www.erg.abdn.ac.uk/~gorry/course/inet-pages/icmp-code.html - if (!(icmpCode >= 0 && icmpCode <= 15)) { - s_logger.warn("Icmp code should be within 0-15 range"); - return false; - } - - return true; - } - - public static boolean isValidIpv6(final String ip) { - try { - IPv6Address.fromString(ip); - } catch (final IllegalArgumentException ex) { - return false; - } - return true; - } - - public static boolean isValidIp6Cidr(final String ip6Cidr) { - try { - IPv6Network.fromString(ip6Cidr); - } catch (final IllegalArgumentException ex) { - return false; - } - return true; - } - - public static int getIp6CidrSize(final String ip6Cidr) { - IPv6Network network = null; - try { - network = IPv6Network.fromString(ip6Cidr); - } catch (final IllegalArgumentException ex) { - return 0; - } - return network.getNetmask().asPrefixLength(); - } - - // Can cover 127 bits - public static String getIp6FromRange(final String ip6Range) { - final String[] ips = ip6Range.split("-"); - final String startIp = ips[0]; - final IPv6Address start = IPv6Address.fromString(startIp); - final BigInteger gap = countIp6InRange(ip6Range); - BigInteger next = new BigInteger(gap.bitLength(), s_rand); - while (next.compareTo(gap) >= 0) { - next = new BigInteger(gap.bitLength(), s_rand); - } - InetAddress resultAddr = null; - final BigInteger startInt = convertIPv6AddressToBigInteger(start); - if (startInt != null) { - final BigInteger resultInt = startInt.add(next); - try { - resultAddr = InetAddress.getByAddress(resultInt.toByteArray()); - } catch (final UnknownHostException e) { - return null; - } - } - if( resultAddr != null) { - final IPv6Address ip = IPv6Address.fromInetAddress(resultAddr); - return ip.toString(); - } - return null; - } - - //RFC3315, section 9.4 - public static String getDuidLL(final String macAddress) { - final String duid = "00:03:00:01:" + macAddress; - return duid; - } - - private static BigInteger convertIPv6AddressToBigInteger(final IPv6Address addr) { - InetAddress inetAddr; - try { - inetAddr = addr.toInetAddress(); - } catch (final UnknownHostException e) { - return null; - } - return new BigInteger(inetAddr.getAddress()); - } - - // Can cover 127 bits - public static BigInteger countIp6InRange(final String ip6Range) { - if (ip6Range == null) { - return null; - } - final String[] ips = ip6Range.split("-"); - final String startIp = ips[0]; - String endIp = ips[0]; - if (ips.length > 1) { - endIp = ips[1]; - } - try { - final BigInteger startInt = convertIPv6AddressToBigInteger(IPv6Address.fromString(startIp)); - final BigInteger endInt = convertIPv6AddressToBigInteger(IPv6Address.fromString(endIp)); - if (endInt != null && startInt != null && startInt.compareTo(endInt) <= 0) { - return endInt.subtract(startInt).add(BigInteger.ONE); - } - } catch (final IllegalArgumentException ex) { - s_logger.error("Failed to convert a string to an IPv6 address", ex); - } - return null; - } - - public static boolean isIp6InRange(final String ip6, final String ip6Range) { - if (ip6Range == null) { - return false; - } - final String[] ips = ip6Range.split("-"); - final String startIp = ips[0]; - String endIp = null; - if (ips.length > 1) { - endIp = ips[1]; - } - final IPv6Address start = IPv6Address.fromString(startIp); - final IPv6Address end = IPv6Address.fromString(endIp); - final IPv6Address ip = IPv6Address.fromString(ip6); - if (start.compareTo(ip) <= 0 && end.compareTo(ip) >= 0) { - return true; - } - return false; - } - - public static boolean isIp6InNetwork(final String ip6, final String ip6Cidr) { - IPv6Network network = null; - try { - network = IPv6Network.fromString(ip6Cidr); - } catch (final IllegalArgumentException ex) { - return false; - } - final IPv6Address ip = IPv6Address.fromString(ip6); - return network.contains(ip); - } - - public static boolean isIp6RangeOverlap(final String ipRange1, final String ipRange2) { - String[] ips = ipRange1.split("-"); - final String startIp1 = ips[0]; - String endIp1 = null; - if (ips.length > 1) { - endIp1 = ips[1]; - } - final IPv6Address start1 = IPv6Address.fromString(startIp1); - final IPv6Address end1 = IPv6Address.fromString(endIp1); - final IPv6AddressRange range1 = IPv6AddressRange.fromFirstAndLast(start1, end1); - ips = ipRange2.split("-"); - final String startIp2 = ips[0]; - String endIp2 = null; - if (ips.length > 1) { - endIp2 = ips[1]; - } - final IPv6Address start2 = IPv6Address.fromString(startIp2); - final IPv6Address end2 = IPv6Address.fromString(endIp2); - final IPv6AddressRange range2 = IPv6AddressRange.fromFirstAndLast(start2, end2); - return range1.overlaps(range2); - } - - public static String getNextIp6InRange(final String currentIp, final String ipRange) { - final String[] ips = ipRange.split("-"); - final String startIp = ips[0]; - String endIp = null; - if (ips.length > 1) { - endIp = ips[1]; - } - final IPv6Address start = IPv6Address.fromString(startIp); - final IPv6Address end = IPv6Address.fromString(endIp); - final IPv6Address current = IPv6Address.fromString(currentIp); - IPv6Address result = null; - if (current.equals(end)) { - result = start; - } else { - result = current.add(1); - } - String resultIp = null; - if (result != null) { - resultIp = result.toString(); - } - return resultIp; - } - - public static String standardizeIp6Address(final String ip6Addr) { - try { - return IPv6Address.fromString(ip6Addr).toString(); - } catch (final IllegalArgumentException ex) { - throw new IllegalArgumentException("Invalid IPv6 address: " + ex.getMessage()); - } - } - - public static String standardizeIp6Cidr(final String ip6Cidr){ - try { - return IPv6Network.fromString(ip6Cidr).toString(); - } catch (final IllegalArgumentException ex) { - throw new IllegalArgumentException("Invalid IPv6 CIDR: " + ex.getMessage()); - } - } - - static final String VLAN_PREFIX = "vlan://"; - static final int VLAN_PREFIX_LENGTH = VLAN_PREFIX.length(); - - public static boolean isValidVlan(String vlan) { - if (null == vlan || "".equals(vlan)) { - return false; - } - if (vlan.startsWith(VLAN_PREFIX)) { - vlan = vlan.substring(VLAN_PREFIX_LENGTH); - } - try { - final int vnet = Integer.parseInt(vlan); - if (vnet <= 0 || vnet >= 4095) { // the valid range is 1- 4094 - return false; - } - return true; - } catch (final NumberFormatException e) { - return false; - } - } - - static final String VLAN_UNTAGGED = "untagged"; - - public static boolean isSameIsolationId(String one, String other) { - // check nulls - // check empty strings - if ((one == null || one.isEmpty()) && (other == null || other.isEmpty())) { - return true; - } - if (one == null || other == null) { - return false; - } - // check 'untagged' - if (one.contains(VLAN_UNTAGGED) && other.contains(VLAN_UNTAGGED)) { - return true; - } - // if one is a number check the other as number and as 'vlan://' + number - if (one.startsWith(VLAN_PREFIX)) { - one = one.substring(VLAN_PREFIX_LENGTH); - } - if (other.startsWith(VLAN_PREFIX)) { - other = other.substring(VLAN_PREFIX_LENGTH); - } - // check valid uris or numbers - if (one.equalsIgnoreCase(other)) { - return true; - } - - return false; - } - - // Attention maintainers: these pvlan functions should take into account code - // in Networks.BroadcastDomainType, where URI construction is done for other - // types of BroadcastDomainTypes - public static URI generateUriForPvlan(final String primaryVlan, final String isolatedPvlan) { - return URI.create("pvlan://" + primaryVlan + "-i" + isolatedPvlan); - } - - public static String getPrimaryPvlanFromUri(final URI uri) { - final String[] vlans = uri.getHost().split("-"); - if (vlans.length < 1) { - return null; - } - return vlans[0]; - } - - public static String getIsolatedPvlanFromUri(final URI uri) { - final String[] vlans = uri.getHost().split("-"); - if (vlans.length < 2) { - return null; - } - for (final String vlan : vlans) { - if (vlan.startsWith("i")) { - return vlan.replace("i", " ").trim(); - } - } - return null; - } - - public static String generateMacOnIncrease(final String baseMac, final long l) { - long mac = mac2Long(baseMac); - if (l > 0xFFFFl) { - return null; - } - mac = mac + (l << 24); - mac = mac & 0x06FFFFFFFFFFl; - return long2Mac(mac); - } - - public static boolean isIpWithtInCidrRange(final String ipAddress, final String cidr) { - if (!isValidIp(ipAddress)) { - return false; - } - if (!isValidCIDR(cidr)) { - return false; - } - - // check if the gatewayip is the part of the ip range being added. - // RFC 3021 - 31-Bit Prefixes on IPv4 Point-to-Point Links - // GW Netmask Stat IP End IP - // 192.168.24.0 - 255.255.255.254 - 192.168.24.0 - 192.168.24.1 - // https://tools.ietf.org/html/rfc3021 - // Added by Wilder Rodrigues - final SubnetUtils subnetUtils = new SubnetUtils(cidr); - subnetUtils.setInclusiveHostCount(true); - - final boolean isInRange = subnetUtils.getInfo().isInRange(ipAddress); - - return isInRange; - } - - public static Boolean IsIpEqualToNetworkOrBroadCastIp(final String requestedIp, final String cidr, final long size) { - assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; - - final long ip = ip2Long(cidr); - final long startNetMask = ip2Long(getCidrNetmask(size)); - - final long start = ip & startNetMask; - long end = start; - - end = end >> MAX_CIDR - size; - - end++; - end = (end << MAX_CIDR - size) - 1; - - final long reqIp = ip2Long(requestedIp); - if (reqIp == start || reqIp == end) { - return true; - } - return false; - } - -}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/com/cloud/utils/net/NfsUtils.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/net/NfsUtils.java b/utils/src/com/cloud/utils/net/NfsUtils.java deleted file mode 100644 index 23c1007..0000000 --- a/utils/src/com/cloud/utils/net/NfsUtils.java +++ /dev/null @@ -1,55 +0,0 @@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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.cloud.utils.net; - -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; - -public class NfsUtils { - - public static String url2Mount(String urlStr) throws URISyntaxException { - URI url; - url = new URI(urlStr); - return url.getHost() + ":" + url.getPath(); - } - - public static String uri2Mount(URI uri) { - return uri.getHost() + ":" + uri.getPath(); - } - - public static String url2PathSafeString(String urlStr) { - String safe = urlStr.replace(File.separatorChar, '-'); - safe = safe.replace("?", ""); - safe = safe.replace("*", ""); - safe = safe.replace("\\", ""); - safe = safe.replace("/", ""); - return safe; - } - - public static String getHostPart(String nfsPath) { - String toks[] = nfsPath.split(":"); - if (toks != null && toks.length == 2) { - return toks[0]; - } - return null; - } - -} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/com/cloud/utils/net/UrlUtil.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/net/UrlUtil.java b/utils/src/com/cloud/utils/net/UrlUtil.java deleted file mode 100644 index 539486e..0000000 --- a/utils/src/com/cloud/utils/net/UrlUtil.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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.cloud.utils.net; - -import java.net.URI; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -public class UrlUtil { - public final static Map<String, String> parseQueryParameters(String query) { - HashMap<String, String> values = new HashMap<String, String>(); - parseQueryParameters(query, false, values); - - return values; - } - - public final static Map<String, String> parseQueryParameters(URL url) { - return parseQueryParameters(url.getQuery()); - } - - public final static Map<String, String> parseQueryParameters(URI url) { - return parseQueryParameters(url.getQuery()); - } - - public final static void parseQueryParameters(String query, boolean lowercaseKeys, Map<String, String> params) { - if (query == null) { - return; - } - - if (query.startsWith("?")) { - query = query.substring(1); - } - - String[] parts = query.split("&"); - for (String part : parts) { - String[] tokens = part.split("="); - - if (lowercaseKeys) { - tokens[0] = tokens[0].toLowerCase(); - } - - params.put(tokens[0], tokens[1]); - } - } -} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/com/cloud/utils/nio/HandlerFactory.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/nio/HandlerFactory.java b/utils/src/com/cloud/utils/nio/HandlerFactory.java deleted file mode 100644 index f6b9c82..0000000 --- a/utils/src/com/cloud/utils/nio/HandlerFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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.cloud.utils.nio; - -/** - * WorkerFactory creates and selects workers. - */ -public interface HandlerFactory { - public Task create(Task.Type type, Link link, byte[] data); - -} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/com/cloud/utils/nio/Link.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/nio/Link.java b/utils/src/com/cloud/utils/nio/Link.java deleted file mode 100644 index 6d6306a..0000000 --- a/utils/src/com/cloud/utils/nio/Link.java +++ /dev/null @@ -1,567 +0,0 @@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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.cloud.utils.nio; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetSocketAddress; -import java.net.SocketTimeoutException; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.SocketChannel; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.util.concurrent.ConcurrentLinkedQueue; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLEngineResult; -import javax.net.ssl.SSLEngineResult.HandshakeStatus; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; - -import org.apache.cloudstack.utils.security.SSLUtils; -import org.apache.log4j.Logger; - -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.db.DbProperties; - -/** - */ -public class Link { - private static final Logger s_logger = Logger.getLogger(Link.class); - - private final InetSocketAddress _addr; - private final NioConnection _connection; - private SelectionKey _key; - private final ConcurrentLinkedQueue<ByteBuffer[]> _writeQueue; - private ByteBuffer _readBuffer; - private ByteBuffer _plaintextBuffer; - private Object _attach; - private boolean _readHeader; - private boolean _gotFollowingPacket; - - private SSLEngine _sslEngine; - public static final String keystoreFile = "/cloudmanagementserver.keystore"; - - public Link(InetSocketAddress addr, NioConnection connection) { - _addr = addr; - _connection = connection; - _readBuffer = ByteBuffer.allocate(2048); - _attach = null; - _key = null; - _writeQueue = new ConcurrentLinkedQueue<ByteBuffer[]>(); - _readHeader = true; - _gotFollowingPacket = false; - } - - public Link(Link link) { - this(link._addr, link._connection); - } - - public Object attachment() { - return _attach; - } - - public void attach(Object attach) { - _attach = attach; - } - - public void setKey(SelectionKey key) { - synchronized (this) { - _key = key; - } - } - - public void setSSLEngine(SSLEngine sslEngine) { - _sslEngine = sslEngine; - } - - /** - * No user, so comment it out. - * - * Static methods for reading from a channel in case - * you need to add a client that doesn't require nio. - * @param ch channel to read from. - * @param bytebuffer to use. - * @return bytes read - * @throws IOException if not read to completion. - public static byte[] read(SocketChannel ch, ByteBuffer buff) throws IOException { - synchronized(buff) { - buff.clear(); - buff.limit(4); - - while (buff.hasRemaining()) { - if (ch.read(buff) == -1) { - throw new IOException("Connection closed with -1 on reading size."); - } - } - - buff.flip(); - - int length = buff.getInt(); - ByteArrayOutputStream output = new ByteArrayOutputStream(length); - WritableByteChannel outCh = Channels.newChannel(output); - - int count = 0; - while (count < length) { - buff.clear(); - int read = ch.read(buff); - if (read < 0) { - throw new IOException("Connection closed with -1 on reading data."); - } - count += read; - buff.flip(); - outCh.write(buff); - } - - return output.toByteArray(); - } - } - */ - - private static void doWrite(SocketChannel ch, ByteBuffer[] buffers, SSLEngine sslEngine) throws IOException { - SSLSession sslSession = sslEngine.getSession(); - ByteBuffer pkgBuf = ByteBuffer.allocate(sslSession.getPacketBufferSize() + 40); - SSLEngineResult engResult; - - ByteBuffer headBuf = ByteBuffer.allocate(4); - - int totalLen = 0; - for (ByteBuffer buffer : buffers) { - totalLen += buffer.limit(); - } - - int processedLen = 0; - while (processedLen < totalLen) { - headBuf.clear(); - pkgBuf.clear(); - engResult = sslEngine.wrap(buffers, pkgBuf); - if (engResult.getHandshakeStatus() != HandshakeStatus.FINISHED && engResult.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING && - engResult.getStatus() != SSLEngineResult.Status.OK) { - throw new IOException("SSL: SSLEngine return bad result! " + engResult); - } - - processedLen = 0; - for (ByteBuffer buffer : buffers) { - processedLen += buffer.position(); - } - - int dataRemaining = pkgBuf.position(); - int header = dataRemaining; - int headRemaining = 4; - pkgBuf.flip(); - if (processedLen < totalLen) { - header = header | HEADER_FLAG_FOLLOWING; - } - headBuf.putInt(header); - headBuf.flip(); - - while (headRemaining > 0) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Writing Header " + headRemaining); - } - long count = ch.write(headBuf); - headRemaining -= count; - } - while (dataRemaining > 0) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Writing Data " + dataRemaining); - } - long count = ch.write(pkgBuf); - dataRemaining -= count; - } - } - } - - /** - * write method to write to a socket. This method writes to completion so - * it doesn't follow the nio standard. We use this to make sure we write - * our own protocol. - * - * @param ch channel to write to. - * @param buffers buffers to write. - * @throws IOException if unable to write to completion. - */ - public static void write(SocketChannel ch, ByteBuffer[] buffers, SSLEngine sslEngine) throws IOException { - synchronized (ch) { - doWrite(ch, buffers, sslEngine); - } - } - - /* SSL has limitation of 16k, we may need to split packets. 18000 is 16k + some extra SSL informations */ - protected static final int MAX_SIZE_PER_PACKET = 18000; - protected static final int HEADER_FLAG_FOLLOWING = 0x10000; - - public byte[] read(SocketChannel ch) throws IOException { - if (_readHeader) { // Start of a packet - if (_readBuffer.position() == 0) { - _readBuffer.limit(4); - } - - if (ch.read(_readBuffer) == -1) { - throw new IOException("Connection closed with -1 on reading size."); - } - - if (_readBuffer.hasRemaining()) { - s_logger.trace("Need to read the rest of the packet length"); - return null; - } - _readBuffer.flip(); - int header = _readBuffer.getInt(); - int readSize = (short)header; - if (s_logger.isTraceEnabled()) { - s_logger.trace("Packet length is " + readSize); - } - - if (readSize > MAX_SIZE_PER_PACKET) { - throw new IOException("Wrong packet size: " + readSize); - } - - if (!_gotFollowingPacket) { - _plaintextBuffer = ByteBuffer.allocate(2000); - } - - if ((header & HEADER_FLAG_FOLLOWING) != 0) { - _gotFollowingPacket = true; - } else { - _gotFollowingPacket = false; - } - - _readBuffer.clear(); - _readHeader = false; - - if (_readBuffer.capacity() < readSize) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Resizing the byte buffer from " + _readBuffer.capacity()); - } - _readBuffer = ByteBuffer.allocate(readSize); - } - _readBuffer.limit(readSize); - } - - if (ch.read(_readBuffer) == -1) { - throw new IOException("Connection closed with -1 on read."); - } - - if (_readBuffer.hasRemaining()) { // We're not done yet. - if (s_logger.isTraceEnabled()) { - s_logger.trace("Still has " + _readBuffer.remaining()); - } - return null; - } - - _readBuffer.flip(); - - ByteBuffer appBuf; - - SSLSession sslSession = _sslEngine.getSession(); - SSLEngineResult engResult; - int remaining = 0; - - while (_readBuffer.hasRemaining()) { - remaining = _readBuffer.remaining(); - appBuf = ByteBuffer.allocate(sslSession.getApplicationBufferSize() + 40); - engResult = _sslEngine.unwrap(_readBuffer, appBuf); - if (engResult.getHandshakeStatus() != HandshakeStatus.FINISHED && engResult.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING && - engResult.getStatus() != SSLEngineResult.Status.OK) { - throw new IOException("SSL: SSLEngine return bad result! " + engResult); - } - if (remaining == _readBuffer.remaining()) { - throw new IOException("SSL: Unable to unwrap received data! still remaining " + remaining + "bytes!"); - } - - appBuf.flip(); - if (_plaintextBuffer.remaining() < appBuf.limit()) { - // We need to expand _plaintextBuffer for more data - ByteBuffer newBuffer = ByteBuffer.allocate(_plaintextBuffer.capacity() + appBuf.limit() * 5); - _plaintextBuffer.flip(); - newBuffer.put(_plaintextBuffer); - _plaintextBuffer = newBuffer; - } - _plaintextBuffer.put(appBuf); - if (s_logger.isTraceEnabled()) { - s_logger.trace("Done with packet: " + appBuf.limit()); - } - } - - _readBuffer.clear(); - _readHeader = true; - - if (!_gotFollowingPacket) { - _plaintextBuffer.flip(); - byte[] result = new byte[_plaintextBuffer.limit()]; - _plaintextBuffer.get(result); - return result; - } else { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Waiting for more packets"); - } - return null; - } - } - - public void send(byte[] data) throws ClosedChannelException { - send(data, false); - } - - public void send(byte[] data, boolean close) throws ClosedChannelException { - send(new ByteBuffer[] {ByteBuffer.wrap(data)}, close); - } - - public void send(ByteBuffer[] data, boolean close) throws ClosedChannelException { - ByteBuffer[] item = new ByteBuffer[data.length + 1]; - int remaining = 0; - for (int i = 0; i < data.length; i++) { - remaining += data[i].remaining(); - item[i + 1] = data[i]; - } - - item[0] = ByteBuffer.allocate(4); - item[0].putInt(remaining); - item[0].flip(); - - if (s_logger.isTraceEnabled()) { - s_logger.trace("Sending packet of length " + remaining); - } - - _writeQueue.add(item); - if (close) { - _writeQueue.add(new ByteBuffer[0]); - } - synchronized (this) { - if (_key == null) { - throw new ClosedChannelException(); - } - _connection.change(SelectionKey.OP_WRITE, _key, null); - } - } - - public void send(ByteBuffer[] data) throws ClosedChannelException { - send(data, false); - } - - public synchronized void close() { - if (_key != null) { - _connection.close(_key); - } - } - - public boolean write(SocketChannel ch) throws IOException { - ByteBuffer[] data = null; - while ((data = _writeQueue.poll()) != null) { - if (data.length == 0) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Closing connection requested"); - } - return true; - } - - ByteBuffer[] raw_data = new ByteBuffer[data.length - 1]; - System.arraycopy(data, 1, raw_data, 0, data.length - 1); - - doWrite(ch, raw_data, _sslEngine); - } - return false; - } - - public InetSocketAddress getSocketAddress() { - return _addr; - } - - public String getIpAddress() { - return _addr.getAddress().toString(); - } - - public synchronized void terminated() { - _key = null; - } - - public synchronized void schedule(Task task) throws ClosedChannelException { - if (_key == null) { - throw new ClosedChannelException(); - } - _connection.scheduleTask(task); - } - - public static SSLContext initSSLContext(boolean isClient) throws GeneralSecurityException, IOException { - InputStream stream; - SSLContext sslContext = null; - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - KeyStore ks = KeyStore.getInstance("JKS"); - TrustManager[] tms; - - File confFile = PropertiesUtil.findConfigFile("db.properties"); - if (null != confFile && !isClient) { - final String pass = DbProperties.getDbProperties().getProperty("db.cloud.keyStorePassphrase"); - char[] passphrase = "vmops.com".toCharArray(); - if (pass != null) { - passphrase = pass.toCharArray(); - } - String confPath = confFile.getParent(); - String keystorePath = confPath + keystoreFile; - if (new File(keystorePath).exists()) { - stream = new FileInputStream(keystorePath); - } else { - s_logger.warn("SSL: Fail to find the generated keystore. Loading fail-safe one to continue."); - stream = NioConnection.class.getResourceAsStream("/cloud.keystore"); - passphrase = "vmops.com".toCharArray(); - } - ks.load(stream, passphrase); - stream.close(); - kmf.init(ks, passphrase); - tmf.init(ks); - tms = tmf.getTrustManagers(); - } else { - ks.load(null, null); - kmf.init(ks, null); - tms = new TrustManager[1]; - tms[0] = new TrustAllManager(); - } - - sslContext = SSLUtils.getSSLContext(); - sslContext.init(kmf.getKeyManagers(), tms, null); - if (s_logger.isTraceEnabled()) { - s_logger.trace("SSL: SSLcontext has been initialized"); - } - - return sslContext; - } - - public static void doHandshake(SocketChannel ch, SSLEngine sslEngine, boolean isClient) throws IOException { - if (s_logger.isTraceEnabled()) { - s_logger.trace("SSL: begin Handshake, isClient: " + isClient); - } - - SSLEngineResult engResult; - SSLSession sslSession = sslEngine.getSession(); - HandshakeStatus hsStatus; - ByteBuffer in_pkgBuf = ByteBuffer.allocate(sslSession.getPacketBufferSize() + 40); - ByteBuffer in_appBuf = ByteBuffer.allocate(sslSession.getApplicationBufferSize() + 40); - ByteBuffer out_pkgBuf = ByteBuffer.allocate(sslSession.getPacketBufferSize() + 40); - ByteBuffer out_appBuf = ByteBuffer.allocate(sslSession.getApplicationBufferSize() + 40); - int count; - ch.socket().setSoTimeout(60 * 1000); - InputStream inStream = ch.socket().getInputStream(); - // Use readCh to make sure the timeout on reading is working - ReadableByteChannel readCh = Channels.newChannel(inStream); - - if (isClient) { - hsStatus = SSLEngineResult.HandshakeStatus.NEED_WRAP; - } else { - hsStatus = SSLEngineResult.HandshakeStatus.NEED_UNWRAP; - } - - while (hsStatus != SSLEngineResult.HandshakeStatus.FINISHED) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("SSL: Handshake status " + hsStatus); - } - engResult = null; - if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP) { - out_pkgBuf.clear(); - out_appBuf.clear(); - out_appBuf.put("Hello".getBytes()); - engResult = sslEngine.wrap(out_appBuf, out_pkgBuf); - out_pkgBuf.flip(); - int remain = out_pkgBuf.limit(); - while (remain != 0) { - remain -= ch.write(out_pkgBuf); - if (remain < 0) { - throw new IOException("Too much bytes sent?"); - } - } - } else if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { - in_appBuf.clear(); - // One packet may contained multiply operation - if (in_pkgBuf.position() == 0 || !in_pkgBuf.hasRemaining()) { - in_pkgBuf.clear(); - count = 0; - try { - count = readCh.read(in_pkgBuf); - } catch (SocketTimeoutException ex) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Handshake reading time out! Cut the connection"); - } - count = -1; - } - if (count == -1) { - throw new IOException("Connection closed with -1 on reading size."); - } - in_pkgBuf.flip(); - } - engResult = sslEngine.unwrap(in_pkgBuf, in_appBuf); - ByteBuffer tmp_pkgBuf = ByteBuffer.allocate(sslSession.getPacketBufferSize() + 40); - int loop_count = 0; - while (engResult.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) { - // The client is too slow? Cut it and let it reconnect - if (loop_count > 10) { - throw new IOException("Too many times in SSL BUFFER_UNDERFLOW, disconnect guest."); - } - // We need more packets to complete this operation - if (s_logger.isTraceEnabled()) { - s_logger.trace("SSL: Buffer underflowed, getting more packets"); - } - tmp_pkgBuf.clear(); - count = ch.read(tmp_pkgBuf); - if (count == -1) { - throw new IOException("Connection closed with -1 on reading size."); - } - tmp_pkgBuf.flip(); - - in_pkgBuf.mark(); - in_pkgBuf.position(in_pkgBuf.limit()); - in_pkgBuf.limit(in_pkgBuf.limit() + tmp_pkgBuf.limit()); - in_pkgBuf.put(tmp_pkgBuf); - in_pkgBuf.reset(); - - in_appBuf.clear(); - engResult = sslEngine.unwrap(in_pkgBuf, in_appBuf); - loop_count++; - } - } else if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) { - Runnable run; - while ((run = sslEngine.getDelegatedTask()) != null) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("SSL: Running delegated task!"); - } - run.run(); - } - } else if (hsStatus == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { - throw new IOException("NOT a handshaking!"); - } - if (engResult != null && engResult.getStatus() != SSLEngineResult.Status.OK) { - throw new IOException("Fail to handshake! " + engResult.getStatus()); - } - if (engResult != null) - hsStatus = engResult.getHandshakeStatus(); - else - hsStatus = sslEngine.getHandshakeStatus(); - } - } - -}
