Skip to content
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

[mDNS] ESP32C3 mDNS remove after a few minutes (IDFGH-6263) #7932

Closed
edieruby opened this issue Nov 19, 2021 · 9 comments
Closed

[mDNS] ESP32C3 mDNS remove after a few minutes (IDFGH-6263) #7932

edieruby opened this issue Nov 19, 2021 · 9 comments
Labels
Resolution: Done Issue is done internally Status: Resolved Issue is done internally

Comments

@edieruby
Copy link

edieruby commented Nov 19, 2021

  • Operating System: Windows
  • Using an IDE?: VS Code
  • Power Supply: USB
    I (48) boot: ESP-IDF v4.3.1-dirty 2nd stage bootloader
    I (49) boot: compile time 16:03:22
    I (49) boot: chip revision: 3
    I (51) boot.esp32c3: SPI Speed : 80MHz
    I (56) boot.esp32c3: SPI Mode : DIO
    I (60) boot.esp32c3: SPI Flash Size : 4MB

based on mDNS example.
add loop query mDNS service in a task.
mDNS service itself will remove after a few minutes.

src code:
mdns.zip

static void check_button(void)
{
static bool old_level = true;
bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO);
// if (!new_level && old_level)
{
query_mdns_service("_http", "_tcp");
}
old_level = new_level;
}

service remove:
image

static void check_button(void)
{
static bool old_level = true;
bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO);
// if (!new_level && old_level)
{
// query_mdns_service("_http", "_tcp");
}
old_level = new_level;
}

when disable query mDNS service , it work well.

@edieruby edieruby changed the title [mDNS]ESP32C3 mDNS remove after a few minutes [mDNS] ESP32C3 mDNS remove after a few minutes Nov 19, 2021
@espressif-bot espressif-bot added the Status: Opened Issue is new label Nov 19, 2021
@github-actions github-actions bot changed the title [mDNS] ESP32C3 mDNS remove after a few minutes [mDNS] ESP32C3 mDNS remove after a few minutes (IDFGH-6263) Nov 19, 2021
@atanisoft
Copy link

At what priority are you running the mDNS query task? mDNS task itself runs at a default of priority 1 (same as app_main). Since the C3 is a single core chip it is possible the mDNS query task is running at a higher priority than the mDNS task leading to the delays.

@david-cermak
Copy link
Collaborator

Hi @edieruby

I confirm that it could be a problem to repeatably query (PTR) the same service/protocol that you advertise (assuming you published the ESP32-Webserver on _http,_tcp, as well)

The problem is quite hard to explain and harder to fix.
Please refer to the chapter Querying here: https://datatracker.ietf.org/doc/html/rfc6762#section-5
This mdns component implements the full featured querirer, which should:

  • cache known answers
  • prevent from querying too often: the intervals between successive queries MUST increase by at least a factor of two
    but since it's not very easy to design an embedded library the continuous way as e.g. avahi-browse does and focus on constrained resources as embedded library should, the component relies on application to use it in consideration.

There're multiple ways to address this issue, from updating the docs and educating users to sending one-shot queries. The most easy seems to be using unicast PTR queries (if configured).
Can you try to apply this patch to see if it helps?

diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c
index 4240a1a787f..931aa9f579b 100644
--- a/components/mdns/mdns.c
+++ b/components/mdns/mdns.c
@@ -3682,7 +3682,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
         return NULL;
     }
     q->next = NULL;
-    q->unicast = search->type != MDNS_TYPE_PTR;
+    q->unicast = 1;
     q->type = search->type;
     q->host = search->instance;
     q->service = search->service;

@edieruby
Copy link
Author

edieruby commented Nov 20, 2021

@david-cermak I will try it.
Thank you.

I want to multiple ESP32-C3s to connect each other by TCP.
mDNS is used to discover each other.
I want each ESP32-C3 can discover other device in a certain time when the other device connected into WIFI.

I uploaded my test code above already.
I query PTR every 30s. I think it's not a high frequency.

confused that why it will affect publish its own mDNS service.

@edieruby
Copy link
Author

At what priority are you running the mDNS query task? mDNS task itself runs at a default of priority 1 (same as app_main). Since the C3 is a single core chip it is possible the mDNS query task is running at a higher priority than the mDNS task leading to the delays.

change the task priority , same problem.
If mDNS task delay, it will add later.
But it will not add after mDNS service is removed.

I will do more test.
Thank you.

@david-cermak
Copy link
Collaborator

@edieruby

confused that why it will affect publish its own mDNS service.

