diff --git a/platformio.ini b/platformio.ini index ea86a1f73d..197500a2dc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -75,6 +75,8 @@ build_flags = ${arduino_base.build_flags} -Wl,--wrap=esp_transport_ws_init ; Run dns_gethostbyname on the lwIP thread; see src/helpers/ESP32DnsThreadFix.cpp. -Wl,--wrap=dns_gethostbyname + ; Rebind port 80 during TIME_WAIT; see src/helpers/ESP32TcpBindReuse.cpp. + -Wl,--wrap=tcp_bind ; -D ESP32_CPU_FREQ=80 ; change it to your need build_src_filter = ${arduino_base.build_src_filter} + ; empty TU unless WITH_MQTT_BRIDGE diff --git a/src/helpers/ESP32TcpBindReuse.cpp b/src/helpers/ESP32TcpBindReuse.cpp new file mode 100644 index 0000000000..e61571b218 --- /dev/null +++ b/src/helpers/ESP32TcpBindReuse.cpp @@ -0,0 +1,29 @@ +// Lets a new port-80 listener bind while an old HTTP connection is still in TIME_WAIT. + +#ifdef ESP_PLATFORM + +#include +#include +#include + +// Arduino 2.0.17 names the switch SO_REUSE; later cores name it LWIP_SO_REUSE. +#ifndef LWIP_SO_REUSE +#ifdef SO_REUSE +#define LWIP_SO_REUSE SO_REUSE +#else +#define LWIP_SO_REUSE 0 +#endif +#endif + +extern "C" err_t __real_tcp_bind(struct tcp_pcb* pcb, const ip_addr_t* ipaddr, u16_t port); + +extern "C" err_t __wrap_tcp_bind(struct tcp_pcb* pcb, const ip_addr_t* ipaddr, u16_t port) { +#if LWIP_SO_REUSE + if (pcb != NULL && port == 80) { + ip_set_option(pcb, SOF_REUSEADDR); + } +#endif + return __real_tcp_bind(pcb, ipaddr, port); +} + +#endif // ESP_PLATFORM