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 not working with WiFi.mode(WIFI_AP_STA) on current git #8308

Closed
4 of 6 tasks
z01ne opened this issue Sep 10, 2021 · 12 comments · Fixed by #8705
Closed
4 of 6 tasks

mDNS not working with WiFi.mode(WIFI_AP_STA) on current git #8308

z01ne opened this issue Sep 10, 2021 · 12 comments · Fixed by #8705
Labels
component: MDNS type: bug waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.

Comments

@z01ne
Copy link

z01ne commented Sep 10, 2021

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: [current]
  • Development Env: [Arduino IDE]
  • Operating System: [Windows]

Problem Description

mDNS not working with WiFi.mode(WIFI_AP_STA) on current git, but working on v2.4.7

MCVE Sketch

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>

void setup(void) {
  Serial.begin(115200);

  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP("SETUP777685", "admin678");

  MDNS.begin("TestMDNS");
  MDNS.addService("http", "tcp", 80);
  MDNS.addServiceTxt("http", "tcp", "type", "smartctrl");
  MDNS.addServiceTxt("http", "tcp", "id", "777685");
}

void loop(void) {
  MDNS.update();
}
@mcspr
Copy link
Collaborator

mcspr commented Oct 3, 2021

Seems to be a logical error when IP isSet() is false for the STA interface. But, logs do show that it finds the AP netif, and attempts to send the data

for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next)
{
if (netif_is_up(pNetIf))
{
IPAddress fromIPAddress;
//fromIPAddress = _getResponseMulticastInterface();
fromIPAddress = pNetIf->ip_addr;
m_pUDPContext->setMulticastInterface(fromIPAddress);
#ifdef MDNS_IP4_SUPPORT
IPAddress toMulticastAddress(DNS_MQUERY_IPV4_GROUP_INIT);
#endif
#ifdef MDNS_IP6_SUPPORT
//TODO: set multicast address
IPAddress toMulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT);
#endif
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: Will send to '%s'.\n"), toMulticastAddress.toString().c_str()););
bResult = ((_prepareMDNSMessage(p_rSendParameter, fromIPAddress)) &&
(m_pUDPContext->sendTimeout(toMulticastAddress, DNS_MQUERY_PORT, MDNS_UDPCONTEXT_TIMEOUT)));
DEBUG_EX_ERR(if (!bResult)
{
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: FAILED!\n"));
});
}
}

Adding -DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_MDNS_RESPONDER and the small patch, udpcontext is finally able to send out the data for the AP:

[MDNSResponder] _writeMDNSAnswer_A ((IP unset))
[MDNSResponder] _sendMDNSMessage_Multicast: FAILED!
[MDNSResponder] _sendMDNSMessage: FAILED!
[MDNSResponder] _updateProbeStatus: FAILED!
...
never sends the data
...
@@ -128,6 +128,10 @@ bool MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParamet
             IPAddress   fromIPAddress;
             //fromIPAddress = _getResponseMulticastInterface();
             fromIPAddress = pNetIf->ip_addr;
+            if (!fromIPAddress.isSet()) {
+                continue;
+            }
+
             m_pUDPContext->setMulticastInterface(fromIPAddress);
[MDNSResponder] _writeMDNSAnswer_A (192.168.4.1)
[MDNSResponder] _updateProbeStatus: Announcing service TestMDNS.http.tcp (1)
...
data can be seen with the network inspector / bonjour http app
...

(obviously, diff is not a fix! just exploring the code)

@d-a-v
Copy link
Collaborator

d-a-v commented Oct 4, 2021

@hreintke and/or me updated this part of this code (to make it interface-agnostic).
Usually when netif_is_up() is true, the interface has a valid address and IPAddress::isSet() should be true.
However if this test solves the issue (that I could not reproduce) then such patch is welcome.

@hreintke What do you think ?

@hreintke
Copy link
Contributor

hreintke commented Oct 5, 2021

@mcspr @d-a-v
Can't reproduce either.

But, logs do show that it finds the AP netif, and attempts to send the data

Can you provide your logs so I can (perhaps) check what is happening.

and the small patch, udpcontext is finally able to send out the data for the AP:

Do you say here :

  • The esp is connected to both AP & STA.
  • The STA interface has !fromIPAddress.isSet()
  • There is no sending of mdns traffic on the AP interface ?

@d-a-v d-a-v added the waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. label Oct 5, 2021
@mcspr
Copy link
Collaborator

mcspr commented Oct 5, 2021

@mcspr @d-a-v Can't reproduce either.

But, logs do show that it finds the AP netif, and attempts to send the data

Can you provide your logs so I can (perhaps) check what is happening.

and the small patch, udpcontext is finally able to send out the data for the AP:

Do you say here :

  • The esp is connected to both AP & STA.
  • The STA interface has !fromIPAddress.isSet()
  • There is no sending of mdns traffic on the AP interface ?

