cbrand / micropython-mdns

MDNS implementation for MicroPython with Service Discovery
MIT License
53 stars 12 forks source link

DNS Advertise won't work on pico rp2040. #24

Closed TechUpdateGuy closed 2 months ago

TechUpdateGuy commented 2 months ago

I have the following code

async def setup_mdns():

    responder = Responder(
                            client,
                            own_ip=lambda: local_ip,
                            host=lambda: "W5500_EVB_PICO-{}".format(0),
                            debug = True
                         )

    responder.advertise(
                        "_RANDOM"
                        , "_tcp"
                        , port=5353
                        #, data={"some": "metadata", "for": ["my", "service"]}
                        )

    while True:
        await asyncio.sleep(1)  # Sleep and keep running indefinitely

As the title suggest, I am running this code on W5500-EVB-PICO micropython v.1.24.0-preview with LWIP_MDNS_RESPONDER 0 flag turned off. Nevertheless, what I noticed is that I can only use mdns hostname when I run 'mdns-scan" linux utility in background which request PTR records from all device constantly. If I don't run mdns-scan, then it won't show up. Upon testing multiple non-trivial solutions (mostly because I don't yet properly understood how to use library). I found using the line client.send_question(DNSQuestion('W5500_EVB_PICO-0.local', TYPE_PTR_ CLASS_IN)) to resolve the issue. But this is crude solution because it requires you to know the hostname or set it to constant. If I try to use generate_random_postfix() to randomly generate an id then I can't use the .send_question() method since every so often, the inner library seem rename hostname as it calls this function for some procedure. Even using ServiceDiscovery to query local mdns didn't work for me. it listed every device except the one I am hosting. I suspect I was using the same client object to drive both. But regardless, let me know if you have any thoughts on the issue.

EDIT: I just want to note, turns out the line client.send_question(DNSQuestion('W5500_EVB_PICO-0.local', TYPE_PTR_ CLASS_IN)) doesn't work. I assume I reached the earlier conclusion because of DNS record in cache and resolving the mdns from there, Sorry about misleading earlier.

PS. you could also use ping to hostname as an alternative to mdns-scan. In addition, I don't know how make the above line wrap for better readability. I tried editing it but I don't get it. If its not readable I apologize.

TechUpdateGuy commented 2 months ago

Got the solution.

Turns out the In responder.py file, the response for "A" type query matches the domain but doesn't account for lower case strings. As such it fails to lookup domain name set with upper case string/letters.

I changed the code for the line if question.query != self.host_fqdn: to the following line below. just added .lower() to account for lower case strings which some computer automatically converts.

def _on_a_question(self, question: DNSQuestion) -> None:

     if question.query.lower() != self.host_fqdn.lower():
            return