Return-Path: X-Original-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9545DE76A for ; Wed, 6 Feb 2013 01:41:59 +0000 (UTC) Received: (qmail 3226 invoked by uid 500); 6 Feb 2013 01:41:59 -0000 Delivered-To: apmail-incubator-cloudstack-commits-archive@incubator.apache.org Received: (qmail 3194 invoked by uid 500); 6 Feb 2013 01:41:59 -0000 Mailing-List: contact cloudstack-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: cloudstack-dev@incubator.apache.org Delivered-To: mailing list cloudstack-commits@incubator.apache.org Received: (qmail 3187 invoked by uid 99); 6 Feb 2013 01:41:59 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Feb 2013 01:41:59 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 372BD82AB81; Wed, 6 Feb 2013 01:41:59 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: yasker@apache.org To: cloudstack-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: git commit: refs/heads/network-refactor - IPv6: CLOUDSTACK-1153: Fix integer overflow on IPv6 address calcuation Message-Id: <20130206014159.372BD82AB81@tyr.zones.apache.org> Date: Wed, 6 Feb 2013 01:41:59 +0000 (UTC) Updated Branches: refs/heads/network-refactor ec206d69b -> 95e63bc1c 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/95e63bc1 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/95e63bc1 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/95e63bc1 Branch: refs/heads/network-refactor Commit: 95e63bc1cfe36a451d317a88ed8125d2bdcea864 Parents: ec206d6 Author: Sheng Yang Authored: Tue Feb 5 17:32:40 2013 -0800 Committer: Sheng Yang Committed: Tue Feb 5 17:32:40 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/95e63bc1/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 f682a06..70debc0 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; @@ -550,8 +551,9 @@ public class NetworkModelImpl implements NetworkModel, Manager{ } 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/95e63bc1/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 2772ce4..b941a41 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -20,6 +20,7 @@ import java.io.BufferedReader; import java.io.File; 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; @@ -1175,19 +1176,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(); } @@ -1197,11 +1204,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]; } @@ -1210,13 +1227,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/95e63bc1/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 ccf0991..fae49fd 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; @@ -83,13 +84,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); @@ -104,9 +110,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"));