LLMNR & FreeRTOS_gethostbyname()

jeronimo479 wrote on Thursday, September 13, 2018:

I’m moving really slowly on this, but my goal is to have 16 embedded systems on closed 10-base-2 Ethernet. I want each node to use a hostname to discover and communicate with the others. I don’t have, or want to have a DHCP server or DNS. I thought about using netbui (WINS), but Hein suggested LLMNR would be better.

So here is my question…

According to FreeRTOS_gethostbyname() API Reference https://is.gd/YqTbaD,
I need to have DNS enabled before FreeRTOS_gethostbyname() will work.

I thoght LLMNR could be used in a system where there is no DNS. Each node would just use multicast to discover the IP of the node responding to ‘hostname’.

Do i need to have DNS and DHCP if i just want to use LLMNR to discover other local nodes?

Wayne

heinbali01 wrote on Friday, September 14, 2018:

Hi Wayne, the three protocols DNS, NBNS and LLMNR have a lot in common, so we found it more practical to put them together in a single module “FreeRTOS_DNS.c”. A better name would have been e.g. “FreeRTOS_name_services.c” or ““FreeRTOS_NS.c””.

The DHCP protocol has it own source module and has little to do with the name services.

There is something that you probably haven’t thought of yet:

    FreeRTOS_gethostbyname( "freertos.org" ); // This call will use DNS
    FreeRTOS_gethostbyname( "my_device" );    // Use LLMNR, if enabled

URL’s on the Internet have at least one dot.

The second call will use LLMNR and it will find embedded devices called “my_device”.

As you probably have seen, you can give each device multiple names. For instance, a printing device can respond to both “printer” as well as “printer_3”:

BaseType_t xApplicationDNSQueryHook( const char *pcName )
{
BaseType_t xReturn;

    /* Determine if a name lookup is for this node.  Two names are given
    to this node: "printer" and "printer_03" */
    if( strcasecmp( pcName, "printer" ) == 0 )
    {
        xReturn = pdPASS;
    }
    else if( strcasecmp( pcName, "printer_03" ) == 0 )
    {
        xReturn = pdPASS;
    }
    else
    {
        xReturn = pdFAIL;
    }

    return xReturn;
}

Note that there is also a non-blocking FreeRTOS_gethostbyname_a() which works with a call-back function.

jeronimo479 wrote on Friday, September 14, 2018:

When I read through the LLMNR specification, it said that the Domain Name Server would be checked multiple times for an IP address, and if that didn’t work and the hostname contained no dots, then LLMNR would be used to send out a multicast request to the LAN.

I got it working last night and I was able to see how it works. Each node has it’s own table of names and IP addresses. What I didn’t see was the interaction between the ARP table and the local DNS table.

If a node with hostname NODEA has already requested hostname NODEB (#1) and retreived an IP, what happens when NODEB (#1) is removed from the LAN, and a different node, using hostname NODEB (#2) , is attached that uses a different MAC & IP?

I assume eventually the arp table entry will be removed, but will FreeRTOS_gethostbyname() continue to return IP from NODEB (#1) or will it go out and query the LAN?

Think of it this way, we have a logger with an SD card and we are going to give it hostname LOGGER. We have a flashlight and are going to give it hostname LAMP. I always want whatever LAMP module is connected to the LAN to send messages to LOGGER for logging. If I remove that lamp node and install a new one, I want the rest of the system to heal and continue working. Likewise, if I remove the LOGGER node and replace it with bright and shinny new LOGGER, I want logging events now sent to the new LOGGER, not the old one that isn’t there anymore.

Will removal from the ARP table also remove local DNS entry causing the next call to FreeRTOS_getnamebyhost() to perform an actual network query instead of returning the old, stale IP?

heinbali01 wrote on Friday, September 14, 2018:

When I read through the LLMNR specification, it said that the Dynamic Name Server

Typo : DNS stands for Domain ( not Dynamic ) Name Server

would be checked multiple times for an IP address, and if that didn’t work and the
hostname contained no dots, then LLMNR would be used to send out a multicast request
to the LAN.

I haven’t seen that text.
But try to surf to “http://my_host/index.html” on a browser while running Wireshark: immediately you will see an LLMNR request looking for “my_host”. There will be a local MDNS request for “my_host.local”, but no real DNS request going the Internet.

What I didn’t see was the interaction between the ARP table and the local DNS table.

Aren’t ARP and a DNS table totally different and independent things?

If a node with hostname NODEA has already requested hostname NODEB (#1) and
retreived an IP, what happens when NODEB (#1) is removed from the LAN, and a different
node, using hostname NODEB (#2) , is attached that uses a different MAC & IP?

That can happen, and when using IPv4, this is an ARP problem: a device thinks that “NODE_B” has MAC-address xxx, but in fact it has a new address.

What you could do is invalidate the ARP entry by calling:

    uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress );

Use eARPGetCacheEntry() to find the current stored MAC-address,

I assume eventually the arp table entry will be removed,

Sure it will: any ARP entry will time-out when it does not get reconfirmed once in a while.

One good thing with FreeRTOS+TCP devices: each device will send-out regularly a so-called gratuitous ARP requests: the packets will be send automatically every 20 seconds ( see arpGRATUITOUS_ARP_PERIOD ). So after 20 seconds, all devices will hear about the new MAC address.

but will FreeRTOS_gethostbyname() continue to return IP from NODEB (#1) or will it go out and query the LAN?

That depends on ipconfigUSE_DNS_CACHE: if defined as non-zero, entries will be stored in a “DNS” cache.

… if I remove the LOGGER node and replace it with bright and shiny new LOGGER,
I want logging events now sent to the new LOGGER, not the old one that isn’t there any more.

Faire enough.
As soon as you detect that the current LOGGER or LAMP stops responding, you can clear the ARP entry. The next thing to do is look-up regularly if there is a new device that is called LOGGER or LAMP.

Will removal from the ARP table also remove local DNS entry causing the next call
to FreeRTOS_getnamebyhost() to perform an actual network query instead of returning the old, stale IP?

If you have defined ipconfigUSE_DNS_CACHE, you can remove ( clear ) a cache entry by calling:

    uint32_t FreeRTOS_dnspurge( const char *pcHostName );

jeronimo479 wrote on Wednesday, September 19, 2018:

Thanks Hein. Very good suggesetions.