diff --git a/cores/esp8266/AddrList.h b/cores/esp8266/AddrList.h index 88bd8122bb..36ccd49b3c 100644 --- a/cores/esp8266/AddrList.h +++ b/cores/esp8266/AddrList.h @@ -127,6 +127,7 @@ struct netifWrapper const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); } 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 ip_addr_t* ipFromNetifNum () const { diff --git a/libraries/ESP8266mDNS/src/LEAmDNS.cpp b/libraries/ESP8266mDNS/src/LEAmDNS.cpp index 7227784c83..0d99113ed0 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS.cpp @@ -87,12 +87,15 @@ MDNSResponder::~MDNSResponder(void) { * Finally the responder is (re)started * */ -bool MDNSResponder::begin(const char* p_pcHostname) { +bool MDNSResponder::begin(const char* p_pcHostname, const IPAddress& p_IPAddress, uint32_t p_u32TTL) { + (void)p_u32TTL; // ignored bool bResult = false; if (0 == m_pUDPContext) { if (_setHostname(p_pcHostname)) { + + m_IPAddress = p_IPAddress; m_GotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& pEvent) { (void) pEvent; @@ -116,18 +119,6 @@ bool MDNSResponder::begin(const char* p_pcHostname) { return bResult; } -/* - * MDNSResponder::begin (LEGACY) - */ -bool MDNSResponder::begin(const char* p_pcHostname, - IPAddress p_IPAddress, - uint32_t p_u32TTL /*= 120*/) { - - (void) p_IPAddress; - (void) p_u32TTL; - return begin(p_pcHostname); -} - /* * MDNSResponder::close * diff --git a/libraries/ESP8266mDNS/src/LEAmDNS.h b/libraries/ESP8266mDNS/src/LEAmDNS.h index 03abcdbb88..3bf16eb10a 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS.h +++ b/libraries/ESP8266mDNS/src/LEAmDNS.h @@ -175,17 +175,10 @@ class MDNSResponder { // Start the MDNS responder by setting the default hostname // Later call MDNS::update() in every 'loop' to run the process loop // (probing, announcing, responding, ...) - bool begin(const char* p_pcHostname); - bool begin(const String& p_strHostname) {return begin(p_strHostname.c_str());} - // for compatibility - bool begin(const char* p_pcHostname, - IPAddress p_IPAddress, // ignored - uint32_t p_u32TTL = 120); // ignored - bool begin(const String& p_strHostname, - IPAddress p_IPAddress, // ignored - uint32_t p_u32TTL = 120) { // ignored - return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL); - } + // if interfaceAddress is not specified, default interface is STA, or AP when STA is not set + bool begin(const char* p_pcHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/); + bool begin(const String& p_strHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/) {return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL);} + // Finish MDNS processing bool close(void); // for esp32 compatability @@ -487,12 +480,12 @@ class MDNSResponder { const char* p_pcDivider = "-", const char* p_pcDefaultDomain = 0); -protected: /** STRUCTS **/ + +public: /** * MDNSServiceInfo, used in application callbacks */ -public: struct MDNSServiceInfo { MDNSServiceInfo(MDNSResponder& p_pM,MDNSResponder::hMDNSServiceQuery p_hS,uint32_t p_u32A) @@ -1155,6 +1148,7 @@ class MDNSResponder { MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback; bool m_bPassivModeEnabled; stcProbeInformation m_HostProbeInformation; + IPAddress m_IPAddress; /** CONTROL **/ /* MAINTENANCE */ @@ -1201,8 +1195,7 @@ class MDNSResponder { /** TRANSFER **/ /* SENDING */ bool _sendMDNSMessage(stcMDNSSendParameter& p_SendParameter); - bool _sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter, - int p_iWiFiOpMode); + bool _sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter); bool _prepareMDNSMessage(stcMDNSSendParameter& p_SendParameter, IPAddress p_IPAddress); bool _sendMDNSServiceQuery(const stcMDNSServiceQuery& p_ServiceQuery); @@ -1210,7 +1203,7 @@ class MDNSResponder { uint16_t p_u16QueryType, stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0); - IPAddress _getResponseMulticastInterface(int p_iWiFiOpModes) const; + const IPAddress& _getResponseMulticastInterface() const { return m_IPAddress; } uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader, bool* p_pbFullNameMatch = 0) const; diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp index d5bd4dde61..64a670f4a5 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp @@ -90,7 +90,52 @@ bool MDNSResponder::_process(bool p_bUserContext) { * MDNSResponder::_restart */ 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 } @@ -314,7 +359,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea // IP4 address was asked for #ifdef MDNS_IP4_SUPPORT if ((AnswerType_A == pKnownRRAnswer->answerType()) && - (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == _getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE))) { + (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == _getResponseMulticastInterface())) { DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: IP4 address already known... skipping!\n"));); sendParameter.m_u8HostReplyMask &= ~ContentFlag_A; @@ -325,7 +370,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea // IP6 address was asked for #ifdef MDNS_IP6_SUPPORT if ((AnswerType_AAAA == pAnswerRR->answerType()) && - (((stcMDNS_RRAnswerAAAA*)pAnswerRR)->m_IPAddress == _getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE))) { + (((stcMDNS_RRAnswerAAAA*)pAnswerRR)->m_IPAddress == _getResponseMulticastInterface())) { DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: IP6 address already known... skipping!\n"));); sendParameter.m_u8HostReplyMask &= ~ContentFlag_AAAA; @@ -343,7 +388,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea // Host domain match #ifdef MDNS_IP4_SUPPORT if (AnswerType_A == pKnownRRAnswer->answerType()) { - IPAddress localIPAddress(_getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE)); + IPAddress localIPAddress(_getResponseMulticastInterface()); if (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == localIPAddress) { // SAME IP address -> We've received an old message from ourselfs (same IP) DEBUG_EX_RX(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Tiebreak (IP4) WON (was an old message)!\n"));); @@ -1039,7 +1084,7 @@ bool MDNSResponder::_updateProbeStatus(void) { // Probe host domain if ((ProbingStatus_ReadyToStart == m_HostProbeInformation.m_ProbingStatus) && // Ready to get started AND //TODO: Fix the following to allow Ethernet shield or other interfaces - (_getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE) != IPAddress())) { // Has IP address + (_getResponseMulticastInterface() != IPAddress())) { // Has IP address DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Starting host probing...\n"));); // First probe delay SHOULD be random 0-250 ms @@ -1721,7 +1766,7 @@ uint8_t MDNSResponder::_replyMaskForHost(const MDNSResponder::stcMDNS_RRHeader& // PTR request #ifdef MDNS_IP4_SUPPORT stcMDNS_RRDomain reverseIP4Domain; - if ((_buildDomainForReverseIP4(_getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE), reverseIP4Domain)) && + if ((_buildDomainForReverseIP4(_getResponseMulticastInterface(), reverseIP4Domain)) && (p_RRHeader.m_Domain == reverseIP4Domain)) { // Reverse domain match u8ReplyMask |= ContentFlag_PTR_IP4; diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Priv.h b/libraries/ESP8266mDNS/src/LEAmDNS_Priv.h index 76ed927291..bcd135959a 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Priv.h +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Priv.h @@ -59,22 +59,22 @@ namespace MDNSImplementation { #ifdef DEBUG_ESP_MDNS_INFO #define DEBUG_EX_INFO(A) A #else - #define DEBUG_EX_INFO(A) + #define DEBUG_EX_INFO(A) do { (void)0; } while (0) #endif #ifdef DEBUG_ESP_MDNS_ERR #define DEBUG_EX_ERR(A) A #else - #define DEBUG_EX_ERR(A) + #define DEBUG_EX_ERR(A) do { (void)0; } while (0) #endif #ifdef DEBUG_ESP_MDNS_TX #define DEBUG_EX_TX(A) A #else - #define DEBUG_EX_TX(A) + #define DEBUG_EX_TX(A) do { (void)0; } while (0) #endif #ifdef DEBUG_ESP_MDNS_RX #define DEBUG_EX_RX(A) A #else - #define DEBUG_EX_RX(A) + #define DEBUG_EX_RX(A) do { (void)0; } while (0) #endif #ifdef DEBUG_ESP_PORT @@ -83,10 +83,10 @@ namespace MDNSImplementation { #define DEBUG_OUTPUT Serial #endif #else - #define DEBUG_EX_INFO(A) - #define DEBUG_EX_ERR(A) - #define DEBUG_EX_TX(A) - #define DEBUG_EX_RX(A) + #define DEBUG_EX_INFO(A) do { (void)0; } while (0) + #define DEBUG_EX_ERR(A) do { (void)0; } while (0) + #define DEBUG_EX_TX(A) do { (void)0; } while (0) + #define DEBUG_EX_RX(A) do { (void)0; } while (0) #endif diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp index c61baf87a3..b4eebbedd9 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp @@ -76,25 +76,16 @@ bool MDNSResponder::_sendMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSen bool bResult = true; - if (p_rSendParameter.m_bResponse) { - if (p_rSendParameter.m_bUnicast) { // Unicast response -> Send to querier - DEBUG_EX_ERR(if (!m_pUDPContext->getRemoteAddress()) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage: MISSING remote address for response!\n")); }); - IPAddress ipRemote; - ipRemote = m_pUDPContext->getRemoteAddress(); - bResult = ((_prepareMDNSMessage(p_rSendParameter, _getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE))) && - (m_pUDPContext->send(ipRemote, m_pUDPContext->getRemotePort()))); - } - else { // Multicast response -> Send via the same network interface, that received the query - bResult = _sendMDNSMessage_Multicast(p_rSendParameter, (SOFTAP_MODE | STATION_MODE)); - } + if (p_rSendParameter.m_bResponse && + p_rSendParameter.m_bUnicast) { // Unicast response -> Send to querier + DEBUG_EX_ERR(if (!m_pUDPContext->getRemoteAddress()) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage: MISSING remote address for response!\n")); }); + IPAddress ipRemote; + ipRemote = m_pUDPContext->getRemoteAddress(); + bResult = ((_prepareMDNSMessage(p_rSendParameter, _getResponseMulticastInterface())) && + (m_pUDPContext->send(ipRemote, m_pUDPContext->getRemotePort()))); } - else { // Multicast query -> Send by all available network interfaces - const int caiWiFiOpModes[2] = { SOFTAP_MODE, STATION_MODE }; - for (int iInterfaceId=0; ((bResult) && (iInterfaceId<=1)); ++iInterfaceId) { - if (wifi_get_opmode() & caiWiFiOpModes[iInterfaceId]) { - bResult = _sendMDNSMessage_Multicast(p_rSendParameter, caiWiFiOpModes[iInterfaceId]); - } - } + else { // Multicast response + bResult = _sendMDNSMessage_Multicast(p_rSendParameter); } // Finally clear service reply masks @@ -112,12 +103,12 @@ bool MDNSResponder::_sendMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSen * Fills the UDP output buffer (via _prepareMDNSMessage) and sends the buffer * via the selected WiFi interface (Station or AP) */ -bool MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter, - int p_iWiFiOpMode) { +bool MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + bool bResult = false; IPAddress fromIPAddress; - fromIPAddress = _getResponseMulticastInterface(p_iWiFiOpMode); + fromIPAddress = _getResponseMulticastInterface(); m_pUDPContext->setMulticastInterface(fromIPAddress); #ifdef MDNS_IP4_SUPPORT @@ -365,46 +356,6 @@ bool MDNSResponder::_sendMDNSQuery(const MDNSResponder::stcMDNS_RRDomain& p_Quer return bResult; } -/* - * MDNSResponder::_getResponseMulticastInterface - * - * Selects the appropriate interface for responses. - * If AP mode is enabled and the remote contact is in the APs local net, then the - * AP interface is used to send the response. - * Otherwise the Station interface (if available) is used. - * - */ -IPAddress MDNSResponder::_getResponseMulticastInterface(int p_iWiFiOpModes) const { - - ip_info IPInfo_Local; - bool bFoundMatch = false; - - if ((p_iWiFiOpModes & SOFTAP_MODE) && - (wifi_get_opmode() & SOFTAP_MODE)) { - //DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _getResponseMulticastInterface: SOFTAP_MODE\n"));); - // Get remote IP address - IPAddress IP_Remote; - IP_Remote = m_pUDPContext->getRemoteAddress(); - // Get local (AP) IP address - wifi_get_ip_info(SOFTAP_IF, &IPInfo_Local); - - if ((IPInfo_Local.ip.addr) && // Has local AP IP address AND - (ip4_addr_netcmp(ip_2_ip4((const ip_addr_t*)IP_Remote), &IPInfo_Local.ip, &IPInfo_Local.netmask))) { // Remote address is in the same subnet as the AP - bFoundMatch = true; - } - } - if ((!bFoundMatch) && - (p_iWiFiOpModes & STATION_MODE) && - (wifi_get_opmode() & STATION_MODE)) { - //DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _getResponseMulticastInterface: STATION_MODE\n"));); - // Get local (STATION) IP address - wifi_get_ip_info(STATION_IF, &IPInfo_Local); - } - //DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _getResponseMulticastInterface(%i): %s\n"), p_iWiFiOpModes, IPAddress(IPInfo_Local.ip).toString().c_str());); - return IPAddress(IPInfo_Local.ip); -} - - /** * HELPERS */