Skip to content

MDNS: fix random crash on startup #6261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Sep 5, 2019
Merged
300 changes: 180 additions & 120 deletions boards.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cores/esp8266/AddrList.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ struct netifWrapper
const char* ifmac () const { return (const char*)_netif->hwaddr; }
int ifnumber () const { return _netif->num; }
bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); }
CONST netif* interface () const { return _netif; }

const ip_addr_t* ipFromNetifNum () const
{
Expand Down
85 changes: 70 additions & 15 deletions libraries/ESP8266mDNS/src/LEAmDNS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

#include <Schedule.h>
#include <AddrList.h>

#include "LEAmDNS_Priv.h"

Expand Down Expand Up @@ -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) {
}

/*
Expand Down Expand Up @@ -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_DisconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& pEvent) {
(void) pEvent;
// Ensure that _restart() runs in USER context
schedule_function([this]() { MDNSResponder::_restart(); });
m_netif = nullptr;
IPAddress ipAddress = p_IPAddress;

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 ?: "-")); } );
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions libraries/ESP8266mDNS/src/LEAmDNS.h
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ class MDNSResponder {
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
bool m_bPassivModeEnabled;
stcProbeInformation m_HostProbeInformation;
IPAddress m_IPAddress;
CONST netif* m_netif; // network interface to run on

/** CONTROL **/
/* MAINTENANCE */
Expand Down Expand Up @@ -1203,7 +1203,7 @@ class MDNSResponder {
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;
Expand Down
71 changes: 14 additions & 57 deletions libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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
}


Expand Down Expand Up @@ -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"));
);
Expand Down Expand Up @@ -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"));
);
Expand Down Expand Up @@ -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"));
);
Expand Down Expand Up @@ -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());
);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();

Expand Down
3 changes: 3 additions & 0 deletions libraries/ESP8266mDNS/src/LEAmDNS_Priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading