mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-27 18:02:17 +03:00
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)
This commit is contained in:
committed by
Earle F. Philhower, III
parent
273f4000f0
commit
5ca0bde200
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include <Schedule.h>
|
||||
#include <AddrList.h>
|
||||
|
||||
#include "LEAmDNS_Priv.h"
|
||||
|
||||
@ -59,11 +60,11 @@ MDNSResponder::MDNSResponder(void)
|
||||
m_pServiceQueries(0),
|
||||
m_fnServiceTxtCallback(0),
|
||||
#ifdef ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
|
||||
m_bPassivModeEnabled(true) {
|
||||
m_bPassivModeEnabled(true),
|
||||
#else
|
||||
m_bPassivModeEnabled(false) {
|
||||
m_bPassivModeEnabled(false),
|
||||
#endif
|
||||
|
||||
m_netif(nullptr) {
|
||||
}
|
||||
|
||||
/*
|
||||
@ -95,20 +96,74 @@ bool MDNSResponder::begin(const char* p_pcHostname, const IPAddress& p_IPAddress
|
||||
if (0 == m_pUDPContext) {
|
||||
if (_setHostname(p_pcHostname)) {
|
||||
|
||||
m_IPAddress = p_IPAddress;
|
||||
//// select interface
|
||||
|
||||
m_GotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& pEvent) {
|
||||
(void) pEvent;
|
||||
// Ensure that _restart() runs in USER context
|
||||
schedule_function([this]() { MDNSResponder::_restart(); });
|
||||
});
|
||||
m_netif = nullptr;
|
||||
IPAddress ipAddress = p_IPAddress;
|
||||
|
||||
m_DisconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& pEvent) {
|
||||
(void) pEvent;
|
||||
// Ensure that _restart() runs in USER context
|
||||
schedule_function([this]() { MDNSResponder::_restart(); });
|
||||
if (!ipAddress.isSet()) {
|
||||
|
||||
IPAddress sta = WiFi.localIP();
|
||||
IPAddress ap = WiFi.softAPIP();
|
||||
|
||||
if (!sta.isSet() && !ap.isSet()) {
|
||||
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] internal interfaces (STA, AP) are not set (none was specified)\n")));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ap.isSet()) {
|
||||
|
||||
if (sta.isSet())
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface AP selected over STA (none was specified)\n")));
|
||||
else
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface AP selected\n")));
|
||||
ipAddress = ap;
|
||||
|
||||
} else {
|
||||
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface STA selected (none was specified)\n")));
|
||||
ipAddress = sta;
|
||||
|
||||
}
|
||||
|
||||
// continue to ensure interface is UP
|
||||
}
|
||||
|
||||
// check existence of this IP address in the interface list
|
||||
bool found = false;
|
||||
m_netif = nullptr;
|
||||
for (auto a: addrList)
|
||||
if (ipAddress == a.addr()) {
|
||||
if (a.ifUp()) {
|
||||
found = true;
|
||||
m_netif = a.interface();
|
||||
break;
|
||||
}
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] found interface for IP '%s' but it is not UP\n"), ipAddress.toString().c_str()););
|
||||
}
|
||||
if (!found) {
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] interface defined by IP '%s' not found\n"), ipAddress.toString().c_str()););
|
||||
return false;
|
||||
}
|
||||
|
||||
//// done selecting the interface
|
||||
|
||||
if (m_netif->num == STATION_IF) {
|
||||
|
||||
m_GotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& pEvent) {
|
||||
(void) pEvent;
|
||||
// Ensure that _restart() runs in USER context
|
||||
schedule_function([this]() { MDNSResponder::_restart(); });
|
||||
});
|
||||
|
||||
m_DisconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& pEvent) {
|
||||
(void) pEvent;
|
||||
// Ensure that _restart() runs in USER context
|
||||
schedule_function([this]() { MDNSResponder::_restart(); });
|
||||
});
|
||||
}
|
||||
|
||||
bResult = _restart();
|
||||
}
|
||||
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,
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] queryService: INVALID input data!\n"), p_pcService, p_pcProtocol););
|
||||
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] queryService: INVALID input data!\n")););
|
||||
}
|
||||
return u32Result;
|
||||
}
|
||||
|
@ -1148,7 +1148,7 @@ protected:
|
||||
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
|
||||
bool m_bPassivModeEnabled;
|
||||
stcProbeInformation m_HostProbeInformation;
|
||||
IPAddress m_IPAddress;
|
||||
CONST netif* m_netif; // network interface to run on
|
||||
|
||||
/** CONTROL **/
|
||||
/* MAINTENANCE */
|
||||
@ -1203,7 +1203,7 @@ protected:
|
||||
uint16_t p_u16QueryType,
|
||||
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
|
||||
|
||||
const IPAddress& _getResponseMulticastInterface() const { return m_IPAddress; }
|
||||
const IPAddress _getResponseMulticastInterface() const { return IPAddress(m_netif->ip_addr); }
|
||||
|
||||
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
|
||||
bool* p_pbFullNameMatch = 0) const;
|
||||
|
@ -78,10 +78,10 @@ bool MDNSResponder::_process(bool p_bUserContext) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
bResult = ((WiFi.isConnected() || // Either station is connected
|
||||
WiFi.softAPgetStationNum()>0) && // Or AP has stations connected
|
||||
(_updateProbeStatus()) && // Probing
|
||||
(_checkServiceQueryCache())); // Service query cache check
|
||||
bResult = (m_netif != nullptr) &&
|
||||
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running
|
||||
_updateProbeStatus() && // Probing
|
||||
_checkServiceQueryCache(); // Service query cache check
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
@ -91,53 +91,10 @@ bool MDNSResponder::_process(bool p_bUserContext) {
|
||||
*/
|
||||
bool MDNSResponder::_restart(void) {
|
||||
|
||||
// check m_IPAddress
|
||||
if (!m_IPAddress.isSet()) {
|
||||
|
||||
IPAddress sta = WiFi.localIP();
|
||||
IPAddress ap = WiFi.softAPIP();
|
||||
|
||||
if (!sta.isSet() && !ap.isSet()) {
|
||||
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] internal interfaces (STA, AP) are not set (none was specified)\n")));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sta.isSet()) {
|
||||
|
||||
if (ap.isSet())
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface STA selected over AP (none was specified)\n")));
|
||||
else
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface STA selected\n")));
|
||||
m_IPAddress = sta;
|
||||
|
||||
} else {
|
||||
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] default interface AP selected (none was specified)\n")));
|
||||
m_IPAddress = ap;
|
||||
|
||||
}
|
||||
|
||||
// continue to ensure interface is UP
|
||||
}
|
||||
|
||||
// check existence of this IP address in the interface list
|
||||
bool found = false;
|
||||
for (auto a: addrList)
|
||||
if (m_IPAddress == a.addr()) {
|
||||
if (a.ifUp()) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
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()););
|
||||
}
|
||||
if (!found) {
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] interface defined by IP '%s' not found\n"), m_IPAddress.toString().c_str()););
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((_resetProbeStatus(true)) && // Stop and restart probing
|
||||
(_allocUDPContext())); // Restart UDP
|
||||
return ((m_netif != nullptr) &&
|
||||
(m_netif->flags & NETIF_FLAG_UP) && // network interface is up and running
|
||||
(_resetProbeStatus(true)) && // Stop and restart probing
|
||||
(_allocUDPContext())); // Restart UDP
|
||||
}
|
||||
|
||||
|
||||
@ -797,7 +754,7 @@ bool MDNSResponder::_processPTRAnswer(const MDNSResponder::stcMDNS_RRAnswerPTR*
|
||||
if (p_pPTRAnswer->m_u32TTL) { // Received update message
|
||||
pSQAnswer->m_TTLServiceDomain.set(p_pPTRAnswer->m_u32TTL); // Update TTL tag
|
||||
DEBUG_EX_INFO(
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processPTRAnswer: Updated TTL(%lu) for "), p_pPTRAnswer->m_u32TTL);
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processPTRAnswer: Updated TTL(%d) for "), (int)p_pPTRAnswer->m_u32TTL);
|
||||
_printRRDomain(pSQAnswer->m_ServiceDomain);
|
||||
DEBUG_OUTPUT.printf_P(PSTR("\n"));
|
||||
);
|
||||
@ -851,7 +808,7 @@ bool MDNSResponder::_processSRVAnswer(const MDNSResponder::stcMDNS_RRAnswerSRV*
|
||||
if (p_pSRVAnswer->m_u32TTL) { // First or update message (TTL != 0)
|
||||
pSQAnswer->m_TTLHostDomainAndPort.set(p_pSRVAnswer->m_u32TTL); // Update TTL tag
|
||||
DEBUG_EX_INFO(
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processSRVAnswer: Updated TTL(%lu) for "), p_pSRVAnswer->m_u32TTL);
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processSRVAnswer: Updated TTL(%d) for "), (int)p_pSRVAnswer->m_u32TTL);
|
||||
_printRRDomain(pSQAnswer->m_ServiceDomain);
|
||||
DEBUG_OUTPUT.printf_P(PSTR(" host domain and port\n"));
|
||||
);
|
||||
@ -904,7 +861,7 @@ bool MDNSResponder::_processTXTAnswer(const MDNSResponder::stcMDNS_RRAnswerTXT*
|
||||
if (p_pTXTAnswer->m_u32TTL) { // First or update message
|
||||
pSQAnswer->m_TTLTxts.set(p_pTXTAnswer->m_u32TTL); // Update TTL tag
|
||||
DEBUG_EX_INFO(
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processTXTAnswer: Updated TTL(%lu) for "), p_pTXTAnswer->m_u32TTL);
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processTXTAnswer: Updated TTL(%d) for "), (int)p_pTXTAnswer->m_u32TTL);
|
||||
_printRRDomain(pSQAnswer->m_ServiceDomain);
|
||||
DEBUG_OUTPUT.printf_P(PSTR(" TXTs\n"));
|
||||
);
|
||||
@ -956,7 +913,7 @@ bool MDNSResponder::_processTXTAnswer(const MDNSResponder::stcMDNS_RRAnswerTXT*
|
||||
if (p_pAAnswer->m_u32TTL) { // Valid TTL -> Update answers TTL
|
||||
pIP4Address->m_TTL.set(p_pAAnswer->m_u32TTL);
|
||||
DEBUG_EX_INFO(
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processAAnswer: Updated TTL(%lu) for "), p_pAAnswer->m_u32TTL);
|
||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processAAnswer: Updated TTL(%d) for "), (int)p_pAAnswer->m_u32TTL);
|
||||
_printRRDomain(pSQAnswer->m_ServiceDomain);
|
||||
DEBUG_OUTPUT.printf_P(PSTR(" IP4Address (%s)\n"), pIP4Address->m_IPAddress.toString().c_str());
|
||||
);
|
||||
@ -1123,7 +1080,7 @@ bool MDNSResponder::_updateProbeStatus(void) {
|
||||
|
||||
if (MDNS_ANNOUNCE_COUNT > m_HostProbeInformation.m_u8SentCount) {
|
||||
m_HostProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY);
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Announcing host (%lu).\n\n"), m_HostProbeInformation.m_u8SentCount););
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Announcing host (%d).\n\n"), m_HostProbeInformation.m_u8SentCount););
|
||||
}
|
||||
else {
|
||||
m_HostProbeInformation.m_Timeout.resetToNeverExpires();
|
||||
@ -1171,7 +1128,7 @@ bool MDNSResponder::_updateProbeStatus(void) {
|
||||
|
||||
if (MDNS_ANNOUNCE_COUNT > pService->m_ProbeInformation.m_u8SentCount) {
|
||||
pService->m_ProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY);
|
||||
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););
|
||||
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););
|
||||
}
|
||||
else {
|
||||
pService->m_ProbeInformation.m_Timeout.resetToNeverExpires();
|
||||
|
@ -170,7 +170,7 @@ namespace MDNSImplementation {
|
||||
*/
|
||||
|
||||
bool MDNSResponder::_callProcess(void) {
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), m_pUDPContext->getRemoteAddress().toString().c_str()););
|
||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()););
|
||||
|
||||
return _process(false);
|
||||
}
|
||||
@ -199,7 +199,7 @@ bool MDNSResponder::_allocUDPContext(void) {
|
||||
//TODO: set multicast address (lwip_joingroup() is IPv4 only at the time of writing)
|
||||
multicast_addr.addr = DNS_MQUERY_IPV6_GROUP_INIT;
|
||||
#endif
|
||||
if (ERR_OK == igmp_joingroup(IP4_ADDR_ANY4, ip_2_ip4(&multicast_addr))) {
|
||||
if (ERR_OK == igmp_joingroup(ip_2_ip4(&m_netif->ip_addr), ip_2_ip4(&multicast_addr))) {
|
||||
m_pUDPContext = new UdpContext;
|
||||
m_pUDPContext->ref();
|
||||
|
||||
|
@ -37,6 +37,9 @@ namespace MDNSImplementation {
|
||||
#define ESP_8266_MDNS_INCLUDE
|
||||
//#define DEBUG_ESP_MDNS_RESPONDER
|
||||
|
||||
#if !defined(DEBUG_ESP_MDNS_RESPONDER) && defined(DEBUG_ESP_MDNS)
|
||||
#define DEBUG_ESP_MDNS_RESPONDER
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_OPEN_SRC
|
||||
#define LWIP_OPEN_SRC
|
||||
|
Reference in New Issue
Block a user