dnssd

package module
v1.2.10 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2023 License: MIT Imports: 15 Imported by: 45

README

DNS-SD

Build Status

This library implements Multicast DNS and DNS-Based Service Discovery to provide zero-configuration operations. It lets you announce and find services in a specific link-local domain.

Usage

Create a mDNS responder

The following code creates a service with name "My Website._http._tcp.local." for the host "My Computer" which has all IPs from network interface "eth0". The service is added to a responder.

import (
	"context"
	"github.com/brutella/dnssd"
)

cfg := dnssd.Config{
    Name:   "My Website",
    Type:   "_http._tcp",
    Domain: "local",
    Host:   "My Computer",
    Ifaces: []string{"eth0"},,
    Port:   12345,
}
sv, _ := dnssd.NewService(cfg)

In most cases you only need to specify the name, type and port of the service.

cfg := dnssd.Config{
    Name:   "My Website",
    Type:   "_http._tcp",
    Port:   12345,
}
sv, _ := dnssd.NewService(cfg)

Then you create a responder and add the service to it.

rp, _ := dnssd.NewResponder()
hdl, _ := rp.Add(sv)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

rp.Respond(ctx)

When calling Respond the responder probes for the service instance name and host name to be unqiue in the network. Once probing is finished, the service will be announced.

Update TXT records

Once a service is added to a responder, you can use the hdl to update properties.

hdl.UpdateText(map[string]string{"key1": "value1", "key2": "value2"}, rsp)

dnssd command

The command line tool in cmd/dnssd lets you browse, register and resolve services similar to dns-sd.

Install

You can install the tool with

go install github.com/brutella/dnssd/cmd/dnssd

Usage

Registering a service on your local machine

Lets register a printer service (_printer._tcp) running on your local computer at port 515 with the name "Private Printer".

dnssd register -Name="Private Printer" -Type="_printer._tcp" -Port=515

Registering a proxy service

If the service is running on a different machine on your local network, you have to specify the hostname and IP. Lets say the printer service is running on the printer with the hostname ABCD and IPv4 address 192.168.1.53, you can register a proxy which announce that service on your network.

dnssd register -Name="Private Printer" -Type="_printer._tcp" -Port=515 -IP=192.168.1.53 -Host=ABCD

Use option -Interface, if you want to announce the service only on a specific network interface. This might be necessary if your local machine is connected to multiple subnets and your announced service is only available on a specific subnet.

dnssd register -Name="Private Printer" -Type="_printer._tcp" -Port=515 -IP=192.168.1.53 -Host=ABCD -Interface=en0

Browsing for a service

If you want to browse for a service type, you can use the browse command.

dnssd browse -Type="_printer._tcp"

Resolving a service instance

If you know the name of a service instance, you can resolve its hostname with the resolve command.

dnssd resolve -Name="Private Printer" -Type="_printer._tcp"

Conformance

This library passes the multicast DNS tests of Apple's Bonjour Conformance Test.

TODO

  • Support hot plugging
  • Support negative responses (RFC6762 6.1)
  • Handle txt records case insensitive
  • Remove outdated services from cache regularly
  • Make sure that hostnames are FQDNs

Contact

Matthias Hochgatterer

Github: https://github.com/brutella

Twitter: https://twitter.com/brutella

License

dnssd is available under the MIT license. See the LICENSE file for more info.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// IPv4LinkLocalMulticast is the IPv4 link-local multicast address.
	IPv4LinkLocalMulticast = net.ParseIP("224.0.0.251")
	// IPv6LinkLocalMulticast is the IPv6 link-local multicast address.
	IPv6LinkLocalMulticast = net.ParseIP("ff02::fb")

	// AddrIPv4LinkLocalMulticast is the IPv4 link-local multicast UDP address.
	AddrIPv4LinkLocalMulticast = &net.UDPAddr{
		IP:   IPv4LinkLocalMulticast,
		Port: 5353,
	}

	// AddrIPv6LinkLocalMulticast is the IPv5 link-local multicast UDP address.
	AddrIPv6LinkLocalMulticast = &net.UDPAddr{
		IP:   IPv6LinkLocalMulticast,
		Port: 5353,
	}

	// TTLDefault is the default time-to-live for mDNS resource records.
	TTLDefault uint32 = 75 * 6

	// TTLHostname is the default time-to-livefor mDNS hostname records.
	TTLHostname uint32 = 120
)

Functions

func A

func A(srv Service, iface *net.Interface) []*dns.A

A returns the A records (IPv4 addresses) for the service.

