Passing const uint8_t* will not work as long as the argument of the method is a reference to an array: CNetAddr::SetLegacyIPv6(const uint8_t (&ipv6)[ADDR_IPV6_SIZE]) which is best of type safety but unfortunately two of the callers don't have an array to pass.
I think either one of the following two is better:
<details>
<summary>change argument to void*</summary>
diff --git i/src/netaddress.cpp w/src/netaddress.cpp
index b421e1b11..bb4d2b50b 100644
--- i/src/netaddress.cpp
+++ w/src/netaddress.cpp
@@ -26,32 +26,33 @@ CNetAddr::CNetAddr() {}
void CNetAddr::SetIP(const CNetAddr& ipIn)
{
m_net = ipIn.m_net;
m_addr = ipIn.m_addr;
}
-void CNetAddr::SetLegacyIPv6(const uint8_t (&ipv6)[ADDR_IPV6_SIZE])
+void CNetAddr::SetLegacyIPv6(const void* ipv6)
{
- const uint8_t* ipv6_end = ipv6 + ADDR_IPV6_SIZE;
+ const uint8_t* ipv6_begin = static_cast<const uint8_t*>(ipv6);
+ const uint8_t* ipv6_end = ipv6_begin + ADDR_IPV6_SIZE;
- if (memcmp(ipv6, IPV4_IN_IPV6_PREFIX, sizeof(IPV4_IN_IPV6_PREFIX)) == 0) {
+ if (memcmp(ipv6_begin, IPV4_IN_IPV6_PREFIX, sizeof(IPV4_IN_IPV6_PREFIX)) == 0) {
// IPv4-in-IPv6
m_net = NET_IPV4;
- m_addr.assign(ipv6 + sizeof(IPV4_IN_IPV6_PREFIX), ipv6_end);
- } else if (memcmp(ipv6, TORV2_IN_IPV6_PREFIX, sizeof(TORV2_IN_IPV6_PREFIX)) == 0) {
+ m_addr.assign(ipv6_begin + sizeof(IPV4_IN_IPV6_PREFIX), ipv6_end);
+ } else if (memcmp(ipv6_begin, TORV2_IN_IPV6_PREFIX, sizeof(TORV2_IN_IPV6_PREFIX)) == 0) {
// TORv2-in-IPv6
m_net = NET_ONION;
- m_addr.assign(ipv6 + sizeof(TORV2_IN_IPV6_PREFIX), ipv6_end);
- } else if (memcmp(ipv6, INTERNAL_IN_IPV6_PREFIX, sizeof(INTERNAL_IN_IPV6_PREFIX)) == 0) {
+ m_addr.assign(ipv6_begin + sizeof(TORV2_IN_IPV6_PREFIX), ipv6_end);
+ } else if (memcmp(ipv6_begin, INTERNAL_IN_IPV6_PREFIX, sizeof(INTERNAL_IN_IPV6_PREFIX)) == 0) {
// Internal-in-IPv6
m_net = NET_INTERNAL;
- m_addr.assign(ipv6 + sizeof(INTERNAL_IN_IPV6_PREFIX), ipv6_end);
+ m_addr.assign(ipv6_begin + sizeof(INTERNAL_IN_IPV6_PREFIX), ipv6_end);
} else {
// IPv6
m_net = NET_IPV6;
- m_addr.assign(ipv6, ipv6_end);
+ m_addr.assign(ipv6_begin, ipv6_end);
}
}
/**
* Try to make this a dummy address that maps the specified name into IPv6 like
* so: (0xFD + %sha256("bitcoin")[0:5]) + %sha256(name)[0:10]. Such dummy
@@ -105,13 +106,13 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
m_addr.assign(ptr, ptr + ADDR_IPV4_SIZE);
}
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
{
assert(sizeof(ipv6Addr) == ADDR_IPV6_SIZE);
- SetLegacyIPv6(*reinterpret_cast<const uint8_t (*)[ADDR_IPV6_SIZE]>(&ipv6Addr));
+ SetLegacyIPv6(&ipv6Addr);
scopeId = scope;
}
bool CNetAddr::IsBindAny() const
{
if (!IsIPv4() && !IsIPv6()) {
diff --git i/src/netaddress.h w/src/netaddress.h
index 8924ed0b4..ca048fbf5 100644
--- i/src/netaddress.h
+++ w/src/netaddress.h
@@ -105,13 +105,13 @@ class CNetAddr
/**
* Set from a legacy IPv6 address.
* Legacy IPv6 address may be a normal IPv6 address, or another address
* (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy
* `addr` encoding.
*/
- void SetLegacyIPv6(const uint8_t (&ipv6)[ADDR_IPV6_SIZE]);
+ void SetLegacyIPv6(const void* ipv6);
bool SetInternal(const std::string& name);
bool SetSpecial(const std::string &strName); // for Tor addresses
bool IsBindAny() const; // INADDR_ANY equivalent
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
diff --git i/src/test/fuzz/asmap.cpp w/src/test/fuzz/asmap.cpp
index 84902ee2d..98ac82453 100644
--- i/src/test/fuzz/asmap.cpp
+++ w/src/test/fuzz/asmap.cpp
@@ -45,13 +45,13 @@ void test_one_input(const std::vector<uint8_t>& buffer)
if (!SanityCheckASMap(asmap)) return;
const uint8_t* addr_data = buffer.data() + 1 + asmap_size;
CNetAddr net_addr;
if (ipv6) {
assert(addr_size == ADDR_IPV6_SIZE);
- net_addr.SetLegacyIPv6(*reinterpret_cast<const uint8_t (*)[ADDR_IPV6_SIZE]>(addr_data));
+ net_addr.SetLegacyIPv6(addr_data);
} else {
assert(addr_size == ADDR_IPV4_SIZE);
in_addr ipv4;
memcpy(&ipv4, addr_data, addr_size);
net_addr.SetIP(CNetAddr{ipv4});
}
</details>
<details>
<summary>change argument to Span</summary>
diff --git i/src/netaddress.cpp w/src/netaddress.cpp
index b421e1b11..121b92650 100644
--- i/src/netaddress.cpp
+++ w/src/netaddress.cpp
@@ -26,32 +26,32 @@ CNetAddr::CNetAddr() {}
void CNetAddr::SetIP(const CNetAddr& ipIn)
{
m_net = ipIn.m_net;
m_addr = ipIn.m_addr;
}
-void CNetAddr::SetLegacyIPv6(const uint8_t (&ipv6)[ADDR_IPV6_SIZE])
+void CNetAddr::SetLegacyIPv6(Span<const uint8_t> ipv6)
{
- const uint8_t* ipv6_end = ipv6 + ADDR_IPV6_SIZE;
+ assert(ipv6.size() == ADDR_IPV6_SIZE);
- if (memcmp(ipv6, IPV4_IN_IPV6_PREFIX, sizeof(IPV4_IN_IPV6_PREFIX)) == 0) {
+ if (memcmp(ipv6.begin(), IPV4_IN_IPV6_PREFIX, sizeof(IPV4_IN_IPV6_PREFIX)) == 0) {
// IPv4-in-IPv6
m_net = NET_IPV4;
- m_addr.assign(ipv6 + sizeof(IPV4_IN_IPV6_PREFIX), ipv6_end);
- } else if (memcmp(ipv6, TORV2_IN_IPV6_PREFIX, sizeof(TORV2_IN_IPV6_PREFIX)) == 0) {
+ m_addr.assign(ipv6.begin() + sizeof(IPV4_IN_IPV6_PREFIX), ipv6.end());
+ } else if (memcmp(ipv6.begin(), TORV2_IN_IPV6_PREFIX, sizeof(TORV2_IN_IPV6_PREFIX)) == 0) {
// TORv2-in-IPv6
m_net = NET_ONION;
- m_addr.assign(ipv6 + sizeof(TORV2_IN_IPV6_PREFIX), ipv6_end);
- } else if (memcmp(ipv6, INTERNAL_IN_IPV6_PREFIX, sizeof(INTERNAL_IN_IPV6_PREFIX)) == 0) {
+ m_addr.assign(ipv6.begin() + sizeof(TORV2_IN_IPV6_PREFIX), ipv6.end());
+ } else if (memcmp(ipv6.begin(), INTERNAL_IN_IPV6_PREFIX, sizeof(INTERNAL_IN_IPV6_PREFIX)) == 0) {
// Internal-in-IPv6
m_net = NET_INTERNAL;
- m_addr.assign(ipv6 + sizeof(INTERNAL_IN_IPV6_PREFIX), ipv6_end);
+ m_addr.assign(ipv6.begin() + sizeof(INTERNAL_IN_IPV6_PREFIX), ipv6.end());
} else {
// IPv6
m_net = NET_IPV6;
- m_addr.assign(ipv6, ipv6_end);
+ m_addr.assign(ipv6.begin(), ipv6.end());
}
}
/**
* Try to make this a dummy address that maps the specified name into IPv6 like
* so: (0xFD + %sha256("bitcoin")[0:5]) + %sha256(name)[0:10]. Such dummy
@@ -104,14 +104,13 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&ipv4Addr);
m_addr.assign(ptr, ptr + ADDR_IPV4_SIZE);
}
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
{
- assert(sizeof(ipv6Addr) == ADDR_IPV6_SIZE);
- SetLegacyIPv6(*reinterpret_cast<const uint8_t (*)[ADDR_IPV6_SIZE]>(&ipv6Addr));
+ SetLegacyIPv6(Span<const uint8_t>(reinterpret_cast<const uint8_t*>(&ipv6Addr), sizeof(ipv6Addr)));
scopeId = scope;
}
bool CNetAddr::IsBindAny() const
{
if (!IsIPv4() && !IsIPv6()) {
diff --git i/src/netaddress.h w/src/netaddress.h
index 8924ed0b4..a76b5e9ce 100644
--- i/src/netaddress.h
+++ w/src/netaddress.h
@@ -105,13 +105,13 @@ class CNetAddr
/**
* Set from a legacy IPv6 address.
* Legacy IPv6 address may be a normal IPv6 address, or another address
* (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy
* `addr` encoding.
*/
- void SetLegacyIPv6(const uint8_t (&ipv6)[ADDR_IPV6_SIZE]);
+ void SetLegacyIPv6(Span<const uint8_t> ipv6);
bool SetInternal(const std::string& name);
bool SetSpecial(const std::string &strName); // for Tor addresses
bool IsBindAny() const; // INADDR_ANY equivalent
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
diff --git i/src/test/fuzz/asmap.cpp w/src/test/fuzz/asmap.cpp
index 84902ee2d..e3aefa18a 100644
--- i/src/test/fuzz/asmap.cpp
+++ w/src/test/fuzz/asmap.cpp
@@ -45,13 +45,13 @@ void test_one_input(const std::vector<uint8_t>& buffer)
if (!SanityCheckASMap(asmap)) return;
const uint8_t* addr_data = buffer.data() + 1 + asmap_size;
CNetAddr net_addr;
if (ipv6) {
assert(addr_size == ADDR_IPV6_SIZE);
- net_addr.SetLegacyIPv6(*reinterpret_cast<const uint8_t (*)[ADDR_IPV6_SIZE]>(addr_data));
+ net_addr.SetLegacyIPv6(Span<const uint8_t>(addr_data, addr_size));
} else {
assert(addr_size == ADDR_IPV4_SIZE);
in_addr ipv4;
memcpy(&ipv4, addr_data, addr_size);
net_addr.SetIP(CNetAddr{ipv4});
}
</details>
What do you think?