Skip to content

Commit 5cfc8f9

Browse files
committed
[#1415] Improved offsetAddres
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.
1 parent e8c3f1a commit 5cfc8f9

File tree

3 files changed

+15
-10
lines changed

3 files changed

+15
-10
lines changed

src/lib/asiolink/addr_utilities.cc

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -381,21 +381,23 @@ IOAddress offsetAddress(const IOAddress& addr, uint64_t offset) {
381381

382382
// If this is IPv4 addrss we utilize the conversion to uint32_t.
383383
if (addr.isV4()) {
384-
return (IOAddress(addr.toUint32() + offset));
384+
auto addr_uint32 = static_cast<uint64_t>(addr.toUint32());
385+
// If the result would exceed the maximum possible IPv4 address, let's return
386+
// the maximum IPv4 address.
387+
if (static_cast<uint64_t>(std::numeric_limits<uint32_t>::max() - addr_uint32) < offset) {
388+
return (IOAddress(std::numeric_limits<uint32_t>::max()));
389+
}
390+
return (IOAddress(static_cast<uint32_t>(addr_uint32 + offset)));
385391
}
386392

387393
// This is IPv6 address. Let's first convert the offset value to network
388394
// byte order and store within the vector.
389395
std::vector<uint8_t> offset_bytes(8);
390396
int offset_idx = 0;
391-
offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0xff00000000000000) >> 56);
392-
offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x00ff000000000000) >> 48);
393-
offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x0000ff0000000000) >> 40);
394-
offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x000000ff00000000) >> 32);
395-
offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x00000000ff000000) >> 24);
396-
offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x0000000000ff0000) >> 16);
397-
offset_bytes[offset_idx++] = static_cast<uint8_t>((offset & 0x000000000000ff00) >> 8);
398-
offset_bytes[offset_idx++] = static_cast<uint8_t>(offset & 0x00000000000000ff);
397+
for (int offset_idx = offset_bytes.size() - 1; offset_idx >= 0; --offset_idx) {
398+
offset_bytes[offset_idx] = static_cast<uint8_t>(offset & 0x00000000000000ff);
399+
offset = offset >> 8;
400+
}
399401

400402
// Convert the IPv6 address to vector.
401403
auto addr_bytes = addr.toBytes();

src/lib/asiolink/addr_utilities.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ uint64_t prefixesInRange(const uint8_t pool_len, const uint8_t delegated_len);
8484
///
8585
/// Adds offset to the IPv4 or iPv6 address and finds the resulting address.
8686
/// Note that the current limitation is the maximum value of the offset,
87-
/// i.e. max uint64_t.
87+
/// i.e. max uint64_t. If the sum of the IPv4 address and the offset exceeds
88+
/// the maximum value of uint32_t type, the 255.255.255.255 is returned.
8889
///
8990
/// @param addr input address
9091
/// @param offset distance of the returned address from the input address.

src/lib/asiolink/tests/addr_utilities_unittest.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ TEST(AddrUtilitiesTest, prefixesInRange) {
371371
TEST(AddrUtilitiesTest, offsetIPv4Address) {
372372
EXPECT_EQ("10.1.2.46", offsetAddress(IOAddress("10.1.1.45"), 257).toText());
373373
EXPECT_EQ("10.1.7.9", offsetAddress(IOAddress("10.1.1.45"), 1500).toText());
374+
// Using very large offset. The maximum IPv4 address should be returned.
375+
EXPECT_EQ("255.255.255.255", offsetAddress(IOAddress("255.255.254.254"), 0xFFFFFFFFFFFFFFFA).toText());
374376
}
375377

376378
// Checks the function which finds an IPv6 address from input address and offset.

0 commit comments

Comments
 (0)