mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-07 06:01:35 +03:00
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.
This commit is contained in:
@ -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
|
||||
{
|
||||
|
@ -87,13 +87,16 @@ 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;
|
||||
// Ensure that _restart() runs in USER context
|
||||
@ -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
|
||||
*
|
||||
|
@ -175,17 +175,10 @@ public:
|
||||
// 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 @@ public:
|
||||
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 @@ protected:
|
||||
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
|
||||
bool m_bPassivModeEnabled;
|
||||
stcProbeInformation m_HostProbeInformation;
|
||||
IPAddress m_IPAddress;
|
||||
|
||||
/** CONTROL **/
|
||||
/* MAINTENANCE */
|
||||
@ -1201,8 +1195,7 @@ protected:
|
||||
/** 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 @@ protected:
|
||||
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;
|
||||
|
@ -91,6 +91,51 @@ 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
|
||||
}
|
||||
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
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(SOFTAP_MODE | STATION_MODE))) &&
|
||||
bResult = ((_prepareMDNSMessage(p_rSendParameter, _getResponseMulticastInterface())) &&
|
||||
(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));
|
||||
}
|
||||
}
|
||||
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
|
||||
*/
|
||||
|
Reference in New Issue
Block a user