fix(network): snapshot and restore every lwIP DNS slot
DHCP can fill all DNS_MAX_SERVERS (3) slots, but only two were saved and restored, so a third server from one medium survived a switch to the other. link.dns now drops trailing empty slots to keep remote replies under 160 bytes.
This commit is contained in:
1 parent
274997e9ae
commit
a24dade1c0
3 files changed
+29
-21
No files matched your search
@@ -558,7 +558,7 @@ These settings apply across all MQTT slots:
|
||||
- `get wifi.pwd` - Get WiFi password
|
||||
- `get link.status` - Get the selected network medium, connection status, IP, signal when available, and uptime
|
||||
- `get link.diag` - Explain automatic Ethernet selection using controller initialization, link event, IP, WiFi fallback, route-lock, and reason state
|
||||
- `get link.dns` - Show the live DNS resolver list, the selected medium's gateway, and the DNS each medium's DHCP lease installed (`-` = empty slot, `none` = never leased)
|
||||
- `get link.dns` - Show the live DNS resolver list, the selected medium's gateway, and the DNS each medium's DHCP lease installed (trailing empty slots are omitted; `-` = empty slot or empty list, `none` = never leased)
|
||||
- `get wifi.status` - WiFi-only compatibility alias; reports n/a when another medium is selected
|
||||
- `get wifi.powersave` - Get WiFi power save mode (none/min/max)
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ GETTERS = {
|
||||
"link.diag": lambda c: (
|
||||
"why:ethernet-not-enabled selected:wifi\n"
|
||||
"wifi:state:connected ip:192.168.1.42"),
|
||||
"link.dns": lambda c: "dns:192.168.1.1,-,- gw:192.168.1.1 lease:192.168.1.1,-",
|
||||
"link.dns": lambda c: "dns:192.168.1.1 gw:192.168.1.1 lease:192.168.1.1",
|
||||
"mqtt.status": lambda c: cli_mqtt_status(c),
|
||||
"mqtt.presets": lambda c: "\n".join(
|
||||
"%2d. %s%s" % (i + 1, n, "" if nd == "none" else " (needs %s)" % nd)
|
||||
|
||||
+27
-19
@@ -33,18 +33,28 @@ extern void tcpipInit();
|
||||
|
||||
namespace {
|
||||
|
||||
static void appendDnsAddr(char* out, size_t out_size, const ip_addr_t& addr) {
|
||||
const size_t len = strlen(out);
|
||||
if (len >= out_size) return;
|
||||
if (len > 0 && len + 1 < out_size) {
|
||||
out[len] = ',';
|
||||
out[len + 1] = '\0';
|
||||
// Trailing empty slots are dropped to keep remote replies short; "-" marks an
|
||||
// empty slot before a populated one, or a list with nothing in it.
|
||||
static void formatDnsList(char* out, size_t out_size, const ip_addr_t* servers, int count) {
|
||||
int last = count - 1;
|
||||
while (last >= 0 && ip_addr_isany_val(servers[last])) last--;
|
||||
out[0] = '\0';
|
||||
if (last < 0) {
|
||||
snprintf(out, out_size, "-");
|
||||
return;
|
||||
}
|
||||
const size_t at = strlen(out);
|
||||
if (ip_addr_isany_val(addr)) {
|
||||
snprintf(out + at, out_size - at, "-");
|
||||
} else {
|
||||
ipaddr_ntoa_r(&addr, out + at, (int)(out_size - at));
|
||||
for (int i = 0; i <= last; i++) {
|
||||
size_t len = strlen(out);
|
||||
if (i > 0 && len + 1 < out_size) {
|
||||
out[len++] = ',';
|
||||
out[len] = '\0';
|
||||
}
|
||||
if (len + 1 >= out_size) return;
|
||||
if (ip_addr_isany_val(servers[i])) {
|
||||
snprintf(out + len, out_size - len, "-");
|
||||
} else {
|
||||
ipaddr_ntoa_r(&servers[i], out + len, (int)(out_size - len));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,8 +71,7 @@ static esp_err_t readDnsServersOnTcpipThread(void* ctx) {
|
||||
static void formatCurrentDnsServers(char* out, size_t out_size) {
|
||||
ip_addr_t servers[DNS_MAX_SERVERS] = {};
|
||||
esp_netif_tcpip_exec(readDnsServersOnTcpipThread, servers);
|
||||
out[0] = '\0';
|
||||
for (int i = 0; i < DNS_MAX_SERVERS; i++) appendDnsAddr(out, out_size, servers[i]);
|
||||
formatDnsList(out, out_size, servers, DNS_MAX_SERVERS);
|
||||
}
|
||||
|
||||
class NetworkLinkBase : public NetworkLink {
|
||||
@@ -74,7 +83,7 @@ class NetworkLinkBase : public NetworkLink {
|
||||
bool _status_initialized = false;
|
||||
bool _last_connected = false;
|
||||
unsigned long _last_status_check = 0;
|
||||
static constexpr int kDnsServers = 2;
|
||||
static constexpr int kDnsServers = DNS_MAX_SERVERS;
|
||||
// Only ever touched on the lwIP thread (see snapshotDns()), so no atomics.
|
||||
ip_addr_t _dns_snapshot[kDnsServers] = {};
|
||||
bool _dns_captured = false;
|
||||
@@ -189,17 +198,16 @@ class NetworkLinkBase : public NetworkLink {
|
||||
for (int i = 0; i < kDnsServers; i++) c->servers[i] = c->self->_dns_snapshot[i];
|
||||
return ESP_OK;
|
||||
}, ©);
|
||||
out[0] = '\0';
|
||||
if (!copy.captured) {
|
||||
snprintf(out, out_size, "none");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < kDnsServers; i++) appendDnsAddr(out, out_size, copy.servers[i]);
|
||||
formatDnsList(out, out_size, copy.servers, kDnsServers);
|
||||
}
|
||||
|
||||
void formatDnsFor(char* reply, size_t reply_size, IPAddress gateway) const {
|
||||
char current[64];
|
||||
char lease[40];
|
||||
char lease[64];
|
||||
formatCurrentDnsServers(current, sizeof(current));
|
||||
formatLeaseDns(lease, sizeof(lease));
|
||||
snprintf(reply, reply_size, "> dns:%s gw:%s lease:%s",
|
||||
@@ -1009,8 +1017,8 @@ class AutomaticNetworkLink final : public NetworkLink {
|
||||
void formatDns(char* reply, size_t reply_size) const override {
|
||||
const NetworkMedium selected = _selected.load(std::memory_order_acquire);
|
||||
char current[64];
|
||||
char eth_lease[40];
|
||||
char wifi_lease[40];
|
||||
char eth_lease[64];
|
||||
char wifi_lease[64];
|
||||
formatCurrentDnsServers(current, sizeof(current));
|
||||
_ethernet.formatLeaseDns(eth_lease, sizeof(eth_lease));
|
||||
_wifi.formatLeaseDns(wifi_lease, sizeof(wifi_lease));
|
||||
|
||||
Reference in new issue
Block a user