Skip to content

feature: Support use of FQDN resolution with DNS and mDNS - #1760

Draft
invario wants to merge 1 commit into
seriousm4x:masterfrom
invario:support-fqdn-mdns
Draft

feature: Support use of FQDN resolution with DNS and mDNS#1760
invario wants to merge 1 commit into
seriousm4x:masterfrom
invario:support-fqdn-mdns

Conversation

@invario

@invario invario commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Resolves: #1753
Submitting as a DRAFT since it is still being worked on:

  • Replaces the IP field in the Device Form with IP/FQDN. Updated the regex to validate as FQDN or valid IP address. Max. input length 255 characters.
image
  • Added ResolveToIPAddr function that takes one string parameter - either FQDN or IP.
    • On Linux/FreeBSD mDNS lookup is implemented with dbus and go-avahi and if it times out, a call to the net.DefaultResolver is made.
    • On Windows/Darwin, a simple call to net.DefaultResolver will perform both a DNS and mNDS lookup.
    • In both cases, if the function is called with an actual IP, it simply returns the IP address.
  • Wrapped all references to device IP to use ResolveToIPAddr and added valid actions if the IP string is ""
  • wakeUDP no longer sends 6 packets for WOL.
    • This is because if a host is powered down, its .local name cannot be resolved via mDNS, and as a result there is no IP address. Without an IP address of the device, we cannot send a unicast (routed) packet, and we also cannot determine the broadcast address. Broadcasting to 255.255.255.255 does not work (reliably) because the OS will send the packet to either the default network interface, or the one with the lowest metric (behavior varies depending on the OS.)
    • As a result, when a device is powered down and the user has configured a .local device, wakeUDP will send (2) WOL packets (ports 7 and 9) to every interface (except loopback, non-broadcast capable, and inactive/down).
    • Refactored some of the existing code
    • Existing users that have IP addresses for their devices and proper netmasks should not have to change a thing

To Do/Need Feedback:

  • I'm strongly considering adding an optional field on the Device Form for Interface that would allow specifying the local/host interface for broadcasting the WOL packet.
  • mDNS lookups currently timeout after 5 seconds. That is less than the default of 3 seconds for UpSnap between pings. I need to resolve this in one of two ways
    • Reduce the timeout to 2 or 3 seconds. On most networks/setup, this shouldn't be a problem. If a device is up, it should respond within milliseconds. I am currently favoring this option
    • Increase the UpSnap ping cron.
  • Update documentation
  • Need testing and input!

Signed-off-by: invario <67800603+invario@users.noreply.github.com>
@invario
invario force-pushed the support-fqdn-mdns branch from 16c499c to b676386 Compare July 25, 2026 21:23
@invario

invario commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

Need to add:

  • If it is unable to connect to dbus/avahi when it encounters a .local FQDN, it should log a warning error and continue on to try to resolve it using a DNS server. Currently, it just errors out if dbus/avahi is not accessible. RFC 6762 says .local should be delegated to mDNS only and should not be passed onto a unicast DNS server. Google says that there may be some edge legacy cases of enterprise Windows networks that resolve .local via unicast DNS. I'm going to leave the logic in place: fail if a .local FQDN is provided and dbus/avahi are not useable.
  • sleep.go needs to have GetString("ip") wrapped Actually, this looks like it was already done, my mistake.

@seriousm4x

seriousm4x commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Thanks a lot for this pr. I really appreciate all the work you have done in the last days/weeks!


Some general issues i found accross this pr is the formatting for go files. All indentation is done with 2 spaces. You can use go's build in formattor called gofmt like so:

cd backend/
go fmt ./...

Which will format all files automatically. Depending on your editor you can enable format on save which will most likely already use gofmt. Before doing other changes to this pr, please make a commit to clean up the formatting.

Also using gopls in your editor gives you some warnings about code that will work but has minor issues.


I've left comments on all the parts where I'd make changes. I have not yet tested the implementation (just quickly changed the IP from my pi to pi.local which worked on my mac). Better testing the code across platforms still needs to be done.

Regarding the feedback you requested:

I'm strongly considering adding an optional field on the Device Form for Interface that would allow specifying the local/host interface for broadcasting the WOL packet.

How do we handle changes in interfaces? When we store nics in the database and those nics become unavailable (new host or other network card) it will cause issues.

mDNS lookups currently timeout after 5 seconds. That is less than the default of 3 seconds for UpSnap between pings. I need to resolve this in one of two ways

I've tested this a couple days back and resolution failed on timeouts below 100ms on my local network. I think setting it to 1-2 seconds should be plenty.

Again, thank you for your work :)

