Skip to content

mDNS: restriction to a single interface #6224

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 2 commits into from
Jun 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cores/esp8266/AddrList.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
17 changes: 4 additions & 13 deletions libraries/ESP8266mDNS/src/LEAmDNS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
*
Expand Down
25 changes: 9 additions & 16 deletions libraries/ESP8266mDNS/src/LEAmDNS.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1155,6 +1148,7 @@ class MDNSResponder {
MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback;
bool m_bPassivModeEnabled;
stcProbeInformation m_HostProbeInformation;
IPAddress m_IPAddress;

/** CONTROL **/
/* MAINTENANCE */
Expand Down Expand Up @@ -1201,16 +1195,15 @@ 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);
bool _sendMDNSQuery(const stcMDNS_RRDomain& p_QueryDomain,
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;
Expand Down
57 changes: 51 additions & 6 deletions libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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")););
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
16 changes: 8 additions & 8 deletions libraries/ESP8266mDNS/src/LEAmDNS_Priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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


Expand Down
73 changes: 12 additions & 61 deletions libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down