func AAAA

func AAAA(srv Service, iface *net.Interface) []*dns.AAAA

AAAA returns the AAAA records (IPv6 addresses) of the service.

func DNSSDServicesPTR

func DNSSDServicesPTR(srv Service) *dns.PTR

func LookupType

func LookupType(ctx context.Context, service string, add AddFunc, rmv RmvFunc) (err error)

LookupType browses for service instanced with a specified service type.

func MulticastInterfaces added in v1.2.5

func MulticastInterfaces(filters ...string) []*net.Interface

MulticastInterfaces returns a list of all active multicast network interfaces.

func NSEC

func NSEC(rr dns.RR, srv Service, iface *net.Interface) *dns.NSEC

NSEC returns the NSEC record for the service.

func PTR

func PTR(srv Service) *dns.PTR

PTR returns the PTR record for the service.

func SRV

func SRV(srv Service) *dns.SRV

SRV returns the SRV record for the service.

func TXT

func TXT(srv Service) *dns.TXT

TXT returns the TXT record for the service.

Types

type AddFunc added in v1.2.0

type AddFunc func(BrowseEntry)

AddFunc is called when a service instance was found.

type BrowseEntry added in v1.2.0

type BrowseEntry struct {
	IPs       []net.IP
	Host      string
	Port      int
	IfaceName string
	Name      string
	Type      string
	Domain    string
	Text      map[string]string
}

BrowseEntry represents a discovered service instance.

func (BrowseEntry) ServiceInstanceName added in v1.2.0

func (e BrowseEntry) ServiceInstanceName() string

ServiceInstanceName returns the service instance name in the form of <instance name>.<service>.<domain>. (Note the trailing dot.)

func (BrowseEntry) UnescapedName added in v1.2.8

func (e BrowseEntry) UnescapedName() string

UnescapedName returns the unescaped instance name.

func (BrowseEntry) UnescapedServiceInstanceName added in v1.2.8

func (e BrowseEntry) UnescapedServiceInstanceName() string

UnescapedServiceInstanceName returns the same as `ServiceInstanceName()` but removes any escape characters.

type Cache

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

Cache stores services in memory.

func NewCache

func NewCache() *Cache

NewCache returns a new in-memory cache.

func (*Cache) Services added in v1.2.0

func (c *Cache) Services() []*Service

Services returns a list of stored services.

func (*Cache) UpdateFrom

func (c *Cache) UpdateFrom(msg *dns.Msg, iface *net.Interface) (adds []*Service, rmvs []*Service)

UpdateFrom updates the cache from resource records in msg. TODO consider the cache-flush bit to make records as to be deleted in one second

type Config added in v1.1.0

type Config struct {
	// Name of the service.
	Name string

	// Type is the service type, for example "_hap._tcp".
	Type string

	// Domain is the name of the domain, for example "local".
	// If empty, "local" is used.
	Domain string

	// Host is the name of the host (no trailing dot).
	// If empty the local host name is used.
	Host string

	// Txt records
	Text map[string]string

	// IP addresses of the service.
	// This field is deprecated and should not be used.
	IPs []net.IP

	// Port is the port of the service.
	Port int

	// Interfaces at which the service should be registered
	Ifaces []string
}

func (Config) Copy added in v1.1.0

func (c Config) Copy() Config

type MDNSConn

type MDNSConn interface {
	// SendQuery sends a mDNS query.
	SendQuery(q *Query) error

	// SendResponse sends a mDNS response
	SendResponse(resp *Response) error

	// Read returns a channel which receives mDNS messages
	Read(ctx context.Context) <-chan *Request

	// Clears the connection buffer
	Drain(ctx context.Context)

	// Close closes the connection
	Close()
}

MDNSConn represents a mDNS connection. It encapsulates an IPv4 and IPv6 UDP connection.

func NewMDNSConn

func NewMDNSConn() (MDNSConn, error)

NewMDNSConn returns a new mdns connection.

type Query

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

Query is a mDNS query

func (Query) IfaceName added in v1.2.0

func (q Query) IfaceName() string

IfaceName returns the name of the network interface where the request was received. If the network interface is unknown, the string "?" is returned.

type ReadFunc

type ReadFunc func(*Request)

type Request

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

Request represents an incoming mDNS message

func (Request) From added in v1.2.7

func (r Request) From() *net.UDPAddr

From returns the sender address.

func (Request) IfaceName added in v1.2.0

func (r Request) IfaceName() string

IfaceName returns the name of the network interface where the request was received. If the network interface is unknown, the string "?" is returned.

