mdns

package module
v2.2.2 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 17 Imported by: 16

README


Pion mDNS

A Go implementation of mDNS

Pion mDNS join us on Discord Follow us on Bluesky
GitHub Workflow Status Go Reference Coverage Status Go Report Card


Go mDNS implementation. The original user is Pion WebRTC, but we would love to see it work for everyone.

Running Server

For a mDNS server that responds to queries for pion-test.local

go run examples/server/main.go

For a mDNS server that responds to queries for pion-test.local with a given address

go run examples/server/publish_ip/main.go -ip=[IP]

If you don't set the ip parameter, "1.2.3.4" will be used instead.

Running Client

To query using Pion you can run the query example

go run examples/query/main.go

You can use the macOS client

dns-sd -q pion-test.local

Or the avahi client

avahi-resolve -a pion-test.local

RFCs

Implemented

Roadmap

The library is used as a part of our WebRTC implementation. Please refer to that roadmap to track our major milestones.

Community

Pion has an active community on the Discord.

Follow the Pion Bluesky or Pion Twitter for project updates and important WebRTC news.

We are always looking to support your projects. Please reach out if you have something to build! If you need commercial support or don't want to use public methods you can contact us at team@pion.ly

Contributing

Check out the contributing wiki to join the group of amazing people making this project possible

License

MIT License - see LICENSE for full text

Documentation

Overview

Package mdns implements mDNS (multicast DNS)

Index

Constants

View Source
const (
	// DefaultAddressIPv4 is the default used by mDNS
	// and in most cases should be the address that the
	// ipv4.PacketConn passed to Server or NewServer is bound to.
	DefaultAddressIPv4 = "224.0.0.0:5353"

	// DefaultAddressIPv6 is the default IPv6 address used
	// by mDNS and in most cases should be the address that
	// the ipv6.PacketConn passed to Server or NewServer is bound to.
	DefaultAddressIPv6 = "[FF02::]:5353"
)

Variables

This section is empty.

Functions

func WithCacheRefresh added in v2.2.0

func WithCacheRefresh(enable bool) cacheRefreshOption

WithCacheRefresh enables or disables proactive cache refresh per RFC 6762 §5.2. When enabled, actively-monitored records are re-queried at 80/85/90/95% of their TTL. Enabled by default in NewServer; disabled in the legacy Server constructor.

func WithIncludeLoopback added in v2.2.0

func WithIncludeLoopback(include bool) includeLoopbackOption

WithIncludeLoopback sets whether loopback interfaces should be included.

func WithInterfaces added in v2.2.0

func WithInterfaces(ifaces ...net.Interface) interfacesOption

WithInterfaces sets the network interfaces to use. If not set, all suitable interfaces will be discovered automatically.

func WithLocalAddress added in v2.2.0

func WithLocalAddress(addr net.IP) localAddressOption

WithLocalAddress sets the IP address to publish in responses. If not set, the address will be automatically determined from the interface.

func WithLocalNames added in v2.2.0

func WithLocalNames(names ...string) localNamesOption

WithLocalNames sets the names that the server will respond to. These are the mDNS names that this server will generate answers for.

func WithLoggerFactory added in v2.2.0

func WithLoggerFactory(factory logging.LoggerFactory) loggerFactoryOption

WithLoggerFactory sets the logger factory for creating loggers.

func WithName added in v2.2.0

func WithName(name string) nameOption

WithName sets the name used for logging purposes.

func WithQueryInterval added in v2.2.1

func WithQueryInterval(interval time.Duration) queryIntervalOption

WithQueryInterval sets how often the client checks for records due for query. Default is 1 second. Must be greater than zero.

func WithRecordTypes added in v2.2.0

func WithRecordTypes(types ...dnsmessage.Type) recordTypesOption

WithRecordTypes limits which DNS record types the server will process. By default (if not called), all record types are allowed - no filtering.