Adding UDP debug logs as well, there's an endless stream of -4 (ERR_RTE) from the underlying udp sender
(softAP network is the default 192.168.4.0/24, transfer.cpp logs modified to point to the currently used netif & ips)

[MDNSResponder] _sendHostProbe (TestMDNS, 16111)
[MDNSResponder] _sendMDNSMessage_Multicast: Will send '192.168.4.1' -> '224.0.0.251' (netif ap timeout 50 port 5353).
[MDNSResponder] _prepareMDNSMessage
[MDNSResponder] _prepareMDNSMessage: ID:0 QR:0 OP:0 AA:0 TC:0 RD:0 RA:0 R:0 QD:1 AN:0 NS:1 AR:0
[MDNSResponder] _writeMDNSQuestion
[MDNSResponder] _writeMDNSAnswer_A (192.168.4.1)
[MDNSResponder] _sendMDNSMessage_Multicast: Will send '(IP unset)' -> '224.0.0.251' (netif st timeout 50 port 5353).
[MDNSResponder] _prepareMDNSMessage
[MDNSResponder] _prepareMDNSMessage: ID:0 QR:0 OP:0 AA:0 TC:0 RD:0 RA:0 R:0 QD:1 AN:0 NS:1 AR:0
[MDNSResponder] _writeMDNSQuestion
[MDNSResponder] _writeMDNSAnswer_A ((IP unset))
:ust rc=-4
:ust rc=-4
:ust rc=-4


:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
[MDNSResponder] _sendMDNSMessage_Multicast: FAILED! (netif st from '(IP unset)' to '224.0.0.251'
[MDNSResponder] _sendMDNSMessage: FAILED!
[MDNSResponder] _updateProbeStatus: FAILED!

... repeat ad infinitum ...

Modifying the example above and adding a WiFi.begin to connect to something, it does work after STA interface receives IP (10.0.0.0/24 in the logs):

connected with TESTTESTTEST, channel 1
dhcp client start...
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
:ust rc=-4
[MDNSResponder] _sendMDNSMessage_Multicast: FAILED! (netif st from '(IP unset)' to '224.0.0.251'
[MDNSResponder] _sendMDNSMessage: FAILED!
[MDNSResponder] _updateProbeStatus: FAILED!

ip:10.0.0.130,mask:255.255.255.0,gw:10.0.0.1
.[MDNSResponder] _sendHostProbe (TestMDNS, 4865)
[MDNSResponder] _sendMDNSMessage_Multicast: Will send '192.168.4.1' -> '224.0.0.251' (netif ap timeout 50 port 5353).
[MDNSResponder] _prepareMDNSMessage
[MDNSResponder] _prepareMDNSMessage: ID:0 QR:0 OP:0 AA:0 TC:0 RD:0 RA:0 R:0 QD:1 AN:0 NS:1 AR:0
[MDNSResponder] _writeMDNSQuestion
[MDNSResponder] _writeMDNSAnswer_A (192.168.4.1)
[MDNSResponder] _sendMDNSMessage_Multicast: Will send '10.0.0.130' -> '224.0.0.251' (netif st timeout 50 port 5353).
[MDNSResponder] _prepareMDNSMessage
[MDNSResponder] _prepareMDNSMessage: ID:0 QR:0 OP:0 AA:0 TC:0 RD:0 RA:0 R:0 QD:1 AN:0 NS:1 AR:0
[MDNSResponder] _writeMDNSQuestion
[MDNSResponder] _writeMDNSAnswer_A (10.0.0.130)
[MDNSResponder] _updateProbeStatus: Did sent host probe

[MDNSResponder] _sendServiceProbe (TestMDNS.http.tcp, 4931)
[MDNSResponder] _sendMDNSMessage_Multicast: Will send '192.168.4.1' -> '224.0.0.251' (netif ap timeout 50 port 5353).
[MDNSResponder] _prepareMDNSMessage
[MDNSResponder] _prepareMDNSMessage: ID:0 QR:0 OP:0 AA:0 TC:0 RD:0 RA:0 R:0 QD:1 AN:0 NS:2 AR:2
[MDNSResponder] _writeMDNSQuestion
[MDNSResponder] _writeMDNSAnswer_PTR_NAME
[MDNSResponder] _writeMDNSAnswer_SRV
[MDNSResponder] _writeMDNSAnswer_TXT
[MDNSResponder] _writeMDNSAnswer_A (192.168.4.1)
[MDNSResponder] _sendMDNSMessage_Multicast: Will send '10.0.0.130' -> '224.0.0.251' (netif st timeout 50 port 5353).
[MDNSResponder] _prepareMDNSMessage
[MDNSResponder] _prepareMDNSMessage: ID:0 QR:0 OP:0 AA:0 TC:0 RD:0 RA:0 R:0 QD:1 AN:0 NS:2 AR:2
[MDNSResponder] _writeMDNSQuestion
[MDNSResponder] _writeMDNSAnswer_PTR_NAME
[MDNSResponder] _writeMDNSAnswer_SRV
[MDNSResponder] _writeMDNSAnswer_TXT
[MDNSResponder] _writeMDNSAnswer_A (10.0.0.130)
[MDNSResponder] _updateProbeStatus: Did sent service probe (1)

@d-a-v
Copy link
Collaborator

d-a-v commented Oct 5, 2021

_sendMDNSMessage_Multicast: Will send '(IP unset)' -> '224.0.0.251' (netif st timeout 50 port 5353).
...
:ust rc=-4

udp_sendto() == -4 is lwIP's ERR_RTE / Routing Problem

All this seems consistent (cannot route from invalid address), except that the source address should not be unset when the interface is up. We are speaking of the STA interface (netif st). Maybe AP doesn't work because of a side effect of the following m_pUDPContext->setMulticastInterface(fromIPAddress); where fromIPAddress is unset.

The reason why the flag NETIF_FLAG_UP is up for the STA interface has yet to be understood, but your patch @mcspr seems to be OK to work the issue around for wherever it is coming from.

@mcspr
Copy link
Collaborator

mcspr commented Oct 5, 2021

There is no sending of mdns traffic on the AP interface ?

Only queries going on

6643	1147.360615	192.168.4.1	224.0.0.251	MDNS	104	Standard query 0x0000 ANY TestMDNS.local, "QU" question A 192.168.4.1
... repeating ...

Unless the loop is blocked via isSet() check or STA is connected so the bResult finally returns true, it never gets to these A record and the http service responses.

2071	148.562197	192.168.4.1	224.0.0.251	MDNS	122	Standard query response 0x0000 A, cache flush 192.168.4.1 PTR, cache flush TestMDNS.local
2076	148.864304	192.168.4.1	224.0.0.251	MDNS	238	Standard query response 0x0000 PTR _http._tcp.local PTR TestMDNS._http._tcp.local SRV, cache flush 0 0 80 TestMDNS.local TXT, cache flush A, cache flush 192.168.4.1

The reason why the flag NETIF_FLAG_UP is up for the STA interface has yet to be understood, but your patch @mcspr seems to be OK to work the issue around for wherever it is coming from.

We do change opmode though, so we do expect both up and link-up? The gist of the issue seems to be with the initial probe result never succeeding from the mdns lib pov, so it never wants to do anything else until it does. And it does seem reasonable to help it out and filter the invalid netif instead of failing everything, will update with a PR

@d-a-v
Copy link
Collaborator

d-a-v commented Oct 5, 2021

We do change opmode though, so we do expect both up and link-up?

There are two interface "up" flags: LINK_UP and UP.
Per doc, the answer to the question raised there which is how an interface can be in the state "LINK_UP" while not "UP" is that it can happen after a dhcp request and before the answer to it. The interface becomes "UP" when the IP address is assigned.

LINK_UP should happen when there is power and the interface is enabled (WiFi) and/or a "cable" is wired.

So it is strange that the IP address above is unset. Reproducing this bug should allow to dig into lwip2's code and track this bug down (having in mind that lwip2 logic is quite sensitive for general stability).
It is anyway good to add your workaround @mcspr.

@hreintke
Copy link
Contributor

hreintke commented Oct 6, 2021

@d-a-v
I agree with you on the workaround. I will submit a PR (today or tomorrow) where I also include some debug print so we still can see it happen when debugging.

The gist of the issue seems to be with the initial probe result never succeeding from the mdns lib pov, so it never wants to do anything else until it does.

I'll check this. Not sending a request should trigger a timeout and keep mdns working.

@hreintke
Copy link
Contributor

hreintke commented Oct 8, 2021

@d-a-v Have some trouble with my dev environment. PR will come what later.

@lolwheel
Copy link

lolwheel commented Mar 2, 2022

I have bumped into this exact issue. The clients cannot associate with the SoftAP interface as long as ESP8266 isn't connected to an access point.

The issue isn't there when the ESP8266 connects to an access point. In that case the SoftAP works as intended.

@hreintke
Copy link
Contributor

Submitted a PR to solve the infinite sending of host probes.

To be decided/handled :
When STA is connected after MDNS,begin() there is no trigger from LwipIntf::stateUpCB -> No probing/announcing started.

@mcspr
Copy link
Collaborator

mcspr commented Aug 22, 2022

Also noticed in https://savannah.nongnu.org/bugs/?37068 and the associated https://git.savannah.nongnu.org/cgit/lwip.git/commit/?id=4e520cdd3009cf2e04c50c173737b379ff7d72a2, it seems UP is totally ok state to be in during DHCP initialization.

State callback needs to happen on IP change instead, not the interface status? If I understood correctly, only way to have a cb is to use EXT callbacks and wait up for LWIP_NSC_IPV4_ADDRESS_CHANGED
(notably, git-greping the source, lwip mdns impl does exactly that:). otherwise, it is simply checking for not-ipv4-any as was suggested earlier)

@mcspr mcspr linked a pull request Dec 14, 2022 that will close this issue
@mcspr mcspr closed this as completed Dec 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: MDNS type: bug waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants