]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1415] Improved offsetAddres
authorMarcin Siodelski <marcin@isc.org>
Wed, 16 Sep 2020 10:26:34 +0000 (12:26 +0200)
committerMarcin Siodelski <marcin@isc.org>
Wed, 16 Sep 2020 14:39:12 +0000 (14:39 +0000)
According to the review comments, the conversion of the offset to a vector
was simplified. In addition, when the offset address exceeds the maximum
value for IPv4 address the max value is returned.

src/lib/asiolink/addr_utilities.cc
src/lib/asiolink/addr_utilities.h
src/lib/asiolink/tests/addr_utilities_unittest.cc

index a23780c54df04548be3782b0553703c07a80fbbb..b31e3ea8d2b9d6f59b73d7709780790372653497 100644 (file)
@@ -381,21 +381,23 @@ IOAddress offsetAddress(const IOAddress& addr, uint64_t offset) {
 
     // If this is IPv4 addrss we utilize the conversion to uint32_t.
     if (addr.isV4()) {
-        return (IOAddress(addr.toUint32() + offset));
+        auto addr_uint32 = static_cast<uint64_t>(addr.toUint32());
+        // If the result would exceed the maximum possible IPv4 address, let's return
+        // the maximum IPv4 address.
+        if (static_cast<uint64_t>(std::numeric_limits<uint32_t>::max() - addr_uint32) < offset) {
+            return (IOAddress(std::numeric_limits<uint32_t>::max()));
+        }
+        return (IOAddress(static_cast<uint32_t>(addr_uint32 + offset)));
     }
 
     // This is IPv6 address. Let's first convert the offset value to network
     // byte order and store within the vector.
     std::vector<uint8_t> offset_bytes(8);
     int offset_idx = 0;
-    offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0xff00000000000000) >> 56);
-    offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x00ff000000000000) >> 48);
-    offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x0000ff0000000000) >> 40);
-    offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x000000ff00000000) >> 32);
-    offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x00000000ff000000) >> 24);
-    offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x0000000000ff0000) >> 16);
-    offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x000000000000ff00) >> 8);
-    offset_bytes[offset_idx++] = static_cast<uint8_t>(offset &  0x00000000000000ff);
+    for (int offset_idx = offset_bytes.size() - 1; offset_idx >= 0; --offset_idx) {
+        offset_bytes[offset_idx] = static_cast<uint8_t>(offset & 0x00000000000000ff);
+        offset = offset >> 8;
+    }
 
     // Convert the IPv6 address to vector.
     auto addr_bytes = addr.toBytes();
index 3ad96a64c26bd30fe60a1337d71d7dccf9caa3bf..bd78deec4ca4a64e362ef7e90834a1ad0a0c2bf3 100644 (file)
@@ -84,7 +84,8 @@ uint64_t prefixesInRange(const uint8_t pool_len, const uint8_t delegated_len);
 ///
 /// Adds offset to the IPv4 or iPv6 address and finds the resulting address.
 /// Note that the current limitation is the maximum value of the offset,
-/// i.e. max uint64_t.
+/// i.e. max uint64_t. If the sum of the IPv4 address and the offset exceeds
+/// the maximum value of uint32_t type, the 255.255.255.255 is returned.
 ///
 /// @param addr input address
 /// @param offset distance of the returned address from the input address.
index b6121029d3fdfb03a79f0d659a197b84b45be05f..69aca84f2c9a6b6da8cf7c5d2a4263d100ff48b9 100644 (file)
@@ -371,6 +371,8 @@ TEST(AddrUtilitiesTest, prefixesInRange) {
 TEST(AddrUtilitiesTest, offsetIPv4Address) {
     EXPECT_EQ("10.1.2.46", offsetAddress(IOAddress("10.1.1.45"), 257).toText());
     EXPECT_EQ("10.1.7.9", offsetAddress(IOAddress("10.1.1.45"), 1500).toText());
+    // Using very large offset. The maximum IPv4 address should be returned.
+    EXPECT_EQ("255.255.255.255", offsetAddress(IOAddress("255.255.254.254"), 0xFFFFFFFFFFFFFFFA).toText());
 }
 
 // Checks the function which finds an IPv6 address from input address and offset.