dnssd

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2022 License: MIT Imports: 14 Imported by: 0

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 the IP "192.168.0.123" on port "12345". 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",
    IPs:    []net.IP{net.ParseIP("192.168.0.123")},
    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)

Examples

There are examples in the _cmd directory to register services, resolve service instances and to browse for service types.

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 = net.ParseIP("224.0.0.251")
	IPv6LinkLocalMulticast = net.ParseIP("ff02::fb")

	AddrIPv4LinkLocalMulticast = &net.UDPAddr{
		IP:   IPv4LinkLocalMulticast,
		Port: 5353,
	}

	AddrIPv6LinkLocalMulticast = &net.UDPAddr{
		IP:   IPv6LinkLocalMulticast,
		Port: 5353,
	}

	TTLDefault  uint32 = 75 * 60 // Default ttl for mDNS resource records
	TTLHostname uint32 = 120     // TTL for mDNS resource records containing the host name
)

Functions

func A

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

func AAAA

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

func DNSSDServicesPTR

func DNSSDServicesPTR(srv Service) *dns.PTR

func LookupType

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

func NSEC

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

func PTR

func PTR(srv Service) *dns.PTR

func SRV

func SRV(srv Service) *dns.SRV

func TXT

func TXT(srv Service) *dns.TXT

Types

type AddFunc

type AddFunc func(BrowseEntry)

type BrowseEntry

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

func (BrowseEntry) ServiceInstanceName

func (e BrowseEntry) ServiceInstanceName() string

type Cache

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

func NewCache

func NewCache() *Cache

func (*Cache) Services

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

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

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

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)

type Query

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

Query is a mDNS query

func (Query) IfaceName

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

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

func (Request) IfaceName

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

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

func (Request) String

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)

type Response

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

Response is a mDNS response

type RmvFunc

type RmvFunc func(BrowseEntry)

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)

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

func (Service) Hostname

func (s Service) Hostname() string

func (*Service) IPsAtInterface

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

IPsAtInterface returns the ip address at a specific interface.

func (*Service) Interfaces

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) ServiceInstanceName

func (s Service) ServiceInstanceName() string

func (Service) ServiceName

func (s Service) ServiceName() string

func (Service) ServicesMetaQueryName

func (s Service) ServicesMetaQueryName() string

func (*Service) SetHostname

func (s *Service) SetHostname(hostname string)

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.
register
Command register registers a dns-sd service instance.
Command register registers a dns-sd service instance.
relay
Relay packets to/from a tunneled interface Intended for use with Docker Deskstop on MacOSX which doesn't properly handle this
Relay packets to/from a tunneled interface Intended for use with Docker Deskstop on MacOSX which doesn't properly handle this
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