1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-11 15:22:13 +03:00

LEA mDNS v2 (#7540)

* LEAmDNSv2
This commit is contained in:
Labor-Et-Ars
2020-09-25 11:12:39 +02:00
committed by GitHub
parent faf59f5190
commit a3281fe2f3
39 changed files with 12359 additions and 1846 deletions

View File

@ -1,3 +1,25 @@
/*
License (MIT license):
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <ESP8266mDNS.h>
/*

View File

@ -10,7 +10,7 @@
- Presenting a DNS-SD service to interested observers, eg. a http server by presenting _http._tcp service
- Support for multi-level compressed names in input; in output only a very simple one-leven full-name compression is implemented
- Probing host and service domains for uniqueness in the local network
- Tiebreaking while probing is supportet in a very minimalistic way (the 'higher' IP address wins the tiebreak)
- Tiebreaking while probing is supported in a very minimalistic way (the 'higher' IP address wins the tiebreak)
- Announcing available services after successful probing
- Using fixed service TXT items or
- Using dynamic service TXT items for presented services (via callback)
@ -42,15 +42,18 @@
*/
#include "ESP8266mDNS_Legacy.h"
#include "LEAmDNS.h"
enum class MDNSApiVersion { LEA, LEAv2 };
#include "LEAmDNS.h" // LEA
#include "LEAmDNS2Host.h" // LEAv2 - API updated
// clsLEAMDNSHost replaces MDNSResponder in LEAv2
using clsLEAMDNSHost = esp8266::experimental::clsLEAMDNSHost;
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
// Maps the implementation to use to the global namespace type
//using MDNSResponder = Legacy_MDNSResponder::MDNSResponder; //legacy
using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; //new
using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; // LEA
//using MDNSResponder = clsLEAMDNSHost; // LEAv2
extern MDNSResponder MDNS;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,166 +0,0 @@
/*
ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
Version 1.1
Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.com)
Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
This is a simple implementation of multicast DNS query support for an Arduino
running on ESP8266 chip. Only support for resolving address queries is currently
implemented.
Requirements:
- ESP8266WiFi library
Usage:
- Include the ESP8266 Multicast DNS library in the sketch.
- Call the begin method in the sketch's setup and provide a domain name (without
the '.local' suffix, i.e. just provide 'foo' to resolve 'foo.local'), and the
Adafruit CC3000 class instance. Optionally provide a time to live (in seconds)
for the DNS record--the default is 1 hour.
- Call the update method in each iteration of the sketch's loop function.
License (MIT license):
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef ESP8266MDNS_LEGACY_H
#define ESP8266MDNS_LEGACY_H
#include "ESP8266WiFi.h"
#include "WiFiUdp.h"
//this should be defined at build time
#ifndef ARDUINO_BOARD
#define ARDUINO_BOARD "generic"
#endif
class UdpContext;
namespace Legacy_MDNSResponder
{
struct MDNSService;
struct MDNSTxt;
struct MDNSAnswer;
class MDNSResponder
{
public:
MDNSResponder();
~MDNSResponder();
bool begin(const char* hostName);
bool begin(const String& hostName)
{
return begin(hostName.c_str());
}
//for compatibility
bool begin(const char* hostName, IPAddress ip, uint32_t ttl = 120)
{
(void) ip;
(void) ttl;
return begin(hostName);
}
bool begin(const String& hostName, IPAddress ip, uint32_t ttl = 120)
{
return begin(hostName.c_str(), ip, ttl);
}
/* Application should call this whenever AP is configured/disabled */
void notifyAPChange();
void update();
void addService(char *service, char *proto, uint16_t port);
void addService(const char *service, const char *proto, uint16_t port)
{
addService((char *)service, (char *)proto, port);
}
void addService(const String& service, const String& proto, uint16_t port)
{
addService(service.c_str(), proto.c_str(), port);
}
bool addServiceTxt(char *name, char *proto, char * key, char * value);
bool addServiceTxt(const char *name, const char *proto, const char *key, const char * value)
{
return addServiceTxt((char *)name, (char *)proto, (char *)key, (char *)value);
}
bool addServiceTxt(const String& name, const String& proto, const String& key, const String& value)
{
return addServiceTxt(name.c_str(), proto.c_str(), key.c_str(), value.c_str());
}
int queryService(char *service, char *proto);
int queryService(const char *service, const char *proto)
{
return queryService((char *)service, (char *)proto);
}
int queryService(const String& service, const String& proto)
{
return queryService(service.c_str(), proto.c_str());
}
String hostname(int idx);
IPAddress IP(int idx);
uint16_t port(int idx);
void enableArduino(uint16_t port, bool auth = false);
void setInstanceName(String name);
void setInstanceName(const char * name)
{
setInstanceName(String(name));
}
void setInstanceName(char * name)
{
setInstanceName(String(name));
}
private:
struct MDNSService * _services;
UdpContext* _conn;
String _hostName;
String _instanceName;
struct MDNSAnswer * _answers;
struct MDNSQuery * _query;
bool _newQuery;
bool _waitingForAnswers;
WiFiEventHandler _disconnectedHandler;
WiFiEventHandler _gotIPHandler;
uint16_t _getServicePort(char *service, char *proto);
MDNSTxt * _getServiceTxt(char *name, char *proto);
uint16_t _getServiceTxtLen(char *name, char *proto);
IPAddress _getRequestMulticastInterface();
void _parsePacket();
void _replyToTypeEnumRequest(IPAddress multicastInterface);
void _replyToInstanceRequest(uint8_t questionMask, uint8_t responseMask, char * service, char *proto, uint16_t port, IPAddress multicastInterface);
MDNSAnswer* _getAnswerFromIdx(int idx);
int _getNumAnswers();
bool _listen();
void _restart();
};
} // namespace Legacy_MDNSResponder
#endif //ESP8266MDNS_H

