mdns

package
v0.0.0-...-b43479a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package mdns resolves .local hostnames over multicast DNS.

This exists because Go programs cannot rely on the operating system to do it. RFC 6762 §3 reserves .local for multicast DNS, so ordinary unicast DNS servers are expected to refuse those names -- which is exactly what a user hitting this sees: systemd-resolved answering SERVFAIL, surfaced by Go as "server misbehaving".

On Linux the lookup normally succeeds inside NSS, via Avahi's mdns4_minimal module. Go's pure-Go resolver does not consult NSS modules at all: it reads /etc/hosts and queries the nameservers in resolv.conf (see the net package's "Name Resolution" documentation). So `ping jupiter.local` succeeds while the identical lookup inside a Go program fails on a correctly working machine, and a box with no Avahi NSS module (hosts: files dns) cannot resolve it at all.

Eta is a LAN filesystem browser and .local is how LAN machines are named, so it queries multicast itself rather than depending on every user's resolver being configured for it.

The multicast protocol is github.com/pion/mdns/v2, the resolver pion/webrtc uses for ICE .local candidates -- not hand-rolled here. What this package adds is only what is specific to Eta: deciding which names are multicast names, caching answers across a browse session, and a dialer that applies it to peer traffic.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DialContext

func DialContext(ctx context.Context, network, address string) (net.Conn, error)

DialContext dials like a normal dialer, except that a .local name is resolved by multicast first.

This is deliberately the dial path rather than the probe: adding a PC is one request, and browsing it is thousands. Fixing only the probe would let a peer be added and then fail on every file listing, which is a worse outcome than refusing it up front.

The system resolver is still tried if multicast finds nothing, so a machine that does have working .local resolution (macOS, or Linux with Avahi wired into NSS) keeps whatever it already had. Multicast goes first because it is the mechanism the name is defined by, and because the system path is the one already known to fail slowly with SERVFAIL.

func Forget

func Forget(host string)

Forget drops any cached answer for a name, so a PC that changed address is re-resolved rather than failing until the entry expires.

func IsLocal

func IsLocal(host string) bool

IsLocal reports whether a hostname is in the mDNS .local domain, and so must be resolved by multicast rather than unicast DNS.

func Lookup

func Lookup(ctx context.Context, host string) (netip.Addr, error)

Lookup resolves a .local name to an address, preferring a cached answer. Browsing one peer is thousands of requests, and re-querying the entire link for each of them would be both slow and antisocial.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL