From 3134535de0d95a540ec9e4b11812d4a7ac934462 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Thu, 19 Jan 2023 01:36:50 +0300 Subject: [PATCH 1/4] IPAddress u8 vs u32 fixes --- cores/esp8266/Client.h | 8 +------- cores/esp8266/IPAddress.cpp | 39 ++++++++++++++++++------------------- cores/esp8266/IPAddress.h | 36 +++++++++++++--------------------- cores/esp8266/Udp.h | 8 -------- 4 files changed, 34 insertions(+), 57 deletions(-) diff --git a/cores/esp8266/Client.h b/cores/esp8266/Client.h index 7f8f810458..2e21cb3b7f 100644 --- a/cores/esp8266/Client.h +++ b/cores/esp8266/Client.h @@ -38,13 +38,7 @@ class Client: public Stream { virtual void stop() = 0; virtual uint8_t connected() = 0; virtual operator bool() = 0; - protected: - uint8_t* rawIPAddress(IPAddress& addr) { - return addr.raw_address(); - } - const uint8_t* rawIPAddress(const IPAddress& addr) { - return addr.raw_address(); - } + }; #endif diff --git a/cores/esp8266/IPAddress.cpp b/cores/esp8266/IPAddress.cpp index 25660ec0b3..847f1e2aae 100644 --- a/cores/esp8266/IPAddress.cpp +++ b/cores/esp8266/IPAddress.cpp @@ -41,24 +41,14 @@ bool IPAddress::isSet () const { } IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) { - setV4(); - (*this)[0] = first_octet; - (*this)[1] = second_octet; - (*this)[2] = third_octet; - (*this)[3] = fourth_octet; -} + uint8_t addr[] { + first_octet, + second_octet, + third_octet, + fourth_octet, + }; -void IPAddress::ctor32(uint32_t address) { - setV4(); - v4() = address; -} - -IPAddress::IPAddress(const uint8_t *address) { - setV4(); - (*this)[0] = address[0]; - (*this)[1] = address[1]; - (*this)[2] = address[2]; - (*this)[3] = address[3]; + *this = &addr[0]; } bool IPAddress::fromString(const char *address) { @@ -116,8 +106,10 @@ bool IPAddress::fromString4(const char *address) { } IPAddress& IPAddress::operator=(const uint8_t *address) { - setV4(); - v4() = *reinterpret_cast(address); + uint32_t value; + std::memcpy(&value, address, sizeof(value)); + + *this = value; return *this; } @@ -128,7 +120,14 @@ IPAddress& IPAddress::operator=(uint32_t address) { } bool IPAddress::operator==(const uint8_t* addr) const { - return isV4() && v4() == *reinterpret_cast(addr); + if (!isV4()) { + return false; + } + + uint32_t value; + std::memcpy(&value, addr, sizeof(value)); + + return v4() == value; } size_t IPAddress::printTo(Print& p) const { diff --git a/cores/esp8266/IPAddress.h b/cores/esp8266/IPAddress.h index 3c4d12965c..f9f8cb9dd4 100644 --- a/cores/esp8266/IPAddress.h +++ b/cores/esp8266/IPAddress.h @@ -47,33 +47,18 @@ struct ip_addr: ipv4_addr { }; class IPAddress: public Printable { private: - ip_addr_t _ip; - // Access the raw byte array containing the address. Because this returns a pointer - // to the internal structure rather than a copy of the address this function should only - // be used when you know that the usage of the returned uint8_t* will be transient and not - // stored. - uint8_t* raw_address() { - return reinterpret_cast(&v4()); - } - const uint8_t* raw_address() const { - return reinterpret_cast(&v4()); - } - - void ctor32 (uint32_t); - public: - // Constructors IPAddress(); IPAddress(const IPAddress&); IPAddress(IPAddress&&); IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); - IPAddress(uint32_t address) { ctor32(address); } - IPAddress(unsigned long address) { ctor32(address); } - IPAddress(int address) { ctor32(address); } - IPAddress(const uint8_t *address); + IPAddress(uint32_t address) { *this = address; } + IPAddress(unsigned long address) { *this = address; } + IPAddress(int address) { *this = address; } + IPAddress(const uint8_t *address) { *this = address; } bool fromString(const char *address); bool fromString(const String &address) { return fromString(address.c_str()); } @@ -88,7 +73,7 @@ class IPAddress: public Printable { operator bool () { return isSet(); } // <- both are needed // generic IPv4 wrapper to uint32-view like arduino loves to see it - const uint32_t& v4() const { return ip_2_ip4(&_ip)->addr; } // for raw_address(const) + const uint32_t& v4() const { return ip_2_ip4(&_ip)->addr; } uint32_t& v4() { return ip_2_ip4(&_ip)->addr; } bool operator==(const IPAddress& addr) const { @@ -117,11 +102,18 @@ class IPAddress: public Printable { // Overloaded index operator to allow getting and setting individual octets of the address uint8_t operator[](int index) const { - return isV4()? *(raw_address() + index): 0; + if (!isV4()) { + return 0; + } + + return ip4_addr_get_byte_val(*ip_2_ip4(&_ip), index); } + uint8_t& operator[](int index) { setV4(); - return *(raw_address() + index); + + uint8_t* ptr = reinterpret_cast(&v4()); + return *(ptr + index); } // Overloaded copy operators to allow initialisation of IPAddress objects from other types diff --git a/cores/esp8266/Udp.h b/cores/esp8266/Udp.h index 6c8ee4b385..3e73b615e0 100644 --- a/cores/esp8266/Udp.h +++ b/cores/esp8266/Udp.h @@ -82,15 +82,7 @@ class UDP: public Stream { virtual IPAddress remoteIP() =0; // Return the port of the host who sent the current incoming packet virtual uint16_t remotePort() =0; - protected: - uint8_t* rawIPAddress(IPAddress& addr) { - return addr.raw_address(); - } - - const uint8_t* rawIPAddress(const IPAddress& addr) { - return addr.raw_address(); - } }; #endif From 853dcb419ce50573d9118ea85829ccad301a3dac Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Thu, 19 Jan 2023 02:04:44 +0300 Subject: [PATCH 2/4] Turns out this is Arduino API --- cores/esp8266/IPAddress.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cores/esp8266/IPAddress.h b/cores/esp8266/IPAddress.h index f9f8cb9dd4..99419b92a9 100644 --- a/cores/esp8266/IPAddress.h +++ b/cores/esp8266/IPAddress.h @@ -47,8 +47,20 @@ struct ip_addr: ipv4_addr { }; class IPAddress: public Printable { private: + ip_addr_t _ip; + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { + return reinterpret_cast(&v4()); + } + const uint8_t* raw_address() const { + return reinterpret_cast(&v4()); + } + public: IPAddress(); IPAddress(const IPAddress&); From 8ed288083f28ddbca29d2aca7451a9754a00282b Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Thu, 19 Jan 2023 02:38:40 +0300 Subject: [PATCH 3/4] fixup! Turns out this is Arduino API --- cores/esp8266/Client.h | 8 +++++++- cores/esp8266/Udp.h | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/cores/esp8266/Client.h b/cores/esp8266/Client.h index 2e21cb3b7f..7f8f810458 100644 --- a/cores/esp8266/Client.h +++ b/cores/esp8266/Client.h @@ -38,7 +38,13 @@ class Client: public Stream { virtual void stop() = 0; virtual uint8_t connected() = 0; virtual operator bool() = 0; - + protected: + uint8_t* rawIPAddress(IPAddress& addr) { + return addr.raw_address(); + } + const uint8_t* rawIPAddress(const IPAddress& addr) { + return addr.raw_address(); + } }; #endif diff --git a/cores/esp8266/Udp.h b/cores/esp8266/Udp.h index 3e73b615e0..6c8ee4b385 100644 --- a/cores/esp8266/Udp.h +++ b/cores/esp8266/Udp.h @@ -82,7 +82,15 @@ class UDP: public Stream { virtual IPAddress remoteIP() =0; // Return the port of the host who sent the current incoming packet virtual uint16_t remotePort() =0; + protected: + uint8_t* rawIPAddress(IPAddress& addr) { + return addr.raw_address(); + } + + const uint8_t* rawIPAddress(const IPAddress& addr) { + return addr.raw_address(); + } }; #endif From 553e5c99b007926f7975f5d3c1929d47db122b8a Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Fri, 20 Jan 2023 11:13:57 +0300 Subject: [PATCH 4/4] also allow unaligned copies while we are here --- cores/esp8266/IPAddress.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/IPAddress.cpp b/cores/esp8266/IPAddress.cpp index 847f1e2aae..6f68bc56e9 100644 --- a/cores/esp8266/IPAddress.cpp +++ b/cores/esp8266/IPAddress.cpp @@ -107,7 +107,7 @@ bool IPAddress::fromString4(const char *address) { IPAddress& IPAddress::operator=(const uint8_t *address) { uint32_t value; - std::memcpy(&value, address, sizeof(value)); + memcpy_P(&value, address, sizeof(value)); *this = value; return *this; @@ -125,7 +125,7 @@ bool IPAddress::operator==(const uint8_t* addr) const { } uint32_t value; - std::memcpy(&value, addr, sizeof(value)); + memcpy_P(&value, addr, sizeof(value)); return v4() == value; }