For WebRTC/ICE usage (legacy behavior), restrict to address records:

mdns.WithRecordTypes(dnsmessage.TypeA, dnsmessage.TypeAAAA)

func WithRefreshInterval added in v2.2.0

func WithRefreshInterval(interval time.Duration) refreshIntervalOption

WithRefreshInterval sets how often the cache refresh loop checks for records due for refresh. Default is 2 seconds. Must be greater than zero. Only effective when cache refresh is enabled.

func WithResponseTTL added in v2.2.0

func WithResponseTTL(seconds uint32) responseTTLOption

WithResponseTTL sets the TTL (in seconds) for DNS response records. Default is 120 seconds per RFC 6762 recommendation.

func WithService added in v2.2.0

func WithService(svc ServiceInstance) serviceOption

WithService registers a DNS-SD service instance to be advertised. May be called multiple times to register multiple services.

The Domain defaults to "local" if unset.

Example:

mdns.NewServer(v4, v6,
    mdns.WithLocalNames("myhost.local"),
    mdns.WithService(mdns.ServiceInstance{
        Instance: "My Web Server",
        Service:  "_http._tcp",
        Port:     8080,
    }),
)

Types

type ClientOption added in v2.2.0

type ClientOption interface {
	// contains filtered or unexported methods
}

ClientOption configures a Client.

type Config

type Config struct {
	// Name is the name of the client/server used for logging purposes.
	Name string

	// QueryInterval controls how often we sends Queries until we
	// get a response for the requested name.
	QueryInterval time.Duration

	// LocalNames are the names that we will generate answers for
	// when we get questions.
	LocalNames []string

	// LocalAddress will override the published address with the given IP
	// when set. Otherwise, the automatically determined address will be used.
	LocalAddress net.IP

	// LoggerFactory is used to create a logger for the server.
	LoggerFactory logging.LoggerFactory

	// IncludeLoopback will include loopback interfaces to be eligible for queries and answers.
	IncludeLoopback bool

	// Interfaces will override the interfaces used for queries and answers.
	Interfaces []net.Interface
}

Config is used to configure a mDNS client or server.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn represents a mDNS Server.

func NewServer added in v2.2.0

func NewServer(
	multicastPktConnV4 *ipv4.PacketConn,
	multicastPktConnV6 *ipv6.PacketConn,
	opts ...ServerOption,
) (*Conn, error)

NewServer creates a new mDNS server with the given options.

At least one of the multicast packet connections must be non-nil. The presence of each IP type of PacketConn will dictate what kinds of questions are sent for queries. That is, if an ipv6.PacketConn is provided, then AAAA questions will be sent. A questions will only be sent if an ipv4.PacketConn is also provided.

Example:

// Create multicast listeners
addr4, _ := net.ResolveUDPAddr("udp4", mdns.DefaultAddressIPv4)
l4, _ := net.ListenUDP("udp4", addr4)

addr6, _ := net.ResolveUDPAddr("udp6", mdns.DefaultAddressIPv6)
l6, _ := net.ListenUDP("udp6", addr6)

// Create server with options
server, err := mdns.NewServer(
    ipv4.NewPacketConn(l4),
    ipv6.NewPacketConn(l6),
    mdns.WithLocalNames("myservice.local"),
)

func Server deprecated

func Server(
	multicastPktConnV4 *ipv4.PacketConn,
	multicastPktConnV6 *ipv6.PacketConn,
	config *Config,
) (*Conn, error)

Server establishes a mDNS connection over an existing conn.

Deprecated: Use NewServer with functional options instead. This function is retained for backward compatibility with existing code.

This function applies WebRTC/ICE legacy behavior by default, only processing A and AAAA record types. The equivalent NewServer call is:

conn, err := mdns.NewServer(
    ipv4.NewPacketConn(l4),
    ipv6.NewPacketConn(l6),
    mdns.WithLocalNames("example.local"),
    mdns.WithRecordTypes(dnsmessage.TypeA, dnsmessage.TypeAAAA),
)

