Closed leifclaesson closed 2 years ago
HI @leifclaesson
I am running the mDNS_Web_Server example on a ESP32_LyraT board and I can ping 'local.ESP32' after start and also after waiting for more than 2 minutes just fine. I wonder if it has something to do with the OS from which the ping is originated from. I am using MacOSX. What is the OS you are testing with?
BTW: I only very quickly looked into how mDNS is supposed to work, so I could be wrong about it. So far it is my understanding that the server only is supposed to send out it's mDNS information when a client asks for it, so I would not expect it to broadcast its information periodically on it's own (except for when it is started), but only upon request. That is why I think it might be related to the mDNS implementation of the OS used to ping the ESP32 board.
Thanks Felix
Hello.
For what it's worth, I can reproduce this behaviour with espressif8266
.
Same sketch (mDNS_Web_Server example, only modified to set the ssid/password).
Compiling with Arduino IDE or pio doesn't seem to make any difference.
Here are my pio libs:
❯ pio update
Updating platformio/contrib-piohome 3.3.1 @ ~3.3.1 [Up-to-date]
Updating platformio/tool-unity 1.20500.200612 @ ~1.20500.0 [Up-to-date]
Updating platformio/tool-scons 4.40001.0 @ ~4.40001.0 [Up-to-date]
Platform Manager
================
Platform atmelavr
--------
Updating platformio/atmelavr 3.0.0 [Up-to-date]
Updating platformio/toolchain-atmelavr 1.50400.190710 @ ~1.50400.0 [Up-to-date]
Updating platformio/framework-arduino-avr 5.1.0 @ ~5.1.0 [Up-to-date]
Platform espressif8266
--------
Updating platformio/espressif8266 2.6.2 [Up-to-date]
Updating platformio/toolchain-xtensa 2.40802.200502 @ ~2.40802.191122 [Up-to-date]
Updating platformio/framework-arduinoespressif8266 3.20704.0 @ ~3.20704.0 [Up-to-date]
Updating platformio/tool-esptool 1.413.0 @ <2 [Up-to-date]
Updating platformio/tool-esptoolpy 1.20800.0 @ ~1.20800.0 [Up-to-date]
Updating platformio/tool-mkspiffs 1.200.0 @ ~1.200.0 [Up-to-date]
Updating platformio/tool-mklittlefs 1.203.200522 @ ~1.203.0 [Up-to-date]
I can ping esp8266.local
at first (both from Linux Mint 19.3 and OS X El Capitan), but after 2 minutes, it returns ping: esp8266.local: Name or service not known
.
I wrote a small bash loop to time it. I start the loop, wait 10 seconds, start the board and let loop and board run:
❯ while sleep 10; do; date; ping -c1 -w3 -O -q esp8266.local | grep received; done
Sat Dec 5 12:43:45 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:44:00 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:44:13 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:44:23 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:44:33 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:44:43 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:44:53 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:45:03 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:45:13 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:45:23 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:45:33 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:45:43 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:45:53 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:46:03 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:46:13 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:46:28 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:46:44 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:46:59 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:47:14 CET 2020
What's weird is that it might randomly start again after a while (2 or 3 minutes), without rebooting the board:
Sat Dec 5 12:47:59 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:48:14 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:48:29 CET 2020
ping: esp8266.local: Name or service not known
Sat Dec 5 12:48:44 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:48:54 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:49:04 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:49:14 CET 2020
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Sat Dec 5 12:49:24 CET 2020
It will stop again after exactly 2 minutes, though.
I realize my board isn't an esp32, but it seems to have the same problem as yours, though, so it might help spotting where the actual problem comes from.
[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.
Just doing some testing on this; will report back
[STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future.
OK I've made some checks with tcpdump.
I can confirm that with the mDNS server in the Espressif native framework (ESP-IDF v4.2), the same pattern of packets is sent. At startup, after obtaining an IP address the ESP32 first broadcasts an mDNS query for the hostname it is about to use (with a TTL of 2 minutes). It does this three times.
If no other machine responds (which would indicate this hostname is already assigned to another machine), the ESP32 then broadcasts an mDNS response to its own query, advertising its IP address (with a TTL of 2 mins). It does this three times.
After this initial announcement I did not see the ESP32 send any further mDNS packets during the 30min period of my test - although it did continue to send periodic ARP broadcasts (which are not related to mDNS).
However unlike the OP, I do not lose the ability to resolve the hostname after the 2 minute period... indeed all the machines on my LAN were still able to resolve and ping the host four hours later.
Looking into this a little more closely, I can see that it is in fact my residential gateway (FritzBox 7530) that has cached the mDNS result for the ESP32, and is serving it to other local clients via the 'normal' DNS service on port 53.
I can agree with @mjcross here. If resolution stops after 2 minutes, that means that the client did not re-query to refresh the record and so made it invalid. Generally it should have asked for the host about 1 minute in (half the TTL).
The MDNS lib in IDF is fully compliant and much tested.
If your application has long gaps between a client accessing the ESP32 via its mDNS hostname, then you might try getting the ESP32 to do an mDNS lookup of its own hostname using the resolve_mdns_host() API call every couple of minutes. This should keep the record 'fresh' in the cache of other machines on the LAN.
If that doesn't work then you might try periodically restarting the mDNS service on the ESP32 every couple of minutes using mdns_free() and mdns_init(), which should cause a re-broadcast of the initial mDNS registration.
try getting the ESP32 to do an mDNS lookup of its own hostname using the resolve_mdns_host() API call every couple of minutes. This should keep the record 'fresh' in the cache of other machines on the LAN.
This is an interesting idea! I will try this. Thank you!
If that doesn't work then you might try periodically restarting the mDNS service on the ESP32 every couple of minutes using mdns_free() and mdns_init(), which should cause a re-broadcast of the initial mDNS registration.
That was actually the first thing I tried -- this causes the ESP to crash and reboot after ~25 hours. Took me quite a while to find why my many ESP32s had trouble staying up, because you don't immediately notice the problem after adding the periodic reinit.. so, that one is not a good solution.
i have the exact same problem... googling my ass off trying to find a fix for this!
If your application has long gaps between a client accessing the ESP32 via its mDNS hostname, then you might try getting the ESP32 to do an mDNS lookup of its own hostname using the resolve_mdns_host() API call every couple of minutes. This should keep the record 'fresh' in the cache of other machines on the LAN.
I have tried but this approach does not work.
Sorry if this comment is off-topic for this bug report.
At least in my case, using Arduino-ESP32 2.0.0-alpha1 with a Fedora 32 x86_64 workstation, I have verified (using Wireshark) that MDNS queries made using avahi-daemon from the Fedora machine are actually answered by the ESP32 device, but avahi-daemon rejects the response because it is considered "invalid" due to having an echoed question record in the response packet. The end result is that the device "drops out" from being locatable via MDNS.
I have opened a bug report here.
exact same issue here with an MKR1010 SAMD 21 cpu using Mdns-generic library. Any clue ?
It seems like a fix for this (or very similar) problem has been implemented in https://github.com/espressif/esp-idf/issues/7453
Pardon my ignorance, but does that mean the fix is going to make it to arduino-esp32 at some point in time? Arduino-esp32 uses esp-IDF underneath, right?
Is the process for getting the latest and greatest a manual PR like this one? https://github.com/espressif/arduino-esp32/pull/5449
yes @nietaki . The latest IDF is available in that branch. We merge it into master from time to time
Thanks for the info @me-no-dev :+1:
FWIW, I stopped using mDNS completely, it was simply not reliable enough, and gets unwieldy when you have many devices. Getting rid of it saves firmware space too which can be crucial, especially on 1MB ESP8266 devices (such as smart light bulbs). I assign static IPs through my router instead.
I am struggling on this issue as well. My android app cannot get answer from esp32 completely, while in Windows 10, the esp32 only answer for the first time after the esp32 has been rebooted. i've been monitoring wireshark all the time, i've seen that Windows did sent question to esp32, but the esp32 just didn't answer it.
Anyway, is there any third party library other than ESPmDNS
?
Just for the record, the original MDNS issue appears to be mostly fixed in ESP32-Arduino 2.0.2. Devices using firmware compiled with this version no longer drop out from being locatable via MDNS.
@rradar
The header file of the MDNS lib (ESPmDNS.h) has a comment as the top of file that describes the usage. And there is this information:
"Call the update method in each iteration of the sketch's loop function."
I searched an update method but not found on this lib. Also i found a third part library (khoih-prog/MDNS_Generic), that have a method mdns.run(), what is called at each loop on the lib examples, and the examples have a comment informing that this line in necessary to work correctly.
I thinked some method called at each loop may be necessary to run the lib routines and repond to queries, but it apears to be missing on de lib. Some one else, notice this coment? Some sugestion?
PS: The ESP8266mDNS has the update method and the same comment. It is possibily a missing implementation on the ESPmDNS, I'm using.
PS2: Set the instance name on the loop, force the device to send again the response, but it is independent of any query. The ESP32 will always send again de response after call MDNS.setInstanceName(), what i think is ok in many cases.
Same problem for me. MDNS stops working.
I'm on IDF 5.1 with Arduino 3x now and there is no run or update method in the ESPmDNS
library.
/*
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)
MDNS-SD Suport 2015 Hristo Gochkov (hristo@espressif.com)
Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
Rewritten for ESP32 by Hristo Gochkov (hristo@espressif.com)
This is a simple implementation of multicast DNS query support for an Arduino
running on ESP32 chip.
Usage:
- Include the ESP32 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 ESP32MDNS_H
#define ESP32MDNS_H
#include "Arduino.h"
#include "IPv6Address.h"
#include "mdns.h"
//this should be defined at build time
#ifndef ARDUINO_VARIANT
#define ARDUINO_VARIANT "esp32"
#endif
class MDNSResponder {
public:
MDNSResponder();
~MDNSResponder();
bool begin(const String& hostName);
bool begin(const char* hostName){
return begin(String(hostName));
}
void end();
void setInstanceName(String name);
void setInstanceName(const char * name){
setInstanceName(String(name));
}
void setInstanceName(char * name){
setInstanceName(String(name));
}
bool addService(char *service, char *proto, uint16_t port);
bool addService(const char *service, const char *proto, uint16_t port){
return addService((char *)service, (char *)proto, port);
}
bool addService(String service, String proto, uint16_t port){
return addService(service.c_str(), proto.c_str(), port);
}
bool addServiceTxt(char *name, char *proto, char * key, char * value);
void addServiceTxt(const char *name, const char *proto, const char *key,const char * value){
addServiceTxt((char *)name, (char *)proto, (char *)key, (char *)value);
}
void addServiceTxt(String name, String proto, String key, String value){
addServiceTxt(name.c_str(), proto.c_str(), key.c_str(), value.c_str());
}
void enableArduino(uint16_t port=3232, bool auth=false);
void disableArduino();
void enableWorkstation(esp_interface_t interface=ESP_IF_WIFI_STA);
void disableWorkstation();
IPAddress queryHost(char *host, uint32_t timeout=2000);
IPAddress queryHost(const char *host, uint32_t timeout=2000){
return queryHost((char *)host, timeout);
}
IPAddress queryHost(String host, uint32_t timeout=2000){
return queryHost(host.c_str(), timeout);
}
int queryService(char *service, char *proto);
int queryService(const char *service, const char *proto){
return queryService((char *)service, (char *)proto);
}
int queryService(String service, String proto){
return queryService(service.c_str(), proto.c_str());
}
String hostname(int idx);
IPAddress IP(int idx);
IPv6Address IPv6(int idx);
uint16_t port(int idx);
int numTxt(int idx);
bool hasTxt(int idx, const char * key);
String txt(int idx, const char * key);
String txt(int idx, int txtIdx);
String txtKey(int idx, int txtIdx);
private:
String _hostname;
mdns_result_t * results;
mdns_result_t * _getResult(int idx);
mdns_txt_item_t * _getResultTxt(int idx, int txtIdx);
};
extern MDNSResponder MDNS;
#endif //ESP32MDNS_H
mDNS runs on it's own. It monitors network interfaces and acts accordingly. I can also say that mDNS works just fine. If you see something else, this is result of your own environment (mDNS client used or else). The mDNS service in ESP-IDF is certified and is the main reason why things like Matter, HomeKit and others are able to work. One way to force mDNS to "restart" is by turning the interface off and on. It will issue unsolicited packets to inform others on the network that it exists. It sounds like your client is not asking about it after the TTL expired.
The "internal task" is in the esp-mdns code. Not in Arduino
I see. What are the reasons that can stop it? The task does not get enough time?
There is no reason on the device itself. When interface is brought up, it broadcasts the device services. This is done unsolicited. From then on it's up to the client (your computer or whatever) to query the device. If the client heard the initial broadcast, it should add the device in it's list and provide the information until the TTL is half passed, after which point it should ask the device for update. What you see corresponds with the client not asking the device for update and only judging by the initial unsolicited broadcast, which after some time expires. Again, the service is fully automated and as long as the client obeys the rules, everything will be fine.
OK. there could be a few more reasons:
I see. There is no way my client wont ask the esp. Iam running a web app right now and seeing the fetch requests made against the hostname in the browser over and over again. It stopped working no matter what device I try. Tried windows, IOS and Android. Ping requests also doesnt work against the hostname. I did not try via IP yet tho. Will try to trigger this again tomorrow and see what is going on. But the esp is definitely connected to the network because I see it in my routers list.
Can some conflict occour if i set up the ESPmdns directly and also with ArduinoOTA? I assume OTA lib also uses the same mdns apis.
It can be that my router is acting funky.
This issue has been previously posted by others but was erroneously closed as "stale" without resolution. It is still a problem.
Hardware:
Board: LOLIN32, MH-ET-LIVE, DOIT devkit v1 and others. Happens with all ESP32 hardware I've tested. Core Installation version: 1.0.4 IDE name: Arduino IDE Flash Frequency: 80Mhz PSRAM enabled: no
Description:
I'm trying to use MDNS. Using the mDNS_Web_Server example, when the device starts, I am able to access the page at 'esp32.local/'. However, after two minutes, this stops working.
Manually resolving the mDNS address shows the same behavior - it works for the first two minutes after the device is started, then simply stops working.
I did a Wireshark capture on the IP address of the ESP32. It broadcasts the mDNS messages, with a TTL of 2 minutes. It only ever broadcasts those messages at startup (I left the device for ~20m).
If I manually call MDNS.begin periodically, it works, but the correct function for this is update() which is missing from the ESP32 version.
I was able to reproduce this on multiple dev boards, and several others have reported the same issue.
Sketch:
mDNS_Web_Server example (only modified to set the ssid/password)
Debug Messages:
None