View File

@ -25,6 +25,7 @@
#include <Schedule.h>
#include <AddrList.h>
#include "ESP8266mDNS.h"
#include "LEAmDNS_Priv.h"

View File

@ -14,7 +14,7 @@
- Presenting a DNS-SD service to interested observers, eg. a http server by presenting _http._tcp service
- Support for multi-level compressed names in input; in output only a very simple one-leven full-name compression is implemented
- Probing host and service domains for uniqueness in the local network
- Tiebreaking while probing is supportet in a very minimalistic way (the 'higher' IP address wins the tiebreak)
- Tiebreaking while probing is supported in a very minimalistic way (the 'higher' IP address wins the tiebreak)
- Announcing available services after successful probing
- Using fixed service TXT items or
- Using dynamic service TXT items for presented services (via callback)
@ -172,6 +172,7 @@ class MDNSResponder
{
public:
/* INTERFACE */
MDNSResponder(void);
virtual ~MDNSResponder(void);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,328 @@
/*
LEAmDNS2Host_Debug.h
License (MIT license):
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "ESP8266mDNS.h"
#include "LEAmDNS2Host.h"
#include "LEAmDNS2_Priv.h"
namespace esp8266
{
namespace experimental
{
#ifdef DEBUG_ESP_PORT
/*
clsLEAmDNS2_Host::_DH
*/
const char* clsLEAMDNSHost::_DH(const clsLEAMDNSHost::clsService* p_pService /*= 0*/) const
{
static char acBuffer[16 + 64];
*acBuffer = 0;
sprintf_P(acBuffer, PSTR("[mDNS]"));
if (p_pService)
{
strcat_P(acBuffer, PSTR(">"));
strcat(acBuffer, _service2String(p_pService));
}
return acBuffer;
}
/*
clsLEAmDNS2_Host::_service2String
*/
const char* clsLEAMDNSHost::_service2String(const clsLEAMDNSHost::clsService* p_pService) const
{
static char acBuffer[64];
*acBuffer = 0;
if (p_pService)
{
sprintf_P(acBuffer, PSTR("%s.%s%s.%s%s.local"),
(p_pService->m_pcInstanceName ? : "-"),
(p_pService->m_pcType ? ('_' == *(p_pService->m_pcType) ? "" : "_") : "-"),
(p_pService->m_pcType ? : "-"),
(p_pService->m_pcProtocol ? ('_' == *(p_pService->m_pcProtocol) ? "" : "_") : "-"),
(p_pService->m_pcProtocol ? : "-"));
}
return acBuffer;
}
/*
clsLEAmDNS2_Host::_printRRDomain
*/
bool clsLEAMDNSHost::_printRRDomain(const clsLEAMDNSHost::clsRRDomain& p_RRDomain) const
{
//DEBUG_OUTPUT.printf_P(PSTR("Domain: "));
const char* pCursor = p_RRDomain.m_acName;
uint8_t u8Length = *pCursor++;
if (u8Length)
{
while (u8Length)
{
for (uint8_t u = 0; u < u8Length; ++u)
{
DEBUG_OUTPUT.printf_P(PSTR("%c"), *(pCursor++));
}
u8Length = *pCursor++;
if (u8Length)
{
DEBUG_OUTPUT.printf_P(PSTR("."));
}
}
}
else // empty domain
{
DEBUG_OUTPUT.printf_P(PSTR("-empty-"));
}
//DEBUG_OUTPUT.printf_P(PSTR("\n"));
return true;
}
/*
clsLEAmDNS2_Host::_printRRAnswer
*/
bool clsLEAMDNSHost::_printRRAnswer(const clsLEAMDNSHost::clsRRAnswer& p_RRAnswer) const
{
DEBUG_OUTPUT.printf_P(PSTR("%s RRAnswer: "), _DH());
_printRRDomain(p_RRAnswer.m_Header.m_Domain);
DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, "), p_RRAnswer.m_Header.m_Attributes.m_u16Type, p_RRAnswer.m_Header.m_Attributes.m_u16Class, p_RRAnswer.m_u32TTL);
switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type & (~0x8000)) // Topmost bit might carry 'cache flush' flag
{
#ifdef MDNS_IPV4_SUPPORT
case DNS_RRTYPE_A:
DEBUG_OUTPUT.printf_P(PSTR("A IP:%s"), ((const clsRRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str());
break;
#endif
case DNS_RRTYPE_PTR:
DEBUG_OUTPUT.printf_P(PSTR("PTR "));
_printRRDomain(((const clsRRAnswerPTR*)&p_RRAnswer)->m_PTRDomain);
break;
case DNS_RRTYPE_TXT:
{
size_t stTxtLength = ((const clsRRAnswerTXT*)&p_RRAnswer)->m_Txts.c_strLength();
char* pTxts = new char[stTxtLength];
if (pTxts)
{
((/*const c_str()!!*/clsRRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts);
DEBUG_OUTPUT.printf_P(PSTR("TXT(%u) %s"), stTxtLength, pTxts);
delete[] pTxts;
}
break;
}
#ifdef MDNS_IPV6_SUPPORT
case DNS_RRTYPE_AAAA:
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_RRAnswer)->m_IPAddress.toString().c_str());
break;
#endif
case DNS_RRTYPE_SRV:
DEBUG_OUTPUT.printf_P(PSTR("SRV Port:%u "), ((const clsRRAnswerSRV*)&p_RRAnswer)->m_u16Port);
_printRRDomain(((const clsRRAnswerSRV*)&p_RRAnswer)->m_SRVDomain);
break;
default:
DEBUG_OUTPUT.printf_P(PSTR("generic "));
break;
}
DEBUG_OUTPUT.printf_P(PSTR("\n"));
return true;
}
/*
clsLEAmDNS2_Host::_RRType2Name
*/
const char* clsLEAMDNSHost::_RRType2Name(uint16_t p_u16RRType) const
{
static char acRRName[16];
*acRRName = 0;
switch (p_u16RRType & (~0x8000)) // Topmost bit might carry 'cache flush' flag
{
#ifdef MDNS_IPV4_SUPPORT
case DNS_RRTYPE_A: strcpy_P(acRRName, PSTR("A")); break;
#endif
case DNS_RRTYPE_PTR: strcpy_P(acRRName, PSTR("PTR")); break;
case DNS_RRTYPE_TXT: strcpy_P(acRRName, PSTR("TXT")); break;
#ifdef MDNS_IPV6_SUPPORT
case DNS_RRTYPE_AAAA: strcpy_P(acRRName, PSTR("AAAA")); break;
#endif
case DNS_RRTYPE_SRV: strcpy_P(acRRName, PSTR("SRV")); break;
case clsConsts::u8DNS_RRTYPE_NSEC: strcpy_P(acRRName, PSTR("NSEC")); break;
case DNS_RRTYPE_ANY: strcpy_P(acRRName, PSTR("ANY")); break;
default: sprintf_P(acRRName, PSTR("Unknown(0x%04X"), p_u16RRType); // MAX 15!
}
return acRRName;
}
/*
clsLEAmDNS2_Host::_RRClass2String
*/
const char* clsLEAMDNSHost::_RRClass2String(uint16_t p_u16RRClass,
bool p_bIsQuery) const
{
static char acClassString[16];
*acClassString = 0;
if (p_u16RRClass & 0x0001)
{
strcat_P(acClassString, PSTR("IN ")); // 3
}
if (p_u16RRClass & 0x8000)
{
strcat_P(acClassString, (p_bIsQuery ? PSTR("UNICAST ") : PSTR("FLUSH "))); // 8/6
}
return acClassString; // 11
}
/*
clsLEAmDNS2_Host::_replyFlags2String
*/
const char* clsLEAMDNSHost::_replyFlags2String(uint32_t p_u32ReplyFlags) const
{
static char acFlagsString[64];
*acFlagsString = 0;
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::A))
{
strcat_P(acFlagsString, PSTR("A ")); // 2
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_IPv4))
{
strcat_P(acFlagsString, PSTR("PTR_IPv4 ")); // 7
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_IPv6))
{
strcat_P(acFlagsString, PSTR("PTR_IPv6 ")); // 7
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::AAAA))
{
strcat_P(acFlagsString, PSTR("AAAA ")); // 5
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_TYPE))
{
strcat_P(acFlagsString, PSTR("PTR_TYPE ")); // 9
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_NAME))
{
strcat_P(acFlagsString, PSTR("PTR_NAME ")); // 9
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::TXT))
{
strcat_P(acFlagsString, PSTR("TXT ")); // 4
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::SRV))
{
strcat_P(acFlagsString, PSTR("SRV ")); // 4
}
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::NSEC))
{
strcat_P(acFlagsString, PSTR("NSEC ")); // 5
}
if (0 == p_u32ReplyFlags)
{
strcpy_P(acFlagsString, PSTR("none"));
}
// Remove trailing spaces
while ((*acFlagsString) &&
(' ' == acFlagsString[strlen(acFlagsString) - 1]))
{
acFlagsString[strlen(acFlagsString) - 1] = 0;
}
return acFlagsString; // 63
}
/*
clsLEAmDNS2_Host::_NSECBitmap2String
*/
const char* clsLEAMDNSHost::_NSECBitmap2String(const clsNSECBitmap* p_pNSECBitmap) const
{
static char acFlagsString[32];
*acFlagsString = 0;
#ifdef MDNS_IPV4_SUPPORT
if (p_pNSECBitmap->getBit(DNS_RRTYPE_A))
{
strcat_P(acFlagsString, PSTR("A ")); // 2
}
#endif
if (p_pNSECBitmap->getBit(DNS_RRTYPE_PTR))
{
strcat_P(acFlagsString, PSTR("PTR ")); // 4
}
#ifdef MDNS_IPV6_SUPPORT
if (p_pNSECBitmap->getBit(DNS_RRTYPE_AAAA))
{
strcat_P(acFlagsString, PSTR("AAAA ")); // 5
}
#endif
if (p_pNSECBitmap->getBit(DNS_RRTYPE_TXT))
{
strcat_P(acFlagsString, PSTR("TXT ")); // 4
}
if (p_pNSECBitmap->getBit(DNS_RRTYPE_SRV))
{
strcat_P(acFlagsString, PSTR("SRV ")); // 4
}
if (p_pNSECBitmap->getBit(clsConsts::u8DNS_RRTYPE_NSEC))
{
strcat_P(acFlagsString, PSTR("NSEC ")); // 5
}
if (!*acFlagsString)
{
strcpy_P(acFlagsString, PSTR("none"));
}
return acFlagsString; // 31
}
#endif // DEBUG_ESP_PORT
} // namespace MDNSImplementation
} // namespace esp8266

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,262 @@
/*
LEAmDNS2_Backbone.cpp
License (MIT license):
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "ESP8266mDNS.h"
#include "LEAmDNS2Host.h"
#include "LEAmDNS2_Priv.h"
namespace esp8266
{
namespace experimental
{
/*
clsLEAmDNS2_Host::clsBackbone::clsBackbone constructor
*/
clsLEAMDNSHost::clsBackbone::clsBackbone(void)
: m_pUDPContext(0),
m_bDelayUDPProcessing(false),
m_u32DelayedDatagrams(0),
m_uniqueHost(0)
{
}
/*
clsLEAmDNS2_Host::clsBackbone::clsBackbone destructor
*/
clsLEAMDNSHost::clsBackbone::~clsBackbone(void)
{
_releaseUDPContext();
}
/*
clsLEAmDNS2_Host::clsBackbone::init
*/
bool clsLEAMDNSHost::clsBackbone::init(void)
{
return _allocUDPContext();
}
/*
clsLEAmDNS2_Host::clsBackbone::addHost
*/
UdpContext* clsLEAMDNSHost::clsBackbone::addHost(clsLEAMDNSHost* p_pHost)
{
UdpContext* pUDPContext = nullptr;
if ((m_pUDPContext) && (p_pHost) && (m_uniqueHost == nullptr))
{
m_uniqueHost = p_pHost;
pUDPContext = m_pUDPContext;
}
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s addHost: %s to add host!\n"), _DH(), (pUDPContext ? "Succeeded" : "FAILED")););
return pUDPContext;
}
/*
clsLEAmDNS2_Host::clsBackbone::removeHost
*/
bool clsLEAMDNSHost::clsBackbone::removeHost(clsLEAMDNSHost* p_pHost)
{
bool bResult = false;
if ((p_pHost) && (m_uniqueHost == p_pHost))
{
m_uniqueHost = nullptr;
bResult = true;
}
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s removeHost: %s to remove host!\n"), _DH(), (bResult ? "Succeeded" : "FAILED")););
return bResult;
}
/*
clsLEAmDNS2_Host::clsBackbone::hostCount
*/
size_t clsLEAMDNSHost::clsBackbone::hostCount(void) const
{
return m_uniqueHost == nullptr ? 0 : 1;
}
/*
clsLEAMDNSHost::clsBackbone::::setDelayUDPProcessing
When executing _sendMessage, with multiple or larger messages, sometimes the ESP IP stack seems
to need a small delay to get the job done. To allow for this delay, a 'delay' was added after one
send operation. However, while 'taking' this delay, sometimes a UDP datagram is received and
processed (which might cause another send operation or change global states).
To avoid 're-entry-like' problems, UDP processing might be blocked for a short period of time.
*/
bool clsLEAMDNSHost::clsBackbone::setDelayUDPProcessing(bool p_bDelayUDPProcessing)
{
if (m_bDelayUDPProcessing != p_bDelayUDPProcessing)
{
m_bDelayUDPProcessing = p_bDelayUDPProcessing;
if ((!m_bDelayUDPProcessing) &&
(m_u32DelayedDatagrams))
{
DEBUG_EX_INFO2(if (6 <= m_u32DelayedDatagrams) DEBUG_OUTPUT.printf_P(PSTR("%s setDelayUDPProcessing: Processing %u delayed datagram(s)\n"), _DH(), m_u32DelayedDatagrams););
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s setDelayUDPProcessing: Processing %u delayed datagram(s)\n"), _DH(), m_u32DelayedDatagrams););
_processUDPInput();
}
m_u32DelayedDatagrams = 0;
}
return true;
}
/*
clsLEAmDNS2_Host::clsBackbone::_allocUDPContext
*/
bool clsLEAMDNSHost::clsBackbone::_allocUDPContext(void)
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext\n"), _DH()););
if (_releaseUDPContext())
{
m_pUDPContext = new UdpContext;
if (m_pUDPContext)
{
m_pUDPContext->ref();
//ip_set_option(m_pUDPContext->pcb(), SOF_REUSEADDR);
//udp_bind_netif(m_pUDPContext->pcb(), m_pNetIf);
if (m_pUDPContext->listen(IP_ANY_TYPE, DNS_MQUERY_PORT))
{
// This is NOT the TTL (Time-To-Live) for MDNS records, but the subnet level distance MDNS records should travel.
// 1 sets the subnet distance to 'local', which is default for MDNS.
// (Btw.: 255 would set it to 'as far as possible' -> internet), however, RFC 3171 seems to force 255 instead
const uint8_t c_u8MulticastTTL = 255;//1;//255;
m_pUDPContext->setMulticastTTL(c_u8MulticastTTL);
m_pUDPContext->onRx(std::bind(&clsLEAMDNSHost::clsBackbone::_processUDPInput, this));
/* m_pUDPContext->onRx([&](void)->void
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext::onRx Received data!\n"), _DH()););
});*/
m_pUDPContext->connect(IP_ANY_TYPE, DNS_MQUERY_PORT);
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: Succeeded to alloc UDPContext!\n"), _DH()););
}
else
{
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: FAILED to make UDPContext listening!\n"), _DH()););
_releaseUDPContext();
}
}
else
{
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: FAILED to alloc UDPContext!\n"), _DH()););
}
}
DEBUG_EX_ERR(if (!m_pUDPContext) DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: FAILED!\n"), _DH()););
return (0 != m_pUDPContext);
}
/*
clsLEAmDNS2_Host::clsBackbone::_releaseUDPContext
*/
bool clsLEAMDNSHost::clsBackbone::_releaseUDPContext(void)
{
if (m_pUDPContext)
{
m_pUDPContext->unref();
m_pUDPContext = nullptr;
}
return true;
}
/*
clsLEAmDNS2_Host::clsBackbone::_processUDPInput
Called in SYS context!
*/
bool clsLEAMDNSHost::clsBackbone::_processUDPInput(void)
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput\n"), _DH()););
bool bResult = true;
if (!m_bDelayUDPProcessing)
{
while ((m_pUDPContext) &&
(m_pUDPContext->next()))
{
clsLEAMDNSHost* pHost = _findHost();
bResult = pHost->_processUDPInput();
DEBUG_EX_INFO2_IF(!bResult,
DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput: FAILED to process UDP input!\n"), _DH()));
DEBUG_EX_ERR_IF((-1) != m_pUDPContext->peek(),
DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput: !!!! CONTENT LEFT IN UDP BUFFER !!!!\n"),
_DH()));
m_pUDPContext->flush();
}
}
else
{
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput: Delaying datagram!\n"), _DH()););
++m_u32DelayedDatagrams;
}
return bResult;
}
/*
MISC
*/
#if not defined ESP_8266_MDNS_INCLUDE || defined DEBUG_ESP_PORT
/*
clsLEAmDNS2_Host::clsBackbone::_DH
*/
const char* clsLEAMDNSHost::clsBackbone::_DH(void) const
{
static char acBuffer[20] = { 0, };
if (!acBuffer[0])
{
strcpy_P(acBuffer, PSTR("[mDNS::backbone]"));
}
return acBuffer;
}
#endif
} // namespace MDNSImplementation
} // namespace esp8266

