Description
Board
N/A
Device Description
N/A
Hardware Configuration
N/A
Version
v3.0.0
IDE Name
N/A
Operating System
N/A
Flash frequency
N/A
PSRAM enabled
no
Upload speed
N/A
Description
The origin of this bug request comes for a bug report in my ESPAsyncWebServer maintained fork here: mathieucarbou/ESPAsyncWebServer#26
The root of the problem lies in the fact that when connected to a WiFi, both should be true.
WiFi.localIP().toString() == request->client()->localIP().toString()
WiFi.localIP() == request->client()->localIP()
But the second one is false.
This is because the library uses behind the new IPAddress
construction with an ip_addr_t
(following some updates from the ESPHome team). This is not wrong, but the new implementation has flaws.
The issue lies at several places:
- the comparison operator
bool IPAddress::operator==(const IPAddress &addr) const {
return (addr._type == _type) && (memcmp(addr._address.bytes, _address.bytes, sizeof(_address.bytes)) == 0);
}
For IPv4, it should only compare _address.dword[IPADDRESS_V4_DWORD_INDEX]
, not the full set of bytes
- the constructor:
IPAddress &IPAddress::from_ip_addr_t(const ip_addr_t *addr) {
if (addr->type == IPADDR_TYPE_V6) {
_type = IPv6;
_address.dword[0] = addr->u_addr.ip6.addr[0];
_address.dword[1] = addr->u_addr.ip6.addr[1];
_address.dword[2] = addr->u_addr.ip6.addr[2];
_address.dword[3] = addr->u_addr.ip6.addr[3];
#if LWIP_IPV6_SCOPES
_zone = addr->u_addr.ip6.zone;
#endif /* LWIP_IPV6_SCOPES */
} else {
_type = IPv4;
_address.dword[IPADDRESS_V4_DWORD_INDEX] = addr->u_addr.ip4.addr;
}
return *this;
}
Which is not "clearing" the indexes 0, 1 and 2 to 0, to ensure the comparison operator works for IPv4
Any of this fix would work. I tested this one:
IPAddress &IPAddress::from_ip_addr_t(const ip_addr_t *addr) {
if (addr->type == IPADDR_TYPE_V6) {
_type = IPv6;
_address.dword[0] = addr->u_addr.ip6.addr[0];
_address.dword[1] = addr->u_addr.ip6.addr[1];
_address.dword[2] = addr->u_addr.ip6.addr[2];
_address.dword[3] = addr->u_addr.ip6.addr[3];
#if LWIP_IPV6_SCOPES
_zone = addr->u_addr.ip6.zone;
#endif /* LWIP_IPV6_SCOPES */
} else {
_type = IPv4;
_address.dword[0] = 0;
_address.dword[1] = 0;
_address.dword[2] = 0;
_address.dword[IPADDRESS_V4_DWORD_INDEX] = addr->u_addr.ip4.addr;
}
return *this;
}
But I think both should be applied (also making sure that the compare operator is comparing the relevant information depending on the IP type)
Sketch
N/A
Debug Message
N/A
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.