From 6ea12bd3c2eee7682dc9379728f4dc604c6bcb75 Mon Sep 17 00:00:00 2001 From: Matthew Blythe Date: Sun, 2 Apr 2017 20:17:35 -0600 Subject: [PATCH 1/5] add support for TXT records in query responses --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 100 ++++++++++++++++-- libraries/ESP8266mDNS/ESP8266mDNS.h | 4 + .../mDNS-SD_Extended/mDNS-SD_Extended.ino | 11 ++ 3 files changed, 109 insertions(+), 6 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index e67ba75c89..a6dcc230df 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -105,6 +105,7 @@ struct MDNSTxt{ struct MDNSAnswer { MDNSAnswer* next; + MDNSTxt * txts; uint8_t ip[4]; uint16_t port; char *hostname; @@ -137,6 +138,13 @@ MDNSResponder::~MDNSResponder() { answer = _getAnswerFromIdx(n); os_free(answer->hostname); os_free(answer); + MDNSTxt *txt; + MDNSTxt *nextTxt = answer->txts; + while(nextTxt != nullptr){ + txt = nextTxt; + nextTxt = nextTxt->_next; + delete txt; + } answer = 0; } _answers = 0; @@ -382,6 +390,66 @@ uint16_t MDNSResponder::port(int idx) { return answer->port; } +int MDNSResponder::numTxt(int idx) { + MDNSAnswer *answer = _getAnswerFromIdx(idx); + if (answer == 0) { + return 0; + } + MDNSTxt *txt = answer->txts; + int numTxt = 0; + while(txt != nullptr){ + numTxt++; + txt = txt->_next; + } + return numTxt; +} + +bool MDNSResponder::hasTxt(int idx, char * key) { + MDNSAnswer *answer = _getAnswerFromIdx(idx); + if (answer == 0) { + return false; + } + MDNSTxt *txt = answer->txts; + while(txt != nullptr){ + if(txt->_txt.startsWith(String(key)+'=')){ + return true; + } + txt = txt->_next; + } + return false; +} + +String MDNSResponder::txt(int idx, char * key) { + MDNSAnswer *answer = _getAnswerFromIdx(idx); + if (answer == 0) { + return String(); + } + MDNSTxt *txt = answer->txts; + String cmp = String(key)+'='; + while(txt != nullptr){ + if(txt->_txt.startsWith(cmp)){ + return txt->_txt.substring(cmp.length()); + } + txt = txt->_next; + } + return String(); +} + +String MDNSResponder::txt(int idx, int txtIdx) { + MDNSAnswer *answer = _getAnswerFromIdx(idx); + if (answer == 0) { + return String(); + } + MDNSTxt *txt = answer->txts; + while(txt != nullptr && txtIdx-- > 0){ + txt = txt->_next; + } + if(txtIdx > 0 || txt==nullptr){ + return String(); + } + return txt->_txt; +} + MDNSAnswer* MDNSResponder::_getAnswerFromIdx(int idx) { MDNSAnswer *answer = _answers; while (answer != 0 && idx-- > 0) { @@ -488,6 +556,7 @@ void MDNSResponder::_parsePacket(){ uint16_t answerPort = 0; uint8_t answerIp[4] = { 0,0,0,0 }; char answerHostName[255]; + MDNSTxt * txtPtr = nullptr; bool serviceMatch = false; MDNSAnswer *answer; uint8_t partsCollected = 0; @@ -502,6 +571,13 @@ void MDNSResponder::_parsePacket(){ answer = _getAnswerFromIdx(n); os_free(answer->hostname); os_free(answer); + MDNSTxt *txt; + MDNSTxt *nextTxt = answer->txts; + while(nextTxt != nullptr){ + txt = nextTxt; + nextTxt = nextTxt->_next; + delete txt; + } answer = 0; } _answers = 0; @@ -589,14 +665,25 @@ void MDNSResponder::_parsePacket(){ else if (answerType == MDNS_TYPE_TXT) { partsCollected |= 0x02; - _conn_readS(hostName, answerRdlength); // Read rdata + while(answerRdlength){ + MDNSTxt *newtxt = new MDNSTxt; + uint16_t txtRdLength = _conn_read8(); + answerRdlength--; + txtRdLength = (answerRdlength_txt = String(hostName); + newtxt->_next = txtPtr; + txtPtr = newtxt; #ifdef MDNS_DEBUG_RX - Serial.printf("TXT %d ", answerRdlength); - for (int n = 0; n < answerRdlength; n++) { - Serial.printf("%c", hostName[n]); - } - Serial.println(); + Serial.printf(" %d:", txtRdLength); + for (int n = 0; n < txtRdLength; n++) { + Serial.printf("%02x ", hostName[n]); + } + Serial.printf("\n%s\n", hostName); #endif + } } else if (answerType == MDNS_TYPE_SRV) { @@ -665,6 +752,7 @@ void MDNSResponder::_parsePacket(){ } answer->next = 0; answer->hostname = 0; + answer->txts = txtPtr; // Populate new answer answer->port = answerPort; diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index c8b3ee89e1..ea4add326f 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -98,6 +98,10 @@ class MDNSResponder { String hostname(int idx); IPAddress IP(int idx); uint16_t port(int idx); + int numTxt(int idx); + bool hasTxt(int idx, char * key); + String txt(int idx, char * key); + String txt(int idx, int txtIdx); void enableArduino(uint16_t port, bool auth=false); diff --git a/libraries/ESP8266mDNS/examples/mDNS-SD_Extended/mDNS-SD_Extended.ino b/libraries/ESP8266mDNS/examples/mDNS-SD_Extended/mDNS-SD_Extended.ino index d3feedee56..0ca6bd0b0b 100644 --- a/libraries/ESP8266mDNS/examples/mDNS-SD_Extended/mDNS-SD_Extended.ino +++ b/libraries/ESP8266mDNS/examples/mDNS-SD_Extended/mDNS-SD_Extended.ino @@ -42,6 +42,8 @@ void setup() { } Serial.println("mDNS responder started"); MDNS.addService("esp", "tcp", 8080); // Announce esp tcp service on port 8080 + MDNS.addServiceTxt("esp", "tcp", "foo", "bar"); + MDNS.addServiceTxt("esp", "tcp", "chipid", String(ESP.getChipId(), HEX)); Serial.println("Sending mDNS query"); int n = MDNS.queryService("esp", "tcp"); // Send out query for esp tcp services @@ -62,6 +64,15 @@ void setup() { Serial.print(":"); Serial.print(MDNS.port(i)); Serial.println(")"); + if(MDNS.numTxt(i)>0){ + int num = MDNS.numTxt(i); + Serial.println(" TXT"); + for(int j=0; j < num; j++){ + Serial.print(" "); + Serial.println(MDNS.txt(i,j)); + } + Serial.println(" ENDTXT"); + } } } Serial.println(); From 441c74ed4d6b640ade4c2a944d67aa3d6f059a03 Mon Sep 17 00:00:00 2001 From: Matthew Blythe Date: Thu, 6 Apr 2017 23:52:34 -0600 Subject: [PATCH 2/5] changes to support receiving regular callbacks from MDNS --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 293 ++++++++++++++++---------- libraries/ESP8266mDNS/ESP8266mDNS.h | 40 +++- 2 files changed, 216 insertions(+), 117 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index a6dcc230df..7c9de30709 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -98,17 +98,112 @@ struct MDNSService { uint16_t _txtLen; // length of all txts }; -struct MDNSTxt{ - MDNSTxt * _next; - String _txt; -}; +MDNSTxt::MDNSTxt() : + _next(nullptr), + _txt() +{} + +MDNSTxt::~MDNSTxt(){ + if(_next != nullptr){ + delete _next; + } +} + +MDNSAnswer::MDNSAnswer() : + txts(nullptr), + ip({0,0,0,0}), + port(0), + hostname(nullptr) +{} + +MDNSAnswer::~MDNSAnswer(){ + if(txts != nullptr){ + delete txts; + } + if(hostname != nullptr){ + delete[] hostname; + } +} + +String MDNSAnswer::getHostname(){ + return hostname; +} + +IPAddress MDNSAnswer::getIP(){ + return IPAddress(ip); +} + +uint16_t MDNSAnswer::getPort(){ + return port; +} + +int MDNSAnswer::numTxt(){ + MDNSTxt *txt = txts; + int numTxt = 0; + while(txt != nullptr){ + numTxt++; + txt = txt->_next; + } + return numTxt; +} + +bool MDNSAnswer::hasTxt(char * key){ + MDNSTxt *txt = txts; + while(txt != nullptr){ + if(txt->_txt.startsWith(String(key)+'=')){ + return true; + } + txt = txt->_next; + } + return false; +} + +String MDNSAnswer::getTxt(char * key){ + MDNSTxt *txt = txts; + String cmp = String(key)+'='; + while(txt != nullptr){ + if(txt->_txt.startsWith(cmp)){ + return txt->_txt.substring(cmp.length()); + } + txt = txt->_next; + } + return String(); +} + +std::pair MDNSAnswer::getTxt(int idx){ + String tmp = getTxtString(idx); + int loc = tmp.indexOf('='); + if(loc == -1){ + return std::make_pair(tmp,String()); + } + else if(loc+1 == tmp.length()){ //the = is the last character + return std::make_pair(tmp.substring(0,loc),String()); + } + else{ + return std::make_pair(tmp.substring(0,loc),tmp.substring(loc+1)); + } +} + +String MDNSAnswer::getTxtString(int idx){ + MDNSTxt *txt = txts; + while(txt != nullptr && idx-- > 0){ + txt = txt->_next; + } + if(idx > 0 || txt==nullptr){ + return String(); + } + return txt->_txt; +} -struct MDNSAnswer { - MDNSAnswer* next; - MDNSTxt * txts; - uint8_t ip[4]; - uint16_t port; - char *hostname; +struct MDNSAnswerList { + MDNSAnswerList() : next(nullptr), answer() {} + ~MDNSAnswerList(){ + if(next != nullptr){ + delete next; + } + } + MDNSAnswerList* next; + MDNSAnswer answer; }; struct MDNSQuery { @@ -117,14 +212,18 @@ struct MDNSQuery { }; -MDNSResponder::MDNSResponder() : _conn(0) { - _services = 0; - _instanceName = ""; - _answers = 0; - _query = 0; - _newQuery = false; - _waitingForAnswers = false; -} +MDNSResponder::MDNSResponder() : + _services(nullptr), + _conn(nullptr), + _hostName(), + _instanceName(), + _answers(nullptr), + _query(nullptr), + _newQuery(false), + _waitingForAnswers(false), + _answerCallback() +{} + MDNSResponder::~MDNSResponder() { if (_query != 0) { os_free(_query); @@ -132,22 +231,10 @@ MDNSResponder::~MDNSResponder() { } // Clear answer list - MDNSAnswer *answer; - int numAnswers = _getNumAnswers(); - for (int n = numAnswers - 1; n >= 0; n--) { - answer = _getAnswerFromIdx(n); - os_free(answer->hostname); - os_free(answer); - MDNSTxt *txt; - MDNSTxt *nextTxt = answer->txts; - while(nextTxt != nullptr){ - txt = nextTxt; - nextTxt = nextTxt->_next; - delete txt; - } - answer = 0; + if(_answers != nullptr){ + delete _answers; + _answers = nullptr; } - _answers = 0; if (_conn) { _conn->unref(); @@ -368,23 +455,23 @@ int MDNSResponder::queryService(char *service, char *proto) { String MDNSResponder::hostname(int idx) { MDNSAnswer *answer = _getAnswerFromIdx(idx); - if (answer == 0) { + if (answer == nullptr) { return String(); } - return answer->hostname; + return answer->getHostname(); } IPAddress MDNSResponder::IP(int idx) { MDNSAnswer *answer = _getAnswerFromIdx(idx); - if (answer == 0) { + if (answer == nullptr) { return IPAddress(); } - return IPAddress(answer->ip); + return answer->getIP(); } uint16_t MDNSResponder::port(int idx) { MDNSAnswer *answer = _getAnswerFromIdx(idx); - if (answer == 0) { + if (answer == nullptr) { return 0; } return answer->port; @@ -392,78 +479,58 @@ uint16_t MDNSResponder::port(int idx) { int MDNSResponder::numTxt(int idx) { MDNSAnswer *answer = _getAnswerFromIdx(idx); - if (answer == 0) { + if (answer == nullptr) { return 0; } - MDNSTxt *txt = answer->txts; - int numTxt = 0; - while(txt != nullptr){ - numTxt++; - txt = txt->_next; - } - return numTxt; + return answer->numTxt(); } bool MDNSResponder::hasTxt(int idx, char * key) { MDNSAnswer *answer = _getAnswerFromIdx(idx); - if (answer == 0) { + if (answer == nullptr) { return false; } - MDNSTxt *txt = answer->txts; - while(txt != nullptr){ - if(txt->_txt.startsWith(String(key)+'=')){ - return true; - } - txt = txt->_next; - } - return false; + return answer->hasTxt(key); } String MDNSResponder::txt(int idx, char * key) { MDNSAnswer *answer = _getAnswerFromIdx(idx); - if (answer == 0) { + if (answer == nullptr) { return String(); } - MDNSTxt *txt = answer->txts; - String cmp = String(key)+'='; - while(txt != nullptr){ - if(txt->_txt.startsWith(cmp)){ - return txt->_txt.substring(cmp.length()); - } - txt = txt->_next; - } - return String(); + return answer->getTxt(key); } String MDNSResponder::txt(int idx, int txtIdx) { MDNSAnswer *answer = _getAnswerFromIdx(idx); - if (answer == 0) { - return String(); - } - MDNSTxt *txt = answer->txts; - while(txt != nullptr && txtIdx-- > 0){ - txt = txt->_next; - } - if(txtIdx > 0 || txt==nullptr){ + if (answer == nullptr) { return String(); } - return txt->_txt; + answer->getTxtString(txtIdx); +} + +MDNSAnswer* MDNSResponder::getAnswer(int idx) { + return _getAnswerFromIdx(idx); +} + +void MDNSResponder::setAnswerCallback(std::function cb){ + _answerCallback = cb; } MDNSAnswer* MDNSResponder::_getAnswerFromIdx(int idx) { - MDNSAnswer *answer = _answers; - while (answer != 0 && idx-- > 0) { + MDNSAnswerList *answer = _answers; + while (answer != nullptr && idx-- > 0) { answer = answer->next; } - if (idx > 0) { - return 0; + if (idx > 0 || answer == nullptr) { + return nullptr; } - return answer; + return &answer->answer; } int MDNSResponder::_getNumAnswers() { int numAnswers = 0; - MDNSAnswer *answer = _answers; + MDNSAnswerList *answer = _answers; while (answer != 0) { numAnswers++; answer = answer->next; @@ -534,7 +601,7 @@ void MDNSResponder::_parsePacket(){ Serial.printf("Reading answers RX: REQ, ID:%u, Q:%u, A:%u, NS:%u, ADD:%u\n", packetHeader[0], packetHeader[2], packetHeader[3], packetHeader[4], packetHeader[5]); #endif - if (!_waitingForAnswers) { + if (!_waitingForAnswers && !_answerCallback) { #ifdef MDNS_DEBUG_RX Serial.println("Not expecting any answers right now, returning"); #endif @@ -558,7 +625,7 @@ void MDNSResponder::_parsePacket(){ char answerHostName[255]; MDNSTxt * txtPtr = nullptr; bool serviceMatch = false; - MDNSAnswer *answer; + MDNSAnswerList *answer; uint8_t partsCollected = 0; uint8_t stringsRead = 0; @@ -566,21 +633,10 @@ void MDNSResponder::_parsePacket(){ // Clear answer list if (_newQuery) { - int oldAnswers = _getNumAnswers(); - for (int n = oldAnswers - 1; n >= 0; n--) { - answer = _getAnswerFromIdx(n); - os_free(answer->hostname); - os_free(answer); - MDNSTxt *txt; - MDNSTxt *nextTxt = answer->txts; - while(nextTxt != nullptr){ - txt = nextTxt; - nextTxt = nextTxt->_next; - delete txt; - } - answer = 0; + if(_answers != nullptr){ + delete _answers; + _answers = nullptr; } - _answers = 0; _newQuery = false; } @@ -734,33 +790,42 @@ void MDNSResponder::_parsePacket(){ } if ((partsCollected == 0x0F) && serviceMatch) { + if(_waitingForAnswers){ #ifdef MDNS_DEBUG_RX - Serial.println("All answers parsed, adding to _answers list.."); + Serial.println("All answers parsed, adding to _answers list.."); #endif - // Add new answer to answer list - if (_answers == 0) { - _answers = (struct MDNSAnswer*)(os_malloc(sizeof(struct MDNSAnswer))); - answer = _answers; - } - else { - answer = _answers; - while (answer->next != 0) { + // Add new answer to answer list + if (_answers == nullptr) { + _answers = new MDNSAnswerList(); + answer = _answers; + } + else { + answer = _answers; + while (answer->next != nullptr) { + answer = answers->next; + } + answer->next = new MDNSAnswerList(); answer = answer->next; } - answer->next = (struct MDNSAnswer*)(os_malloc(sizeof(struct MDNSAnswer))); - answer = answer->next; } - answer->next = 0; - answer->hostname = 0; - answer->txts = txtPtr; + else{ //must want an answerCallback + answer = new MDNSAnswerList(); + } // Populate new answer - answer->port = answerPort; + answer->answer.txts = txtPtr; + answer->answer.port = answerPort; for (int i = 0; i < 4; i++) { - answer->ip[i] = answerIp[i]; + answer->answer.ip[i] = answerIp[i]; + } + answer->answer.hostname = new char [strlen(answerHostName) + 1]; + os_strcpy(answer->answer.hostname, answerHostName); + if(!_waitingForAnswers){ + if(_answerCallback){ //double-check just to be sure, but this should be OK + _answerCallback(&answer->answer); + } + delete answer; } - answer->hostname = (char *)os_malloc(strlen(answerHostName) + 1); - os_strcpy(answer->hostname, answerHostName); _conn->flush(); return; } diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index ea4add326f..b56bb6b394 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -54,8 +54,38 @@ License (MIT license): class UdpContext; struct MDNSService; -struct MDNSTxt; -struct MDNSAnswer; +class MDNSTxt{ +friend class MDNSAnswer; +friend class MDNSResponder; +public: + MDNSTxt(); + ~MDNSTxt(); +private: + MDNSTxt * _next; + String _txt; +}; +class MDNSAnswer { +friend class MDNSResponder; +public: + MDNSAnswer(); + ~MDNSAnswer(); + + String getHostname(); + IPAddress getIP(); + uint16_t getPort(); + int numTxt(); + bool hasTxt(char * key); + String getTxt(char * key); + std::pair getTxt(int idx); + String getTxtString(int idx); + +private: + MDNSTxt * txts; + uint8_t ip[4]; + uint16_t port; + char *hostname; +}; +struct MDNSAnswerList; class MDNSResponder { public: @@ -102,6 +132,9 @@ class MDNSResponder { bool hasTxt(int idx, char * key); String txt(int idx, char * key); String txt(int idx, int txtIdx); + MDNSAnswer* getAnswer(int idx); + + void setAnswerCallback(std::function); void enableArduino(uint16_t port, bool auth=false); @@ -118,12 +151,13 @@ class MDNSResponder { UdpContext* _conn; String _hostName; String _instanceName; - struct MDNSAnswer * _answers; + struct MDNSAnswerList * _answers; struct MDNSQuery * _query; bool _newQuery; bool _waitingForAnswers; WiFiEventHandler _disconnectedHandler; WiFiEventHandler _gotIPHandler; + std::function _answerCallback; uint16_t _getServicePort(char *service, char *proto); From ac20bc587a01d73068d3bd9286ac09449fdf75ef Mon Sep 17 00:00:00 2001 From: Matthew Blythe Date: Sun, 9 Apr 2017 14:16:06 -0600 Subject: [PATCH 3/5] fix bad cherry-pick --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 7c9de30709..5bcf142a1f 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -802,7 +802,7 @@ void MDNSResponder::_parsePacket(){ else { answer = _answers; while (answer->next != nullptr) { - answer = answers->next; + answer = answer->next; } answer->next = new MDNSAnswerList(); answer = answer->next; From 86204ca24f1cef25642ba7fa4539b58603a0ae81 Mon Sep 17 00:00:00 2001 From: Matthew Blythe Date: Tue, 13 Jun 2017 21:56:03 -0600 Subject: [PATCH 4/5] fix compiler warnings --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 24 ++++++++++++++++-------- libraries/ESP8266mDNS/ESP8266mDNS.h | 8 ++++---- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 5bcf142a1f..526f08fe5d 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -111,7 +111,7 @@ MDNSTxt::~MDNSTxt(){ MDNSAnswer::MDNSAnswer() : txts(nullptr), - ip({0,0,0,0}), + ip(), //NOTE: should value-initialize to 0 port(0), hostname(nullptr) {} @@ -147,7 +147,7 @@ int MDNSAnswer::numTxt(){ return numTxt; } -bool MDNSAnswer::hasTxt(char * key){ +bool MDNSAnswer::hasTxt(const char * key){ MDNSTxt *txt = txts; while(txt != nullptr){ if(txt->_txt.startsWith(String(key)+'=')){ @@ -158,7 +158,7 @@ bool MDNSAnswer::hasTxt(char * key){ return false; } -String MDNSAnswer::getTxt(char * key){ +String MDNSAnswer::getTxt(const char * key){ MDNSTxt *txt = txts; String cmp = String(key)+'='; while(txt != nullptr){ @@ -441,7 +441,11 @@ int MDNSResponder::queryService(char *service, char *proto) { }; _conn->append(reinterpret_cast(ptrAttrs), 4); _waitingForAnswers = true; - _conn->send(); + if(!_conn->send()){ +#ifdef MDNS_DEBUG_ERR + Serial.println("ERROR: Query send failed!"); +#endif + } #ifdef MDNS_DEBUG_TX Serial.println("Waiting for answers.."); @@ -485,7 +489,7 @@ int MDNSResponder::numTxt(int idx) { return answer->numTxt(); } -bool MDNSResponder::hasTxt(int idx, char * key) { +bool MDNSResponder::hasTxt(int idx, const char * key) { MDNSAnswer *answer = _getAnswerFromIdx(idx); if (answer == nullptr) { return false; @@ -493,7 +497,7 @@ bool MDNSResponder::hasTxt(int idx, char * key) { return answer->hasTxt(key); } -String MDNSResponder::txt(int idx, char * key) { +String MDNSResponder::txt(int idx, const char * key) { MDNSAnswer *answer = _getAnswerFromIdx(idx); if (answer == nullptr) { return String(); @@ -506,7 +510,7 @@ String MDNSResponder::txt(int idx, int txtIdx) { if (answer == nullptr) { return String(); } - answer->getTxtString(txtIdx); + return answer->getTxtString(txtIdx); } MDNSAnswer* MDNSResponder::getAnswer(int idx) { @@ -1243,7 +1247,11 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 ip_addr_t ifaddr; ifaddr.addr = ip; _conn->setMulticastInterface(ifaddr); - _conn->send(); + if(!_conn->send()){ +#ifdef MDNS_DEBUG_ERR + Serial.println("ERROR: Reply send failed!"); +#endif + } } #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index b56bb6b394..ef2e05736a 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -74,8 +74,8 @@ friend class MDNSResponder; IPAddress getIP(); uint16_t getPort(); int numTxt(); - bool hasTxt(char * key); - String getTxt(char * key); + bool hasTxt(const char * key); + String getTxt(const char * key); std::pair getTxt(int idx); String getTxtString(int idx); @@ -129,8 +129,8 @@ class MDNSResponder { IPAddress IP(int idx); uint16_t port(int idx); int numTxt(int idx); - bool hasTxt(int idx, char * key); - String txt(int idx, char * key); + bool hasTxt(int idx, const char * key); + String txt(int idx, const char * key); String txt(int idx, int txtIdx); MDNSAnswer* getAnswer(int idx); From 9c166835dc411228659472017a5bec31ee998492 Mon Sep 17 00:00:00 2001 From: Matthew Blythe Date: Wed, 14 Jun 2017 21:52:14 -0600 Subject: [PATCH 5/5] fix memory leak --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 26a9e93c4a..87bca2f4ee 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -330,7 +330,7 @@ bool MDNSResponder::addServiceTxt(char *name, char *proto, char *key, char *valu if(strcmp(servicePtr->_name, name) == 0 && strcmp(servicePtr->_proto, proto) == 0){ //found a service name match if (servicePtr->_txtLen + txtLen > 1300) return false; //max txt record size - MDNSTxt *newtxt = new MDNSTxt; + MDNSTxt *newtxt = new MDNSTxt(); newtxt->_txt = String(key) + "=" + String(value); newtxt->_next = 0; if(servicePtr->_txts == 0) { //no services have been added @@ -687,6 +687,9 @@ void MDNSResponder::_parsePacket(){ Serial.println("failed to read the response name"); #endif _conn->flush(); + if(txtPtr){ + delete txtPtr; + } return; } _conn_readS(serviceName, tmp8); @@ -725,6 +728,9 @@ void MDNSResponder::_parsePacket(){ Serial.printf("Data len too long! %u\n", answerRdlength); #endif _conn->flush(); + if(txtPtr){ + delete txtPtr; + } return; } } @@ -752,7 +758,7 @@ void MDNSResponder::_parsePacket(){ else if (answerType == MDNS_TYPE_TXT) { partsCollected |= 0x02; while(answerRdlength){ - MDNSTxt *newtxt = new MDNSTxt; + MDNSTxt *newtxt = new MDNSTxt(); uint16_t txtRdLength = _conn_read8(); answerRdlength--; txtRdLength = (answerRdlengthflush(); + //NOTE: don't delete txtPtr because it's either part of _answers or has been deleted return; } } _conn->flush(); + if(txtPtr){ + delete txtPtr; + } return; }