View File

@ -0,0 +1,115 @@
/*
LEAmDNS_Priv.h
License (MIT license):
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef MDNS2_PRIV_H
#define MDNS2_PRIV_H
/*
LWIP_OPEN_SRC
*/
#ifndef LWIP_OPEN_SRC
#define LWIP_OPEN_SRC
#endif
/*
Enable class debug functions
*/
#define ESP_8266_MDNS_INCLUDE
//#define DEBUG_ESP_MDNS_RESPONDER // force debug, arduino IDE uses DEBUG_ESP_MDNS
/*
Enable/disable debug trace macros
*/
#if defined(DEBUG_ESP_PORT)
#define DEBUG_ESP_MDNS_ERR
#endif
#if defined(DEBUG_ESP_PORT) && (defined(DEBUG_ESP_MDNS) || defined(DEBUG_ESP_MDNS_RESPONDER))
#define DEBUG_ESP_MDNS_INFO
#define DEBUG_ESP_MDNS_INFO2
//#define DEBUG_ESP_MDNS_TX
//#define DEBUG_ESP_MDNS_RX
#endif
#ifdef DEBUG_ESP_PORT
#define DEBUG_OUTPUT DEBUG_ESP_PORT
#else
#define DEBUG_OUTPUT Serialx
#endif
#ifdef DEBUG_ESP_MDNS_INFO
#define DEBUG_EX_INFO(A) A
#define DEBUG_EX_INFO_IF(C,A...) do if (C) { A; } while (0)
#else
#define DEBUG_EX_INFO(A)
#define DEBUG_EX_INFO_IF(C,A...)
#endif
#ifdef DEBUG_ESP_MDNS_INFO2
#define DEBUG_EX_INFO2(A) A
#define DEBUG_EX_INFO2_IF(C,A...) do if (C) { A; } while (0)
#else
#define DEBUG_EX_INFO2(A)
#define DEBUG_EX_INFO2_IF(C,A...)
#endif
#ifdef DEBUG_ESP_MDNS_ERR
#define DEBUG_EX_ERR(A) A
#define DEBUG_EX_ERR_IF(C,A...) do if (C) { A; } while (0)
#else
#define DEBUG_EX_ERR(A)
#define DEBUG_EX_ERR_IF(C,A...)
#endif
#ifdef DEBUG_ESP_MDNS_TX
#define DEBUG_EX_TX(A) do { A; } while (0)
#else
#define DEBUG_EX_TX(A)
#endif
#ifdef DEBUG_ESP_MDNS_RX
#define DEBUG_EX_RX(A) do { A; } while (0)
#else
#define DEBUG_EX_RX(A)
#endif
/*
Enable/disable the usage of the F() macro in debug trace printf calls.
There needs to be an PGM comptible printf function to use this.
USE_PGM_PRINTF and F
*/
#define USE_PGM_PRINTF
#ifdef USE_PGM_PRINTF
#else
#ifdef F
#undef F
#endif
#define F(A) A
#endif
#endif // MDNS2_PRIV_H