func (Request) Raw added in v1.2.7

func (r Request) Raw() *dns.Msg

Raw returns the raw DNS maessage.

func (Request) String added in v1.1.0

func (r Request) String() string

type Responder

type Responder interface {
	// Add adds a service to the responder.
	// Use the returned service handle to update service properties.
	Add(srv Service) (ServiceHandle, error)

	// Remove removes the service associated with the service handle from the responder.
	Remove(srv ServiceHandle)

	// Respond makes the receiver announcing and managing services.
	Respond(ctx context.Context) error

	// Debug calls a function for every dns request the responder receives.
	Debug(ctx context.Context, fn ReadFunc)
}

Responder represents a mDNS responder.

func NewResponder

func NewResponder() (Responder, error)

NewResponder returns a new mDNS responder.

type Response

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

Response is a mDNS response

type RmvFunc added in v1.2.0

type RmvFunc func(BrowseEntry)

RmvFunc is called when a service instance disappared.

type Service

type Service struct {
	Name   string
	Type   string
	Domain string
	Host   string
	Text   map[string]string
	TTL    time.Duration // Original time to live
	Port   int
	IPs    []net.IP
	Ifaces []string
	// contains filtered or unexported fields
}

Service represents a DNS-SD service instance

func LookupInstance

func LookupInstance(ctx context.Context, instance string) (Service, error)

LookupInstance resolves a service by its service instance name.

func NewService

func NewService(cfg Config) (s Service, err error)

NewService returns a new service for the given config.

func ProbeService

func ProbeService(ctx context.Context, srv Service) (Service, error)

ProbeService probes for the hostname and service instance name of srv. If err == nil, the returned service is verified to be unique on the local network.

func ReprobeService

func ReprobeService(ctx context.Context, srv Service) (Service, error)

func (Service) Copy

func (s Service) Copy() *Service

Copy returns a copy of the service.

func (Service) Hostname

func (s Service) Hostname() string

func (*Service) IPsAtInterface added in v1.1.0

func (s *Service) IPsAtInterface(iface *net.Interface) []net.IP

IPsAtInterface returns the ip address at a specific interface.

func (*Service) Interfaces added in v1.2.0

func (s *Service) Interfaces() []*net.Interface

Interfaces returns the network interfaces for which the service is registered, or all multicast network interfaces, if no IP addresses are specified.

func (*Service) IsVisibleAtInterface added in v1.2.5

func (s *Service) IsVisibleAtInterface(n string) bool

IsVisibleAtInterface returns true, if the service is published at the network interface with name n.

func (Service) ServiceInstanceName

func (s Service) ServiceInstanceName() string

ServiceInstanceName returns the service instance name in the form of <instance name>.<service>.<domain>. (Note the trailing dot.)

func (Service) ServiceName

func (s Service) ServiceName() string

ServiceName returns the service name in the form of "<service>.<domain>." (Note the trailing dot.)

func (Service) ServicesMetaQueryName

func (s Service) ServicesMetaQueryName() string

ServicesMetaQueryName returns the name of the meta query for the service domain in the form of "_services._dns-sd._udp.<domain.". (Note the trailing dot.)

func (*Service) SetHostname

func (s *Service) SetHostname(hostname string)

SetHostname sets the service's host name and domain (if specified as "<hostname>.<domain>."). (Note the trailing dot.)

func (Service) UnescapedName added in v1.2.8

func (s Service) UnescapedName() string

UnescapedName returns the unescaped instance name.

func (Service) UnescapedServiceInstanceName added in v1.2.8

func (s Service) UnescapedServiceInstanceName() string

UnescapedServiceInstanceName returns the same as `ServiceInstanceName()` but removes any escape characters.

type ServiceHandle

type ServiceHandle interface {
	UpdateText(text map[string]string, r Responder)
	Service() Service
}

ServiceHandle serves a middleman between a service and a responder.

Directories

Path Synopsis
cmd
bct
browse
Command browse browses for specific dns-sd service types.
Command browse browses for specific dns-sd service types.
debug
Command debug logs dns packets to the console.
Command debug logs dns packets to the console.
dnssd
dnssd is a utilty to register and browser DNS-SD services.
dnssd is a utilty to register and browser DNS-SD services.
register
Command register registers a dns-sd service instance.
Command register registers a dns-sd service instance.
resolve
Command resolve resolves a dns-sd service instance.
Command resolve resolves a dns-sd service instance.

Jump to

Keyboard shortcuts

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