For full mDNS/DNS-SD support (all record types), omit WithRecordTypes.

func (*Conn) Browse added in v2.2.0

func (c *Conn) Browse(ctx context.Context, serviceType string) error

Browse starts discovering DNS-SD service instances of the given type on the local network. It sends periodic PTR queries for "<serviceType>.local." and fires the OnServiceDiscovered handler for each unique instance found.

The context controls the lifetime of the browse operation. Discovered instances are deduplicated.

Example:

conn.OnServiceDiscovered(func(evt mdns.ServiceEvent) {
    fmt.Printf("Found: %s at %s:%d\n",
        evt.Instance.Instance, evt.Addr, evt.Instance.Port)
})
err := conn.Browse(ctx, "_http._tcp")

func (*Conn) Close

func (c *Conn) Close() error

Close closes the mDNS Conn.

func (*Conn) EnumerateServiceTypes added in v2.2.0

func (c *Conn) EnumerateServiceTypes(ctx context.Context) error

EnumerateServiceTypes starts discovering all service types advertised on the local network using the DNS-SD service type enumeration meta-query (RFC 6763 §9).

Fires the OnServiceTypeDiscovered handler for each unique service type found. The context controls the lifetime of the enumeration.

func (*Conn) OnServiceDiscovered added in v2.2.0

func (c *Conn) OnServiceDiscovered(handler func(ServiceEvent))

OnServiceDiscovered sets a handler that is fired when a DNS-SD service instance is discovered during browsing. The handler is stored atomically and may be changed at any time. Set to nil to clear.

func (*Conn) OnServiceTypeDiscovered added in v2.2.0

func (c *Conn) OnServiceTypeDiscovered(handler func(string))

OnServiceTypeDiscovered sets a handler that is fired when a service type is discovered during enumeration. The handler is stored atomically and may be changed at any time. Set to nil to clear.

func (*Conn) Query deprecated

func (c *Conn) Query(ctx context.Context, name string) (dnsmessage.ResourceHeader, net.Addr, error)

Query sends mDNS Queries for the following name until either the Context is canceled/expires or we get a result

Deprecated: Use QueryAddr instead as it supports the easier to use netip.Addr.

func (*Conn) QueryAddr added in v2.0.5

func (c *Conn) QueryAddr(ctx context.Context, name string) (dnsmessage.ResourceHeader, netip.Addr, error)

QueryAddr sends mDNS Queries for the following name until either the Context is canceled/expires or we get a result.

func (*Conn) Register added in v2.2.0

func (c *Conn) Register(svc ServiceInstance) error

Register adds a DNS-SD service instance to the server. The service will be advertised in response to PTR, SRV, and TXT queries. Returns an error if the connection is closed or has no server.

func (*Conn) Unregister added in v2.2.0

func (c *Conn) Unregister(instance, service string)

Unregister removes a DNS-SD service instance from the server. The instance is identified by its Instance name and Service type.

func (*Conn) UpdateTXT added in v2.2.0

func (c *Conn) UpdateTXT(instance, service string, text []TXTEntry) error

UpdateTXT replaces the TXT data of a registered DNS-SD service and immediately announces the new record. The instance is identified by its Instance name and Service type.

https://www.rfc-editor.org/rfc/rfc6762.html#section-8.4 https://www.rfc-editor.org/rfc/rfc6762.html#section-10.2

type ServerOption added in v2.2.0

type ServerOption interface {
	// contains filtered or unexported methods
}

ServerOption configures a Server.

type ServiceEvent added in v2.2.0

type ServiceEvent struct {
	// Type identifies whether the service was added or updated.
	Type ServiceEventType

	// Instance is the discovered service.
	Instance ServiceInstance

	// Addr is the resolved address of the service host.
	Addr netip.Addr
}