View File

@ -0,0 +1,31 @@
/*
LEAmDNS2_lwIPdefs.h
License (MIT license):
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef LEAMDNS2_LWIPDEFS_H
#define LEAMDNS2_LWIPDEFS_H
#include <lwip/init.h>
#include <lwip/prot/dns.h> // DNS_RRTYPE_xxx, DNS_MQUERY_PORT
#endif // LEAMDNS2_LWIPDEFS_H

View File

@ -37,6 +37,7 @@ extern "C" {
#include "user_interface.h"
}
#include "ESP8266mDNS.h"
#include "LEAmDNS_lwIPdefs.h"
#include "LEAmDNS_Priv.h"
@ -1982,7 +1983,7 @@ bool MDNSResponder::_checkServiceQueryCache(void)
/*
MDNSResponder::_replyMaskForHost
Determines the relavant host answers for the given question.
Determines the relevant host answers for the given question.
- A question for the hostname (eg. esp8266.local) will result in an A/AAAA (eg. 192.168.2.129) reply.
- A question for the reverse IP address (eg. 192-168.2.120.inarpa.arpa) will result in an PTR_IP4 (eg. esp8266.local) reply.

View File

@ -22,55 +22,13 @@
*/
#include "lwip/igmp.h"
#include <lwip/igmp.h>
#include <stdlib_noniso.h> // strrstr()
#include "ESP8266mDNS.h"
#include "LEAmDNS_lwIPdefs.h"
#include "LEAmDNS_Priv.h"
namespace
{
/*
strrstr (static)
Backwards search for p_pcPattern in p_pcString
Based on: https://stackoverflow.com/a/1634398/2778898
*/
const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pcPattern)
{
const char* pcResult = 0;
size_t stStringLength = (p_pcString ? strlen(p_pcString) : 0);
size_t stPatternLength = (p_pcPattern ? strlen(p_pcPattern) : 0);
if ((stStringLength) &&
(stPatternLength) &&
(stPatternLength <= stStringLength))
{
// Pattern is shorter or has the same length tham the string
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s)
{
if (0 == strncmp(s, p_pcPattern, stPatternLength))
{
pcResult = s;
break;
}
}
}
return pcResult;
}
} // anonymous
namespace esp8266
{

View File

@ -53,7 +53,7 @@ namespace MDNSImplementation
//#define ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
// Enable/disable debug trace macros
#ifdef DEBUG_ESP_MDNS_RESPONDER
#if defined(DEBUG_ESP_PORT) && defined(DEBUG_ESP_MDNS_RESPONDER)
#define DEBUG_ESP_MDNS_INFO
#define DEBUG_ESP_MDNS_ERR
#define DEBUG_ESP_MDNS_TX
@ -64,22 +64,22 @@ namespace MDNSImplementation
#ifdef DEBUG_ESP_MDNS_INFO
#define DEBUG_EX_INFO(A) A
#else
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
#define DEBUG_EX_INFO(A)
#endif
#ifdef DEBUG_ESP_MDNS_ERR
#define DEBUG_EX_ERR(A) A
#else
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
#define DEBUG_EX_ERR(A)
#endif
#ifdef DEBUG_ESP_MDNS_TX
#define DEBUG_EX_TX(A) A
#else
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
#define DEBUG_EX_TX(A)
#endif
#ifdef DEBUG_ESP_MDNS_RX
#define DEBUG_EX_RX(A) A
#else
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
#define DEBUG_EX_RX(A)
#endif
#ifdef DEBUG_ESP_PORT

View File

@ -22,6 +22,7 @@
*/
#include "ESP8266mDNS.h"
#include "LEAmDNS_Priv.h"
#include "LEAmDNS_lwIPdefs.h"
@ -787,7 +788,7 @@ bool MDNSResponder::stcMDNS_RRDomain::compare(const stcMDNS_RRDomain& p_Other) c
{
if (*((unsigned char*)pT)) // Not 0
{
pT += (1 + * ((unsigned char*)pT)); // Shift by length byte and lenght
pT += (1 + * ((unsigned char*)pT)); // Shift by length byte and length
pO += (1 + * ((unsigned char*)pO));
}
else // Is 0 -> Successfully reached the end

View File

@ -26,6 +26,7 @@ extern "C" {
#include "user_interface.h"
}
#include "ESP8266mDNS.h"
#include "LEAmDNS_lwIPdefs.h"
#include "LEAmDNS_Priv.h"