You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bf...@apache.org on 2013/02/07 21:04:12 UTC

[9/51] [abbrv] git commit: refs/heads/ui-plugins - IPv6: CLOUDSTACK-1153: Fix integer overflow on IPv6 address calcuation

IPv6: CLOUDSTACK-1153: Fix integer overflow on IPv6 address calcuation

Use BigInteger, which is 128 bits long.


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/fda8ec3c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/fda8ec3c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/fda8ec3c

Branch: refs/heads/ui-plugins
Commit: fda8ec3c594d16a710b9baeb04b9682e7d86e6b4
Parents: e81389a
Author: Sheng Yang <sh...@citrix.com>
Authored: Tue Feb 5 17:32:40 2013 -0800
Committer: Sheng Yang <sh...@citrix.com>
Committed: Tue Feb 5 17:41:37 2013 -0800

----------------------------------------------------------------------
 server/src/com/cloud/network/NetworkModelImpl.java |    6 +-
 utils/src/com/cloud/utils/net/NetUtils.java        |   50 ++++++++++-----
 utils/test/com/cloud/utils/net/NetUtilsTest.java   |   19 ++++--
 3 files changed, 52 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fda8ec3c/server/src/com/cloud/network/NetworkModelImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index 6e22782..f8d0add 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -17,6 +17,7 @@
 
 package com.cloud.network;
 
+import java.math.BigInteger;
 import java.security.InvalidParameterException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -556,8 +557,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
     	}
     	Vlan vlan = getVlanForNetwork(network.getId());
     	long existedCount = _ipv6Dao.countExistedIpsInNetwork(network.getId());
-    	long rangeCount = NetUtils.countIp6InRange(vlan.getIp6Range());
-		return (existedCount < rangeCount);
+    	BigInteger existedInt = BigInteger.valueOf(existedCount);
+    	BigInteger rangeInt = NetUtils.countIp6InRange(vlan.getIp6Range());
+		return (existedInt.compareTo(rangeInt) < 0);
 	}
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fda8ec3c/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
index 0875f88..f6b62de 100755
--- a/utils/src/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/com/cloud/utils/net/NetUtils.java
@@ -19,6 +19,7 @@ package com.cloud.utils.net;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.lang.reflect.Array;
+import java.math.BigInteger;
 import java.net.InetAddress;
 import java.net.InterfaceAddress;
 import java.net.NetworkInterface;
@@ -1151,19 +1152,25 @@ public class NetUtils {
 		return network.getNetmask().asPrefixLength();
 	}
 
