Skip to content

Commit 5ca0bde

Browse files
d-a-vearlephilhower
authored andcommitted
MDNS: fix random crash on startup (#6261)
* mDNS debug option + AP address is used by default when STA is also present * mDNS: store network interface, checking it is up * igmp: force on selected interface (avoid crash *sometimes*) * fix for all lwip2 ipv4 ipv6 & lwip1 * mdns: IPAddress is not needed to reference associated interface * mdns: debug: fix print warnings * emulation: add ets_strncpy * emulation: truly emulate AddrList (remove fake one)
1 parent 273f400 commit 5ca0bde

File tree

12 files changed

+289
-316
lines changed

12 files changed

+289
-316
lines changed

boards.txt

+180-120
Large diffs are not rendered by default.

cores/esp8266/AddrList.h

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct netifWrapper
128128
const char* ifmac () const { return (const char*)_netif->hwaddr; }
129129
int ifnumber () const { return _netif->num; }
130130
bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); }
131+
CONST netif* interface () const { return _netif; }
131132

132133
const ip_addr_t* ipFromNetifNum () const
133134
{

libraries/ESP8266mDNS/src/LEAmDNS.cpp

+70-15
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include <Schedule.h>
26+
#include <AddrList.h>
2627

2728
#include "LEAmDNS_Priv.h"
2829

@@ -59,11 +60,11 @@ MDNSResponder::MDNSResponder(void)
5960
m_pServiceQueries(0),
6061
m_fnServiceTxtCallback(0),
6162
#ifdef ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
62-
m_bPassivModeEnabled(true) {
63+
m_bPassivModeEnabled(true),
6364
#else
64-
m_bPassivModeEnabled(false) {
65+
m_bPassivModeEnabled(false),
6566
#endif
66-
67+
m_netif(nullptr) {
6768
}
6869

6970
/*
@@ -95,20 +96,74 @@ bool MDNSResponder::begin(const char* p_pcHostname, const IPAddress& p_IPAddress
9596
if (0 == m_pUDPContext) {
9697
if (_setHostname(p_pcHostname)) {
9798

98-
m_IPAddress = p_IPAddress;
99+
//// select interface
99100

100-
m_GotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& pEvent) {
101-
(void) pEvent;
102-
// Ensure that _restart() runs in USER context
103-
schedule_function([this]() { MDNSResponder::_restart(); });
104-
});
105-
106-
m_DisconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& pEvent) {
107-
(void) pEvent;
108-
// Ensure that _restart() runs in USER context
109-
schedule_function([this]() { MDNSResponder::_restart(); });
101+
m_netif = nullptr;
102+
IPAddress ipAddress = p_IPAddress;
103+
104+
if (!ipAddress.isSet()) {
105+
106+
IPAddress sta = WiFi.localIP();
107+
IPAddress ap = WiFi.softAPIP();
108+
109+
if (!sta.isSet() && !ap.isSet()) {
110+
111+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] internal interfaces (STA, AP) are not set (none was specified)\n")));
112+
return false;
113+
}
114+
115+
if (ap.isSet()) {
116+
117+
if (sta.isSet())
118+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface AP selected over STA (none was specified)\n")));
119+
else
120+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface AP selected\n")));
121+
ipAddress = ap;
122+
123+
} else {
124+
125+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface STA selected (none was specified)\n")));
126+
ipAddress = sta;
127+
128+
}
129+
130+
// continue to ensure interface is UP
131+
}
132+
133+
// check existence of this IP address in the interface list
134+
bool found = false;
135+
m_netif = nullptr;
136+
for (auto a: addrList)
137+
if (ipAddress == a.addr()) {
138+
if (a.ifUp()) {
139+
found = true;
140+
m_netif = a.interface();
141+
break;
142+
}
143+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] found interface for IP '%s' but it is not UP\n"), ipAddress.toString().c_str()););
144+
}
145+
if (!found) {
146+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] interface defined by IP '%s' not found\n"), ipAddress.toString().c_str()););
147+
return false;
148+
}
149+
150+
//// done selecting the interface
151+
152+
if (m_netif->num == STATION_IF) {
153+
154+
m_GotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& pEvent) {
155+
(void) pEvent;
156+
// Ensure that _restart() runs in USER context
157+
schedule_function([this]() { MDNSResponder::_restart(); });
110158
});
111159

160+
m_DisconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& pEvent) {
161+
(void) pEvent;
162+
// Ensure that _restart() runs in USER context
163+
schedule_function([this]() { MDNSResponder::_restart(); });
164+
});
165+
}
166+
112167
bResult = _restart();
113168
}
114169
DEBUG_EX_ERR(if (!bResult) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] begin: FAILED for '%s'!\n"), (p_pcHostname ?: "-")); } );
@@ -642,7 +697,7 @@ uint32_t MDNSResponder::queryService(const char* p_pcService,
642697
}
643698
}
644699
else {
645-
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] queryService: INVALID input data!\n"), p_pcService, p_pcProtocol););
700+
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] queryService: INVALID input data!\n")););
646701
}
647702
return u32Result;
648703
}

libraries/ESP8266mDNS/src/LEAmDNS.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,7 @@ class MDNSResponder {
11481148
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
11491149
bool m_bPassivModeEnabled;
11501150
stcProbeInformation m_HostProbeInformation;
1151-
IPAddress m_IPAddress;
1151+
CONST netif* m_netif; // network interface to run on
11521152

11531153
/** CONTROL **/
11541154
/* MAINTENANCE */
@@ -1203,7 +1203,7 @@ class MDNSResponder {
12031203
uint16_t p_u16QueryType,
12041204
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
12051205

1206-
const IPAddress& _getResponseMulticastInterface() const { return m_IPAddress; }
1206+
const IPAddress _getResponseMulticastInterface() const { return IPAddress(m_netif->ip_addr); }
12071207

12081208
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
12091209
bool* p_pbFullNameMatch = 0) const;

libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp

+14-57
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ bool MDNSResponder::_process(bool p_bUserContext) {
7878
}
7979
}
8080
else {
81-
bResult = ((WiFi.isConnected() || // Either station is connected
82-
WiFi.softAPgetStationNum()>0) && // Or AP has stations connected
83-
(_updateProbeStatus()) && // Probing
84-
(_checkServiceQueryCache())); // Service query cache check
81+
bResult = (m_netif != nullptr) &&
82+
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running
83+
_updateProbeStatus() && // Probing
84+
_checkServiceQueryCache(); // Service query cache check
8585
}
8686
return bResult;
8787
}
@@ -91,53 +91,10 @@ bool MDNSResponder::_process(bool p_bUserContext) {
9191
*/
9292
bool MDNSResponder::_restart(void) {
9393

94-
// check m_IPAddress
95-
if (!m_IPAddress.isSet()) {
96-
97-
IPAddress sta = WiFi.localIP();
98-
IPAddress ap = WiFi.softAPIP();
99-
100-
if (!sta.isSet() && !ap.isSet()) {
101-
102-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] internal interfaces (STA, AP) are not set (none was specified)\n")));
103-
return false;
104-
}
105-
106-
if (sta.isSet()) {
107-
108-
if (ap.isSet())
109-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface STA selected over AP (none was specified)\n")));
110-
else
111-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface STA selected\n")));
112-
m_IPAddress = sta;
113-
114-
} else {
115-
116-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface AP selected (none was specified)\n")));
117-
m_IPAddress = ap;
118-
119-
}
120-
121-
// continue to ensure interface is UP
122-
}
123-
124-
// check existence of this IP address in the interface list
125-
bool found = false;
126-
for (auto a: addrList)
127-
if (m_IPAddress == a.addr()) {
128-
if (a.ifUp()) {
129-
found = true;
130-
break;
131-
}
132-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] found interface for IP '%s' but it is not UP\n"), m_IPAddress.toString().c_str()););
133-
}
134-
if (!found) {
135-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] interface defined by IP '%s' not found\n"), m_IPAddress.toString().c_str()););
136-
return false;
137-
}
138-
139-
return ((_resetProbeStatus(true)) && // Stop and restart probing
140-
(_allocUDPContext())); // Restart UDP
94+
return ((m_netif != nullptr) &&
95+
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running
96+
(_resetProbeStatus(true)) && // Stop and restart probing
97+
(_allocUDPContext())); // Restart UDP
14198
}
14299

