Fix W5100S socket exhaustion blocking MQTT and additional TCP clients (#9770)

The W5100S Ethernet chip has only 4 hardware sockets. On RAK4631
Ethernet gateways with syslog and NTP enabled, all 4 sockets were
permanently consumed (NTP UDP + Syslog UDP + TCP API listener + TCP
API client), leaving none for MQTT, DHCP lease renewal, or additional
TCP connections.

- NTP: Remove permanent timeClient.begin() at startup; NTPClient::update()
  auto-initializes when needed. Add timeClient.end() after each query to
  release the UDP socket immediately.
- Syslog: Remove socket allocation from Syslog::enable(). Open and close
  the UDP socket on-demand in _sendLog() around each message send.
- MQTT: Fix socket leak in isValidConfig() where a successful test
  connection was never closed (PubSubClient destructor does not call
  disconnect). Add explicit pubSub->disconnect() before returning.

Made-with: Cursor

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
Philip Lykov
2026-03-30 15:12:23 +03:00
committed by GitHub
parent db694f2f24
commit 5319bc7c2c
2 changed files with 11 additions and 3 deletions

View File

@@ -98,7 +98,6 @@ Syslog &Syslog::logMask(uint8_t priMask)
void Syslog::enable()
{
this->_client->begin(this->_port);
this->_enabled = true;
}
@@ -166,14 +165,21 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
if ((pri & LOG_FACMASK) == 0)
pri = LOG_MAKEPRI(LOG_FAC(this->_priDefault), pri);
// W5100S: acquire UDP socket on-demand to avoid permanent socket consumption
if (!this->_client->begin(this->_port)) {
return false;
}
if (this->_server != NULL) {
result = this->_client->beginPacket(this->_server, this->_port);
} else {
result = this->_client->beginPacket(this->_ip, this->_port);
}
if (result != 1)
if (result != 1) {
this->_client->stop();
return false;
}
this->_client->print('<');
this->_client->print(pri);
@@ -193,6 +199,8 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
this->_client->print(message);
this->_client->endPacket();
this->_client->stop(); // W5100S: release UDP socket for other services
return true;
}

View File

@@ -102,7 +102,6 @@ static int32_t reconnectETH()
#ifndef DISABLE_NTP
LOG_INFO("Start NTP time client");
timeClient.begin();
timeClient.setUpdateInterval(60 * 60); // Update once an hour
#endif
@@ -159,6 +158,7 @@ static int32_t reconnectETH()
LOG_ERROR("NTP Update failed");
ntp_renew = millis() + 300 * 1000; // failure, retry every 5 minutes
}
timeClient.end(); // W5100S: release UDP socket for other services
}
#endif