Comment thread backend/cronjobs/cronjobs.go
Comment thread backend/networking/magicpacket.go
Comment thread backend/networking/magicpacket.go
Comment thread backend/networking/magicpacket.go
Comment thread backend/networking/magicpacket.go
Comment thread backend/networking/mdnsresolve.go
Comment thread backend/networking/resolve.go
Comment thread backend/networking/resolve.go
Comment thread backend/networking/wake.go
placeholder={m.device_general_netmask()}
class="input"
maxlength="16"
pattern={netmaskPattern}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will create a merge conflict with my new commits from issue #1761.

Make sure to pull in the latest commits and keep your changes.

@invario invario Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rebased and resolved the conflicts, but now I need to replace my migration file. But I'm going to work on the regexp for international domains first.

@invario

invario commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

I will take care of all the formatting and try gopls, thank you! It will take me a few days to go over it all but once I do, I'll reply and/or make the changes. Agreed on needing better testing on the other platforms. I have a MacOS VM and FreeBSD VM fired up inside my Windows PC and a separate Linux and LInux+Docker setup to test each new compile but I'm just one person testing lol.

How do we handle changes in interfaces? When we store nics in the database and those nics become unavailable (new host or other network card) it will cause issues.

We can identify the interface by the IP assigned to the host/server itself, so the optional input field on the form would take an IP. mdlayher/wol doesn't' allow specifying an interface, however, so this field would only be used in the case of a .local FQDN when the machine is powered down and the .local cannot resolve.

Or we can just leave it at broadcasting on all interfaces, but the OCD in me doesn't like the idea of sending so many packets out at once unnecessarily. BUT from what I can tell from Googling, there is 0 harm in keeping it this way. Packets are very small, and the occurrences of this (when a WOL is triggered) is rare.

I've tested this a couple days back and resolution failed on timeouts below 100ms on my local network. I think setting it to 1-2 seconds should be plenty.

Great! I'll set the context timeout to 2 then.

Again, thank you for your work :)

❤️

@invario

invario commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Need to add:

  • If it is unable to connect to dbus/avahi when it encounters a .local FQDN, it should log a warning error and continue on to try to resolve it using a DNS server. Currently, it just errors out if dbus/avahi is not accessible.

RFC 6762 says .local should be delegated to mDNS only and should not be passed onto a unicast DNS server. Google says that there may be some edge legacy cases of enterprise Windows networks that resolve .local via unicast DNS. I'm going to leave the logic in place: fail if a .local FQDN is provided and dbus/avahi are not useable.

@invario

invario commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

@seriousm4x Earlier in the other thread we spoke about mDNS queries flooding the network but I realized I made an oversight in my calculations. With 13 devices that are powered on, responses are going to be cached for the TTL (80% of 120 secs) which mitigates the spam factor a bit.

However, if all the devices are powered off, there is nothing to cache and UpSnap will send out 260 mDNS queries per minute, which is a pretty high number. Any ideas on how to better handle when devices are off?

Comment thread backend/migrations/1784845816_updated_devices.go
@seriousm4x

Copy link
Copy Markdown
Owner

However, if all the devices are powered off, there is nothing to cache and UpSnap will send out 260 mDNS queries per minute, which is a pretty high number. Any ideas on how to better handle when devices are off?

We could save the last known ip address and ping that. When a device is offline, we could only do an mdns request every x ping. Ip leases don't change that often so it's quite likely that once the device comes back up it will get the same ip. So only quering mdns every x ping would reduce the amount of queries.

@invario

invario commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

However, if all the devices are powered off, there is nothing to cache and UpSnap will send out 260 mDNS queries per minute, which is a pretty high number. Any ideas on how to better handle when devices are off?

We could save the last known ip address and ping that. When a device is offline, we could only do an mdns request every x ping. Ip leases don't change that often so it's quite likely that once the device comes back up it will get the same ip. So only quering mdns every x ping would reduce the amount of queries.

In my experience, that varies a lot, depending on the network configuration and how many devices are joining/leaving the network. The longer the device is powered off, the greater the likelihood its IP will be handed out by the DHCP server to some other random device that needs an IP. In a busy network, it can happen very quickly. Example: I manage a family member's network in his coffee shop, and that is high traffic, high turnover for DHCP, so IPs get reassigned very, very quickly.

But even if I were to save the previous IP and continue using that when it goes offline, if/when the IP were to get reassigned to another device, then we're just stuck in the same boat again with flooding queries trying to get the new IP.

I'm going to keep thinking about a way to fix this. I've made the other changes discussed above, but am going to hold off on pushing the update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drop IP requirement and add dns hostnames

3 participants