143100

@@ -797,7 +754,7 @@ bool MDNSResponder::_processPTRAnswer(const MDNSResponder::stcMDNS_RRAnswerPTR*
797754
if (p_pPTRAnswer->m_u32TTL) { // Received update message
798755
pSQAnswer->m_TTLServiceDomain.set(p_pPTRAnswer->m_u32TTL); // Update TTL tag
799756
DEBUG_EX_INFO(
800-
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processPTRAnswer: Updated TTL(%lu) for "), p_pPTRAnswer->m_u32TTL);
757+
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processPTRAnswer: Updated TTL(%d) for "), (int)p_pPTRAnswer->m_u32TTL);
801758
_printRRDomain(pSQAnswer->m_ServiceDomain);
802759
DEBUG_OUTPUT.printf_P(PSTR("\n"));
803760
);
@@ -851,7 +808,7 @@ bool MDNSResponder::_processSRVAnswer(const MDNSResponder::stcMDNS_RRAnswerSRV*
851808
if (p_pSRVAnswer->m_u32TTL) { // First or update message (TTL != 0)
852809
pSQAnswer->m_TTLHostDomainAndPort.set(p_pSRVAnswer->m_u32TTL); // Update TTL tag
853810
DEBUG_EX_INFO(
854-
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processSRVAnswer: Updated TTL(%lu) for "), p_pSRVAnswer->m_u32TTL);
811+
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processSRVAnswer: Updated TTL(%d) for "), (int)p_pSRVAnswer->m_u32TTL);
855812
_printRRDomain(pSQAnswer->m_ServiceDomain);
856813
DEBUG_OUTPUT.printf_P(PSTR(" host domain and port\n"));
857814
);
@@ -904,7 +861,7 @@ bool MDNSResponder::_processTXTAnswer(const MDNSResponder::stcMDNS_RRAnswerTXT*
904861
if (p_pTXTAnswer->m_u32TTL) { // First or update message
905862
pSQAnswer->m_TTLTxts.set(p_pTXTAnswer->m_u32TTL); // Update TTL tag
906863
DEBUG_EX_INFO(
907-
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processTXTAnswer: Updated TTL(%lu) for "), p_pTXTAnswer->m_u32TTL);
864+
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processTXTAnswer: Updated TTL(%d) for "), (int)p_pTXTAnswer->m_u32TTL);
908865
_printRRDomain(pSQAnswer->m_ServiceDomain);
909866
DEBUG_OUTPUT.printf_P(PSTR(" TXTs\n"));
910867
);
@@ -956,7 +913,7 @@ bool MDNSResponder::_processTXTAnswer(const MDNSResponder::stcMDNS_RRAnswerTXT*
956913
if (p_pAAnswer->m_u32TTL) { // Valid TTL -> Update answers TTL
957914
pIP4Address->m_TTL.set(p_pAAnswer->m_u32TTL);
958915
DEBUG_EX_INFO(
959-
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processAAnswer: Updated TTL(%lu) for "), p_pAAnswer->m_u32TTL);
916+
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processAAnswer: Updated TTL(%d) for "), (int)p_pAAnswer->m_u32TTL);
960917
_printRRDomain(pSQAnswer->m_ServiceDomain);
961918
DEBUG_OUTPUT.printf_P(PSTR(" IP4Address (%s)\n"), pIP4Address->m_IPAddress.toString().c_str());
962919
);
@@ -1123,7 +1080,7 @@ bool MDNSResponder::_updateProbeStatus(void) {
11231080

11241081
if (MDNS_ANNOUNCE_COUNT > m_HostProbeInformation.m_u8SentCount) {
11251082
m_HostProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY);
1126-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Announcing host (%lu).\n\n"), m_HostProbeInformation.m_u8SentCount););
1083+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Announcing host (%d).\n\n"), m_HostProbeInformation.m_u8SentCount););
11271084
}
11281085
else {
11291086
m_HostProbeInformation.m_Timeout.resetToNeverExpires();
@@ -1171,7 +1128,7 @@ bool MDNSResponder::_updateProbeStatus(void) {
11711128

11721129
if (MDNS_ANNOUNCE_COUNT > pService->m_ProbeInformation.m_u8SentCount) {
11731130
pService->m_ProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY);
1174-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Announcing service %s.%s.%s (%lu)\n\n"), (pService->m_pcName ?: m_pcHostname), pService->m_pcService, pService->m_pcProtocol, pService->m_ProbeInformation.m_u8SentCount););
1131+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Announcing service %s.%s.%s (%d)\n\n"), (pService->m_pcName ?: m_pcHostname), pService->m_pcService, pService->m_pcProtocol, pService->m_ProbeInformation.m_u8SentCount););
11751132
}
11761133
else {
11771134
pService->m_ProbeInformation.m_Timeout.resetToNeverExpires();

libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ namespace MDNSImplementation {
170170
*/
171171

172172
bool MDNSResponder::_callProcess(void) {
173-
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), m_pUDPContext->getRemoteAddress().toString().c_str()););
173+
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()););
174174

175175
return _process(false);
176176
}
@@ -199,7 +199,7 @@ bool MDNSResponder::_allocUDPContext(void) {
199199
//TODO: set multicast address (lwip_joingroup() is IPv4 only at the time of writing)
200200
multicast_addr.addr = DNS_MQUERY_IPV6_GROUP_INIT;
201201
#endif
202-
if (ERR_OK == igmp_joingroup(IP4_ADDR_ANY4, ip_2_ip4(&multicast_addr))) {
202+
if (ERR_OK == igmp_joingroup(ip_2_ip4(&m_netif->ip_addr), ip_2_ip4(&multicast_addr))) {
203203
m_pUDPContext = new UdpContext;
204204
m_pUDPContext->ref();
205205

libraries/ESP8266mDNS/src/LEAmDNS_Priv.h

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ namespace MDNSImplementation {
3737
#define ESP_8266_MDNS_INCLUDE
3838
//#define DEBUG_ESP_MDNS_RESPONDER
3939

40+
#if !defined(DEBUG_ESP_MDNS_RESPONDER) && defined(DEBUG_ESP_MDNS)
41+
#define DEBUG_ESP_MDNS_RESPONDER
42+
#endif
4043

4144
#ifndef LWIP_OPEN_SRC
4245
#define LWIP_OPEN_SRC

0 commit comments

Comments
 (0)