ServiceEvent represents a resolved DNS-SD service instance. It is emitted by Browse when a complete service instance has been resolved (PTR → SRV + TXT → address).

type ServiceEventType added in v2.2.0

type ServiceEventType uint8

ServiceEventType identifies why a ServiceEvent was emitted.

const (
	// ServiceAdded indicates that a service instance was resolved for the first time.
	ServiceAdded ServiceEventType = iota
	// ServiceUpdated indicates that a resolved service instance changed while
	// it was being continuously monitored.
	//
	// https://www.rfc-editor.org/rfc/rfc6762.html#section-5.2
	ServiceUpdated
)

type ServiceInstance added in v2.2.0

type ServiceInstance struct {
	// Instance is the user-friendly name (UTF-8, max 63 bytes after encoding).
	// May contain dots and other punctuation (RFC 6763 §4.1.1).
	Instance string

	// Service is the service type, e.g. "_http._tcp".
	// Must be in the form "_<name>._<proto>" where proto is "tcp" or "udp".
	Service string

	// Domain is the DNS domain, typically "local" for mDNS.
	Domain string

	// Host is the target hostname for the SRV record (e.g. "myhost.local.").
	Host string

	// Port is the TCP or UDP port number.
	Port uint16

	// Priority is the SRV priority field (lower = preferred). Default 0.
	Priority uint16

	// Weight is the SRV weight field. Default 0.
	Weight uint16

	// Text contains the key/value pairs for the TXT record.
	Text []TXTEntry
}

ServiceInstance represents a DNS-SD service instance (RFC 6763).

A service instance is identified by:

<Instance>.<Service>.<Domain>

Example:

Instance: "My Web Server"
Service:  "_http._tcp"
Domain:   "local"
Host:     "myhost.local."
Port:     8080

type TXTEntry added in v2.2.0

type TXTEntry struct {
	Key   string
	Value []byte // nil = boolean attribute (present, no value)
}

TXTEntry represents a single key=value pair in a DNS-SD TXT record (RFC 6763 §6). Key is case-insensitive, printable US-ASCII (0x20-0x7E) excluding '=' (0x3D). Value is opaque bytes (often UTF-8).

A nil Value indicates a boolean attribute — the key is simply present with no value. An empty (non-nil, zero-length) Value represents a key with an explicitly empty value (e.g. "PlugIns=").

Prefer the NewTXTString, NewTXTBinary, and NewTXTFlag constructors over a struct literal: they map the three RFC 6763 §6.4 cases to distinct calls and avoid the nil-vs-empty Value footgun.

func NewTXTBinary added in v2.2.0

func NewTXTBinary(key string, value []byte) TXTEntry

NewTXTBinary creates a TXT entry with a key and an opaque binary value (RFC 6763 §6.5), encoded on the wire as "key=<bytes>". A nil value is treated as an explicit empty value ("key="); use NewTXTFlag for a boolean attribute that carries no value at all.

func NewTXTFlag added in v2.2.0

func NewTXTFlag(key string) TXTEntry

NewTXTFlag creates a boolean TXT attribute: a key that is present with no value, encoded on the wire as just "key" (RFC 6763 §6.4).

func NewTXTString added in v2.2.0

func NewTXTString(key, value string) TXTEntry

NewTXTString creates a TXT entry with a key and string value, encoded on the wire as "key=value". An empty value yields "key=" (RFC 6763 §6.4).

Directories

Path Synopsis
examples
query command
This example program showcases the use of the mDNS client by querying a previously published address
This example program showcases the use of the mDNS client by querying a previously published address
server command
This example program showcases the use of the mDNS server by publishing "pion-test.local"
This example program showcases the use of the mDNS server by publishing "pion-test.local"
server/publish_ip command
This example program allows to set an IP that deviates from the automatically determined interface address.
This example program allows to set an IP that deviates from the automatically determined interface address.

Jump to

Keyboard shortcuts

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