-	//FIXME: only able to cover lower 32 bits
+	// Can cover 127 bits
 	public static String getIp6FromRange(String ip6Range) {
     	String[] ips = ip6Range.split("-");
     	String startIp = ips[0];
     	IPv6Address start = IPv6Address.fromString(startIp);
-    	// Find a random number based on lower 32 bits
-    	long gap = countIp6InRange(ip6Range);
-    	if (gap > Integer.MAX_VALUE) {
-    		gap = Integer.MAX_VALUE;
+    	BigInteger gap = countIp6InRange(ip6Range);
+    	BigInteger next = new BigInteger(gap.bitLength(), _rand);
+    	while (next.compareTo(gap) >= 0) {
+    		next = new BigInteger(gap.bitLength(), _rand);
     	}
-    	int next = _rand.nextInt((int)(gap));
-    	// And a number based on the difference of lower 32 bits
-    	IPv6Address ip = start.add(next);
+    	BigInteger startInt = convertIPv6AddressToBigInteger(start);
+    	BigInteger resultInt = startInt.add(next);
+    	InetAddress resultAddr;
+		try {
+			resultAddr = InetAddress.getByAddress(resultInt.toByteArray());
+		} catch (UnknownHostException e) {
+			return null;
+		}
+    	IPv6Address ip = IPv6Address.fromInetAddress(resultAddr);
     	return ip.toString();
 	}
 
@@ -1173,11 +1180,21 @@ public class NetUtils {
 		return duid;
 	}
 	
-	//FIXME: only able to cover lower 64 bits
-	public static long countIp6InRange(String ip6Range) {
+	private static BigInteger convertIPv6AddressToBigInteger(IPv6Address addr) {
+		InetAddress inetAddr;
+		try {
+			inetAddr = addr.toInetAddress();
+		} catch (UnknownHostException e) {
+			return null;
+		}
+		return new BigInteger(inetAddr.getAddress());
+	}
+	
+	// Can cover 127 bits
+	public static BigInteger countIp6InRange(String ip6Range) {
     	String[] ips = ip6Range.split("-");
     	String startIp = ips[0];
-    	String endIp = null;
+    	String endIp = ips[0];
     	if (ips.length > 1) {
     		endIp = ips[1];
     	}
@@ -1186,13 +1203,14 @@ public class NetUtils {
     		start = IPv6Address.fromString(startIp);
     		end = IPv6Address.fromString(endIp);
 		} catch (IllegalArgumentException ex) {
-			return 0;
+			return null;
 		}
-    	long startLow = start.getLowBits(), endLow = end.getLowBits();
-    	if (startLow > endLow) {
-    		return 0;
+    	BigInteger startInt = convertIPv6AddressToBigInteger(start);
+    	BigInteger endInt = convertIPv6AddressToBigInteger(end);
+    	if (startInt.compareTo(endInt) > 0) {
+    		return null;
     	}
-    	return endLow - startLow + 1;
+    	return endInt.subtract(startInt).add(BigInteger.ONE);
 	}
 
 	public static boolean isIp6InRange(String ip6, String ip6Range) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fda8ec3c/utils/test/com/cloud/utils/net/NetUtilsTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java
index 686025e..09c6f60 100644
--- a/utils/test/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.utils.net;
 
+import java.math.BigInteger;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
@@ -84,13 +85,18 @@ public class NetUtilsTest extends TestCase {
     	assertFalse(NetUtils.isValidIp6Cidr("1234:5678::1"));
     	assertEquals(NetUtils.getIp6CidrSize("1234:5678::1/32"), 32);
     	assertEquals(NetUtils.getIp6CidrSize("1234:5678::1"), 0);
-    	assertEquals(NetUtils.countIp6InRange("1234:5678::1-1234:5678::2"), 2);
-    	assertEquals(NetUtils.countIp6InRange("1234:5678::2-1234:5678::0"), 0);
+    	BigInteger two = new BigInteger("2");
+    	assertEquals(NetUtils.countIp6InRange("1234:5678::1-1234:5678::2"), two);
+    	assertEquals(NetUtils.countIp6InRange("1234:5678::2-1234:5678::0"), null);
     	assertEquals(NetUtils.getIp6FromRange("1234:5678::1-1234:5678::1"), "1234:5678::1");
+    	for (int i = 0; i < 5; i ++) {
+    		String ip = NetUtils.getIp6FromRange("1234:5678::1-1234:5678::2");
+    		assertTrue(ip.equals("1234:5678::1") || ip.equals("1234:5678::2"));
+    		s_logger.info("IP is " + ip);
+    	}
     	String ipString = null;
-    	String range = "1234:5678::1-1234:5678::8000:0000";
     	IPv6Address ipStart = IPv6Address.fromString("1234:5678::1");
-    	IPv6Address ipEnd = IPv6Address.fromString("1234:5678::8000:0000");
+    	IPv6Address ipEnd = IPv6Address.fromString("1234:5678::ffff:ffff:ffff:ffff");
     	for (int i = 0; i < 10; i ++) {
     		ipString = NetUtils.getIp6FromRange(ipStart.toString() + "-" + ipEnd.toString());
     		s_logger.info("IP is " + ipString);
@@ -105,9 +111,12 @@ public class NetUtilsTest extends TestCase {
     	assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::ffff", "1234:5678::2-1234:5678::e"));
     	assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::f", "1234:5678::2-1234:5678::e"));
     	//Test getNextIp6InRange
-    	assertEquals(NetUtils.getNextIp6InRange("1234:5678::8000:0000", range), "1234:5678::1");
+    	String range = "1234:5678::1-1234:5678::8000:0000";
+    	assertEquals(NetUtils.getNextIp6InRange("1234:5678::8000:0", range), "1234:5678::1");
     	assertEquals(NetUtils.getNextIp6InRange("1234:5678::7fff:ffff", range), "1234:5678::8000:0");
     	assertEquals(NetUtils.getNextIp6InRange("1234:5678::1", range), "1234:5678::2");
+    	range = "1234:5678::1-1234:5678::ffff:ffff:ffff:ffff";
+    	assertEquals(NetUtils.getNextIp6InRange("1234:5678::ffff:ffff:ffff:ffff", range), "1234:5678::1");
     	//Test isIp6InNetwork
     	assertFalse(NetUtils.isIp6InNetwork("1234:5678:abcd::1", "1234:5678::/64"));
     	assertTrue(NetUtils.isIp6InNetwork("1234:5678::1", "1234:5678::/64"));