Please read this chapter https://datatracker.ietf.org/doc/html/rfc6762#section-5.2
This explains how the continuous mDNS querier should behave in order not to flood the local network with unnecessary repeating. This also requires the libraries to provide an asynchronous interface and cache entries. However the Espressif mnds implementation (for simplicity and usability in embedded environment) implements more like a synchronous API and provides no internal cashing of resolved services (please compare to the standard avahi/dns-sd services).
Ideally we should provide a set of callbacks/events to be fires once the desired service show up (or was removed). This would be quite a big change to API and very impractical, too.

So I think if you simply change the query type to unicast and let it run less frequently it should solve your issue.

I will try it.

Have you tested the unicast change? It should prevent from removing the service even if you query without any delay.

@edieruby
Copy link
Author

@edieruby

confused that why it will affect publish its own mDNS service.

Please read this chapter https://datatracker.ietf.org/doc/html/rfc6762#section-5.2 This explains how the continuous mDNS querier should behave in order not to flood the local network with unnecessary repeating. This also requires the libraries to provide an asynchronous interface and cache entries. However the Espressif mnds implementation (for simplicity and usability in embedded environment) implements more like a synchronous API and provides no internal cashing of resolved services (please compare to the standard avahi/dns-sd services). Ideally we should provide a set of callbacks/events to be fires once the desired service show up (or was removed). This would be quite a big change to API and very impractical, too.

So I think if you simply change the query type to unicast and let it run less frequently it should solve your issue.

I will try it.

Have you tested the unicast change? It should prevent from removing the service even if you query without any delay.

Not yet.
I will try it later.
Thank you.

@edieruby
Copy link
Author

Hi @edieruby

I confirm that it could be a problem to repeatably query (PTR) the same service/protocol that you advertise (assuming you published the ESP32-Webserver on _http,_tcp, as well)

The problem is quite hard to explain and harder to fix. Please refer to the chapter Querying here: https://datatracker.ietf.org/doc/html/rfc6762#section-5 This mdns component implements the full featured querirer, which should:

  • cache known answers
  • prevent from querying too often: the intervals between successive queries MUST increase by at least a factor of two
    but since it's not very easy to design an embedded library the continuous way as e.g. avahi-browse does and focus on constrained resources as embedded library should, the component relies on application to use it in consideration.

There're multiple ways to address this issue, from updating the docs and educating users to sending one-shot queries. The most easy seems to be using unicast PTR queries (if configured). Can you try to apply this patch to see if it helps?

diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c
index 4240a1a787f..931aa9f579b 100644
--- a/components/mdns/mdns.c
+++ b/components/mdns/mdns.c
@@ -3682,7 +3682,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
         return NULL;
     }
     q->next = NULL;
-    q->unicast = search->type != MDNS_TYPE_PTR;
+    q->unicast = 1;
     q->type = search->type;
     q->host = search->instance;
     q->service = search->service;

It works.

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels Nov 26, 2021
@espressif-bot espressif-bot added Status: Reviewing Issue is being reviewed and removed Status: In Progress Work is in progress labels Dec 17, 2021
espressif-bot pushed a commit that referenced this issue Jan 17, 2022
@espressif-bot espressif-bot added Resolution: Done Issue is done internally Status: Resolved Issue is done internally and removed Status: Reviewing Issue is being reviewed labels Jan 18, 2022
@david-cermak
Copy link
Collaborator

@edieruby Now, it's possible to send queries of both Unicast and Multicast types, even for PTR (added in 7eeeb01). Does it solve your issue? Please close if yes, or comment otherwise. Thanks!

dskulina pushed a commit to playable-tech/esp-idf that referenced this issue Feb 4, 2022
dskulina pushed a commit to playable-tech/esp-idf that referenced this issue Feb 5, 2022
@edieruby
Copy link
Author

edieruby commented Feb 7, 2022

works. Thanks!

@edieruby edieruby closed this as completed Feb 7, 2022
david-cermak added a commit to david-cermak/esp-protocols that referenced this issue Mar 24, 2022
gabsuren pushed a commit to gabsuren/esp-protocols-1 that referenced this issue Mar 25, 2022
gabsuren pushed a commit to gabsuren/esp-protocols-1 that referenced this issue Apr 8, 2022
gabsuren pushed a commit to gabsuren/esp-protocols-1 that referenced this issue May 17, 2022
gabsuren pushed a commit to gabsuren/esp-protocols-1 that referenced this issue May 27, 2022
gabsuren pushed a commit to gabsuren/esp-protocols-1 that referenced this issue May 27, 2022
gabsuren pushed a commit to gabsuren/esp-protocols-1 that referenced this issue May 27, 2022
0xFEEDC0DE64 pushed a commit to 0xFEEDC0DE64/esp-protocols that referenced this issue Jun 30, 2022
euripedesrocha pushed a commit to euripedesrocha/esp-protocols that referenced this issue Oct 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Resolved Issue is done internally
Projects
None yet
Development

No branches or pull requests

4 participants