You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ya...@apache.org on 2013/02/06 02:41:21 UTC
git commit: refs/heads/4.1 - IPv6: CLOUDSTACK-1153: Fix integer
overflow on IPv6 address calcuation
Updated Branches:
refs/heads/4.1 5793a0c59 -> 659955483
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/65995548
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/65995548
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/65995548
Branch: refs/heads/4.1
Commit: 659955483d46d0a5b156ca3637efc045464ebae6
Parents: 5793a0c
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:12 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/65995548/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/65995548/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/65995548/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"));