Skip to content

Commit f9009b8

Browse files
authored
mDNS: restriction to a single interface (#6224)
Default interface is STA (or AP if available and STA is unavailable). An interface can also be specified in ::begin() by its IP address. MDNS will not cross interfaces (there is currently no notion of "bridged interfaces") Multiple instances should be working, this is not tested in this commit.
1 parent 5306976 commit f9009b8

File tree

6 files changed

+85
-104
lines changed

6 files changed

+85
-104
lines changed

cores/esp8266/AddrList.h

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct netifWrapper
127127
const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); }
128128
const char* ifmac () const { return (const char*)_netif->hwaddr; }
129129
int ifnumber () const { return _netif->num; }
130+
bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); }
130131

131132
const ip_addr_t* ipFromNetifNum () const
132133
{

libraries/ESP8266mDNS/src/LEAmDNS.cpp

+4-13
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,15 @@ MDNSResponder::~MDNSResponder(void) {
8787
* Finally the responder is (re)started
8888
*
8989
*/
90-
bool MDNSResponder::begin(const char* p_pcHostname) {
90+
bool MDNSResponder::begin(const char* p_pcHostname, const IPAddress& p_IPAddress, uint32_t p_u32TTL) {
9191

92+
(void)p_u32TTL; // ignored
9293
bool bResult = false;
9394

9495
if (0 == m_pUDPContext) {
9596
if (_setHostname(p_pcHostname)) {
97+
98+
m_IPAddress = p_IPAddress;
9699

97100
m_GotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& pEvent) {
98101
(void) pEvent;
@@ -116,18 +119,6 @@ bool MDNSResponder::begin(const char* p_pcHostname) {
116119
return bResult;
117120
}
118121

119-
/*
120-
* MDNSResponder::begin (LEGACY)
121-
*/
122-
bool MDNSResponder::begin(const char* p_pcHostname,
123-
IPAddress p_IPAddress,
124-
uint32_t p_u32TTL /*= 120*/) {
125-
126-
(void) p_IPAddress;
127-
(void) p_u32TTL;
128-
return begin(p_pcHostname);
129-
}
130-
131122
/*
132123
* MDNSResponder::close
133124
*

libraries/ESP8266mDNS/src/LEAmDNS.h

+9-16
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,10 @@ class MDNSResponder {
175175
// Start the MDNS responder by setting the default hostname
176176
// Later call MDNS::update() in every 'loop' to run the process loop
177177
// (probing, announcing, responding, ...)
178-
bool begin(const char* p_pcHostname);
179-
bool begin(const String& p_strHostname) {return begin(p_strHostname.c_str());}
180-
// for compatibility
181-
bool begin(const char* p_pcHostname,
182-
IPAddress p_IPAddress, // ignored
183-
uint32_t p_u32TTL = 120); // ignored
184-
bool begin(const String& p_strHostname,
185-
IPAddress p_IPAddress, // ignored
186-
uint32_t p_u32TTL = 120) { // ignored
187-
return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL);
188-
}
178+
// if interfaceAddress is not specified, default interface is STA, or AP when STA is not set
179+
bool begin(const char* p_pcHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/);
180+
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);}
181+
189182
// Finish MDNS processing
190183
bool close(void);
191184
// for esp32 compatability
@@ -487,12 +480,12 @@ class MDNSResponder {
487480
const char* p_pcDivider = "-",
488481
const char* p_pcDefaultDomain = 0);
489482

490-
protected:
491483
/** STRUCTS **/
484+
485+
public:
492486
/**
493487
* MDNSServiceInfo, used in application callbacks
494488
*/
495-
public:
496489
struct MDNSServiceInfo
497490
{
498491
MDNSServiceInfo(MDNSResponder& p_pM,MDNSResponder::hMDNSServiceQuery p_hS,uint32_t p_u32A)
@@ -1155,6 +1148,7 @@ class MDNSResponder {
11551148
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
11561149
bool m_bPassivModeEnabled;
11571150
stcProbeInformation m_HostProbeInformation;
1151+
IPAddress m_IPAddress;
11581152

11591153
/** CONTROL **/
11601154
/* MAINTENANCE */
@@ -1201,16 +1195,15 @@ class MDNSResponder {
12011195
/** TRANSFER **/
12021196
/* SENDING */
12031197
bool _sendMDNSMessage(stcMDNSSendParameter& p_SendParameter);
1204-
bool _sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter,
1205-
int p_iWiFiOpMode);
1198+
bool _sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter);
12061199
bool _prepareMDNSMessage(stcMDNSSendParameter& p_SendParameter,
12071200
IPAddress p_IPAddress);
12081201
bool _sendMDNSServiceQuery(const stcMDNSServiceQuery& p_ServiceQuery);
12091202
bool _sendMDNSQuery(const stcMDNS_RRDomain& p_QueryDomain,
12101203
uint16_t p_u16QueryType,
12111204
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
12121205

1213-
IPAddress _getResponseMulticastInterface(int p_iWiFiOpModes) const;
1206+
const IPAddress& _getResponseMulticastInterface() const { return m_IPAddress; }
12141207

12151208
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
12161209
bool* p_pbFullNameMatch = 0) const;

libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp

+51-6
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,52 @@ bool MDNSResponder::_process(bool p_bUserContext) {
9090
* MDNSResponder::_restart
9191
*/
9292
bool MDNSResponder::_restart(void) {
93-
93+
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+
94139
return ((_resetProbeStatus(true)) && // Stop and restart probing
95140
(_allocUDPContext())); // Restart UDP
96141
}
@@ -314,7 +359,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
314359
// IP4 address was asked for
315360
#ifdef MDNS_IP4_SUPPORT
316361
if ((AnswerType_A == pKnownRRAnswer->answerType()) &&
317-
(((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == _getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE))) {
362+
(((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == _getResponseMulticastInterface())) {
318363

319364
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: IP4 address already known... skipping!\n")););
320365
sendParameter.m_u8HostReplyMask &= ~ContentFlag_A;
@@ -325,7 +370,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
325370
// IP6 address was asked for
326371
#ifdef MDNS_IP6_SUPPORT
327372
if ((AnswerType_AAAA == pAnswerRR->answerType()) &&
328-
(((stcMDNS_RRAnswerAAAA*)pAnswerRR)->m_IPAddress == _getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE))) {
373+
(((stcMDNS_RRAnswerAAAA*)pAnswerRR)->m_IPAddress == _getResponseMulticastInterface())) {
329374

330375
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: IP6 address already known... skipping!\n")););
331376
sendParameter.m_u8HostReplyMask &= ~ContentFlag_AAAA;
@@ -343,7 +388,7 @@ bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHea
343388
// Host domain match
344389
#ifdef MDNS_IP4_SUPPORT
345390
if (AnswerType_A == pKnownRRAnswer->answerType()) {
346-
IPAddress localIPAddress(_getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE));
391+
IPAddress localIPAddress(_getResponseMulticastInterface());
347392
if (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress == localIPAddress) {
348393
// SAME IP address -> We've received an old message from ourselfs (same IP)
349394
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) {
10391084
// Probe host domain
10401085
if ((ProbingStatus_ReadyToStart == m_HostProbeInformation.m_ProbingStatus) && // Ready to get started AND
10411086
//TODO: Fix the following to allow Ethernet shield or other interfaces
1042-
(_getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE) != IPAddress())) { // Has IP address
1087+
(_getResponseMulticastInterface() != IPAddress())) { // Has IP address
10431088
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Starting host probing...\n")););
10441089

10451090
// First probe delay SHOULD be random 0-250 ms
@@ -1721,7 +1766,7 @@ uint8_t MDNSResponder::_replyMaskForHost(const MDNSResponder::stcMDNS_RRHeader&
17211766
// PTR request
17221767
#ifdef MDNS_IP4_SUPPORT
17231768
stcMDNS_RRDomain reverseIP4Domain;
1724-
if ((_buildDomainForReverseIP4(_getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE), reverseIP4Domain)) &&
1769+
if ((_buildDomainForReverseIP4(_getResponseMulticastInterface(), reverseIP4Domain)) &&
17251770
(p_RRHeader.m_Domain == reverseIP4Domain)) {
17261771
// Reverse domain match
17271772
u8ReplyMask |= ContentFlag_PTR_IP4;

libraries/ESP8266mDNS/src/LEAmDNS_Priv.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,22 @@ namespace MDNSImplementation {
5959
#ifdef DEBUG_ESP_MDNS_INFO
6060
#define DEBUG_EX_INFO(A) A
6161
#else
62-
#define DEBUG_EX_INFO(A)
62+
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
6363
#endif
6464
#ifdef DEBUG_ESP_MDNS_ERR
6565
#define DEBUG_EX_ERR(A) A
6666
#else
67-
#define DEBUG_EX_ERR(A)
67+
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
6868
#endif
6969
#ifdef DEBUG_ESP_MDNS_TX
7070
#define DEBUG_EX_TX(A) A
7171
#else
72-
#define DEBUG_EX_TX(A)
72+
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
7373
#endif
7474
#ifdef DEBUG_ESP_MDNS_RX
7575
#define DEBUG_EX_RX(A) A
7676
#else
77-
#define DEBUG_EX_RX(A)
77+
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
7878
#endif
7979

8080
#ifdef DEBUG_ESP_PORT
@@ -83,10 +83,10 @@ namespace MDNSImplementation {
8383
#define DEBUG_OUTPUT Serial
8484
#endif
8585
#else
86-
#define DEBUG_EX_INFO(A)
87-
#define DEBUG_EX_ERR(A)
88-
#define DEBUG_EX_TX(A)
89-
#define DEBUG_EX_RX(A)
86+
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
87+
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
88+
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
89+
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
9090
#endif
9191

9292

libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp

+12-61
Original file line numberDiff line numberDiff line change
@@ -76,25 +76,16 @@ bool MDNSResponder::_sendMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSen
7676

7777
bool bResult = true;
7878

79-
if (p_rSendParameter.m_bResponse) {
80-
if (p_rSendParameter.m_bUnicast) { // Unicast response -> Send to querier
81-
DEBUG_EX_ERR(if (!m_pUDPContext->getRemoteAddress()) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage: MISSING remote address for response!\n")); });
82-
IPAddress ipRemote;
83-
ipRemote = m_pUDPContext->getRemoteAddress();
84-
bResult = ((_prepareMDNSMessage(p_rSendParameter, _getResponseMulticastInterface(SOFTAP_MODE | STATION_MODE))) &&
85-
(m_pUDPContext->send(ipRemote, m_pUDPContext->getRemotePort())));
86-
}
87-
else { // Multicast response -> Send via the same network interface, that received the query
88-
bResult = _sendMDNSMessage_Multicast(p_rSendParameter, (SOFTAP_MODE | STATION_MODE));
89-
}
79+
if (p_rSendParameter.m_bResponse &&
80+
p_rSendParameter.m_bUnicast) { // Unicast response -> Send to querier
81+
DEBUG_EX_ERR(if (!m_pUDPContext->getRemoteAddress()) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage: MISSING remote address for response!\n")); });
82+
IPAddress ipRemote;
83+
ipRemote = m_pUDPContext->getRemoteAddress();
84+
bResult = ((_prepareMDNSMessage(p_rSendParameter, _getResponseMulticastInterface())) &&
85+
(m_pUDPContext->send(ipRemote, m_pUDPContext->getRemotePort())));
9086
}
91-
else { // Multicast query -> Send by all available network interfaces
92-
const int caiWiFiOpModes[2] = { SOFTAP_MODE, STATION_MODE };
93-
for (int iInterfaceId=0; ((bResult) && (iInterfaceId<=1)); ++iInterfaceId) {
94-
if (wifi_get_opmode() & caiWiFiOpModes[iInterfaceId]) {
95-
bResult = _sendMDNSMessage_Multicast(p_rSendParameter, caiWiFiOpModes[iInterfaceId]);
96-
}
97-
}
87+
else { // Multicast response
88+
bResult = _sendMDNSMessage_Multicast(p_rSendParameter);
9889
}
9990

10091
// Finally clear service reply masks
@@ -112,12 +103,12 @@ bool MDNSResponder::_sendMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSen
112103
* Fills the UDP output buffer (via _prepareMDNSMessage) and sends the buffer
113104
* via the selected WiFi interface (Station or AP)
114105
*/
115-
bool MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter,
116-
int p_iWiFiOpMode) {
106+
bool MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter) {
107+
117108
bool bResult = false;
118109

119110
IPAddress fromIPAddress;
120-
fromIPAddress = _getResponseMulticastInterface(p_iWiFiOpMode);
111+
fromIPAddress = _getResponseMulticastInterface();
121112
m_pUDPContext->setMulticastInterface(fromIPAddress);
122113

123114
#ifdef MDNS_IP4_SUPPORT
@@ -365,46 +356,6 @@ bool MDNSResponder::_sendMDNSQuery(const MDNSResponder::stcMDNS_RRDomain& p_Quer
365356
return bResult;
366357
}
367358

368-
/*
369-
* MDNSResponder::_getResponseMulticastInterface
370-
*
371-
* Selects the appropriate interface for responses.
372-
* If AP mode is enabled and the remote contact is in the APs local net, then the
373-
* AP interface is used to send the response.
374-
* Otherwise the Station interface (if available) is used.
375-
*
376-
*/
377-
IPAddress MDNSResponder::_getResponseMulticastInterface(int p_iWiFiOpModes) const {
378-
379-
ip_info IPInfo_Local;
380-
bool bFoundMatch = false;
381-
382-
if ((p_iWiFiOpModes & SOFTAP_MODE) &&
383-
(wifi_get_opmode() & SOFTAP_MODE)) {
384-
//DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _getResponseMulticastInterface: SOFTAP_MODE\n")););
385-
// Get remote IP address
386-
IPAddress IP_Remote;
387-
IP_Remote = m_pUDPContext->getRemoteAddress();
388-
// Get local (AP) IP address
389-
wifi_get_ip_info(SOFTAP_IF, &IPInfo_Local);
390-
391-
if ((IPInfo_Local.ip.addr) && // Has local AP IP address AND
392-
(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
393-
bFoundMatch = true;
394-
}
395-
}
396-
if ((!bFoundMatch) &&
397-
(p_iWiFiOpModes & STATION_MODE) &&
398-
(wifi_get_opmode() & STATION_MODE)) {
399-
//DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _getResponseMulticastInterface: STATION_MODE\n")););
400-
// Get local (STATION) IP address
401-
wifi_get_ip_info(STATION_IF, &IPInfo_Local);
402-
}
403-
//DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _getResponseMulticastInterface(%i): %s\n"), p_iWiFiOpModes, IPAddress(IPInfo_Local.ip).toString().c_str()););
404-
return IPAddress(IPInfo_Local.ip);
405-
}
406-
407-
408359
/**
409360
* HELPERS
410361
*/

0 commit comments

Comments
 (0)