dnssd

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2023 License: MIT Imports: 13 Imported by: 6

Documentation

Overview

Package dnssd provides tools for DNS-based service discovery as specified by RFC 6763. See https://www.rfc-editor.org/rfc/rfc6763.

Index

Constants

View Source
const DefaultTTL = 2 * time.Minute

DefaultTTL is the default TTL to use for DNS records.

View Source
const DefaultUnicastQueryTimeout = 500 * time.Millisecond

DefaultUnicastQueryTimeout is the default time to allow for unicast DNS queries to be served.

Variables

This section is empty.

Functions

func AbsoluteInstanceEnumerationDomain added in v0.3.0

func AbsoluteInstanceEnumerationDomain(service, domain string) string

AbsoluteInstanceEnumerationDomain returns the DNS name that is queried to perform "service instance enumeration" (aka "browsing") for specific service type & domain.

Service instance enumeration is used to find all of the instances of a specific service type on a specific domain.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.

func AbsoluteSelectiveInstanceEnumerationDomain added in v0.3.0

func AbsoluteSelectiveInstanceEnumerationDomain(subType, serviceType, domain string) string

AbsoluteSelectiveInstanceEnumerationDomain returns the absolute DNS name that is queried to perform "selective instance enumeration" for a specific service sub-type.

Selective instance enumeration is like instance enumeration (browsing), but the results are filtered even further to service instances where the service behaves in a specific way or fulfills some specific function.

For example, browsing can be used to find all instances that provide the _http._tcp service type, but selective instance enumeration can be used to narrow those results to include only web servers that are printer control panels.

See https://www.rfc-editor.org/rfc/rfc6763#section-7.1

func AbsoluteServiceInstanceName added in v0.3.0

func AbsoluteServiceInstanceName(instance, serviceType, domain string) string

AbsoluteServiceInstanceName returns the fully-qualfied DNS domain name that is queried to lookup records about a single service instance.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

func AbsoluteTypeEnumerationDomain added in v0.3.0

func AbsoluteTypeEnumerationDomain(domain string) string

AbsoluteTypeEnumerationDomain returns the absolute DNS name that is queried to perform "service type enumeration" for a specific domain.

Service type enumeration is used to find all of the available services on a single domain.

See https://www.rfc-editor.org/rfc/rfc6763#section-9

func EscapeInstance

func EscapeInstance(instance string) string

EscapeInstance escapes a service instance name for use within DNS records.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.3.

func NewAAAARecord

func NewAAAARecord(i ServiceInstance, ip net.IP) *dns.AAAA

NewAAAARecord returns an A record for a service instance.

ip must be a valid IPv4 or IPv6 address.

func NewARecord

func NewARecord(i ServiceInstance, ip net.IP) *dns.A

NewARecord returns an A record for a service instance.

ip must be an IPv4 address, or an IPv4 address expresses as an IPv6 address.

func NewPTRRecord

func NewPTRRecord(i ServiceInstance) *dns.PTR

NewPTRRecord returns the PTR record for a service instance.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1

func NewRecords

func NewRecords(i ServiceInstance, options ...AdvertiseOption) []dns.RR

NewRecords returns the set of DNS-SD records used to announce the given service instance.

func NewSRVRecord

func NewSRVRecord(i ServiceInstance) *dns.SRV

NewSRVRecord returns the SRV record for a service instance.

See https://www.rfc-editor.org/rfc/rfc6763#section-5.

func NewServiceSubTypePTRRecord

func NewServiceSubTypePTRRecord(i ServiceInstance, subType string) *dns.PTR

NewServiceSubTypePTRRecord returns a PTR record used to advertise a service was providing a specific service sub-type.

See https://www.rfc-editor.org/rfc/rfc6763#section-7.1.

func NewServiceTypePTRRecord

func NewServiceTypePTRRecord(serviceType, domain string, ttl time.Duration) *dns.PTR

NewServiceTypePTRRecord returns the PTR record for a service type.

These records are sent in response to a service type enumeration request.

See https://www.rfc-editor.org/rfc/rfc6763#section-9

func NewTXTRecords

func NewTXTRecords(i ServiceInstance) []*dns.TXT

NewTXTRecords returns TXT records containing a service instance's attributes.

It returns one TXT record for each non-empty set of attributes in i.Attributes.

If there are no attributes, it returns a single empty TXT record.

See https://www.rfc-editor.org/rfc/rfc6763#section-6. See https://www.rfc-editor.org/rfc/rfc6763#section-6.8.

func ParseInstance

func ParseInstance(name string) (instance, tail string, err error)

ParseInstance parses the "<instance>" portion of a service instance name.

The given name must be either an escaped "<instance>" portion of a fully-qualified "service instance name", or the fully-qualified "service instance name" itself. Parsing stops at the first unescaped dot.

instance is the parsed and unescaped instance name. tail is the remaining unparsed portion of n, not including the separating dot.

tail is empty if name is just the "<instance>" portion (that is, it does not contain any unescaped dots).

func RelativeInstanceEnumerationDomain added in v0.3.0

func RelativeInstanceEnumerationDomain(service string) string

RelativeInstanceEnumerationDomain returns the DNS name that is queried to perform "service instance enumeration" (aka "browsing") for specific service type relative to the domain in which the records are advertised.

Service instance enumeration is used to find all of the instances of a specific service type on a specific domain.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.

func RelativeSelectiveInstanceEnumerationDomain added in v0.3.0

func RelativeSelectiveInstanceEnumerationDomain(subType, serviceType string) string

RelativeSelectiveInstanceEnumerationDomain returns the DNS name that is queried to perform "selective instance enumeration" for a specific service sub-type relative to the domain in which the records are advertised.

Selective instance enumeration is like instance enumeration (browsing), but the results are filtered even further to service instances where the service behaves in a specific way or fulfills some specific function.

For example, browsing can be used to find all instances that provide the _http._tcp service type, but selective instance enumeration can be used to narrow those results to include only web servers that are printer control panels.

See https://www.rfc-editor.org/rfc/rfc6763#section-7.1

func RelativeServiceInstanceName added in v0.3.0

func RelativeServiceInstanceName(instance, serviceType string) string

RelativeServiceInstanceName returns the DNS domain name that is queried to lookup records about a single service instance relative to the domain in which the records are published.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

func RelativeTypeEnumerationDomain added in v0.3.0

func RelativeTypeEnumerationDomain() string

RelativeTypeEnumerationDomain returns the DNS name that is queried to perform "service type enumeration" relative to the domain in which the records are advertised.

Service type enumeration is used to find all of the available services on a single domain.

See https://www.rfc-editor.org/rfc/rfc6763#section-9

Types

type AdvertiseOption

type AdvertiseOption func(*advertiseOptions)

AdvertiseOption is an option that changes the behavior of how a service instance is advertised.

func WithIPAddress

func WithIPAddress(ip net.IP) AdvertiseOption

WithIPAddress is an AccountOption that adds DNS A and/or AAAA records that map the service's hostname to the given IP.

func WithServiceSubType

func WithServiceSubType(subType string) AdvertiseOption

WithServiceSubType is an announce option that advertises the service as providing a specific service sub-type.

See https://www.rfc-editor.org/rfc/rfc6763#section-7.1

type AttributeCollection added in v0.4.0

type AttributeCollection []Attributes

AttributeCollection is a collection of Attributes. Each entry in the slice contains the attributes conveyed in a separate TXT record.

func (AttributeCollection) Equal added in v0.4.0

Equal returns true if c and x contain the same sets of attributes, in any order.

func (AttributeCollection) Flags added in v0.4.0

func (c AttributeCollection) Flags() map[string]struct{}

Flags returns the flag (i.e. non-pair) attributes that are set.

func (AttributeCollection) Get added in v0.4.0

func (c AttributeCollection) Get(k string) (v []byte, ok bool)

Get returns the last value that is associated with the key k.

ok is true there is a key/value pair with this key.

func (AttributeCollection) HasFlags added in v0.4.0

func (c AttributeCollection) HasFlags(keys ...string) bool

HasFlags returns true if all of the given flags are present in the attributes.

func (AttributeCollection) Pairs added in v0.4.0

func (c AttributeCollection) Pairs() map[string][]byte

Pairs returns the key/value pair (i.e. non-flag) attributes.

type Attributes

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

Attributes represents the set of attributes conveyed in a DNS-SD service instance's TXT record.

Each attribute may be either a key/value pair, where the value is a byte slice, or a flag (called a boolean attribute in RFC 6763).

Pairs and flags occupy the same keyspace, meaning that it is not possible to have a flag with the same name as a pair's key.

This is a consequence of how the attributes are represented inside the TXT records. A flag is represented as a key without value, which is also distinct from a pair with an empty value.

Keys are case-insensitive. They MUST be at least one character long and SHOULD NOT be longer than 9 characters. The characters of a key MUST be printable US-ASCII values (0x20-0x7E), excluding '=' (0x3D).

See https://www.rfc-editor.org/rfc/rfc6763#section-6.1

Attributes is not safe for concurrent use without synchronization.

func NewAttributes added in v0.1.3

func NewAttributes() Attributes

NewAttributes returns a new empty attribute set.

func (Attributes) Equal added in v0.2.0

func (a Attributes) Equal(attr Attributes) bool

Equal returns true if the attributes are equal.

func (Attributes) Flags

func (a Attributes) Flags() map[string]struct{}

Flags returns the flag (i.e. non-pair) attributes that are set.

func (Attributes) Get

func (a Attributes) Get(k string) (v []byte, ok bool)

Get returns the value that is associated with the key k.

ok is true there is a key/value pair with this key.

func (Attributes) HasFlags

func (a Attributes) HasFlags(keys ...string) bool

HasFlags returns true if all of the given flags are present in the attributes.

func (Attributes) IsEmpty

func (a Attributes) IsEmpty() bool

IsEmpty returns true if there are no attributes present.

func (Attributes) Pairs

func (a Attributes) Pairs() map[string][]byte

Pairs returns the key/value pair (i.e. non-flag) attributes.

func (Attributes) ToTXT

func (a Attributes) ToTXT() []string

ToTXT returns the string representation of each key/value pair, as they appear in the TXT record.

The result is deterministic (keys are sorted) to avoid unnecessary DNS churn when the attributes are used to construct DNS records.

func (Attributes) WithFlag added in v0.2.0

func (a Attributes) WithFlag(k string) Attributes

WithFlag returns a lcone of the attributes with an additional flag.

It replaces any existing key/value pair with this key.

Use Without() to clear a flag.

func (Attributes) WithPair added in v0.2.0

func (a Attributes) WithPair(k string, v []byte) Attributes

WithPair returns a clone of the attributes with an additional key/value pair.

It replaces any existing key/value pair or flag with this key.

func (Attributes) WithTXT added in v0.2.0

func (a Attributes) WithTXT(pair string) (_ Attributes, ok bool, err error)

WithTXT returns a clone of the attributes containing an attribute parsed from a single value within in a DNS-SD service instance's TXT record.

As per RFC 6763, TXT record values that begin with an '=' are ignored, in which case ok is false. Empty values are also ignored.

func (Attributes) Without added in v0.2.0

func (a Attributes) Without(keys ...string) Attributes

Without returns a clone of the attributes without the given keys, regardless of whether they are key/value pairs or flags.

type Enumerator

type Enumerator interface {
	// EnumerateServiceTypes finds all of the service types advertised within a
	// single domain.
	//
	// It blocks until ctx is canceled or an error occurs.
	//
	// obs is an observer fuction that is called whenever a new service type is
	// discovered. The context passed to obs is canceled when that service type
	// goes away. Enumeration is aborted if obs returns an error.
	EnumerateServiceTypes(
		ctx context.Context,
		domain string,
		obs func(ctx context.Context, serviceType string) error,
	) error

	// EnumerateInstances finds all of the instances of a specific service type
	// that are advertised within a single domain. This operation is also known
	// as "browsing".
	//
	// It blocks until ctx is canceled or an error occurs.
	//
	// obs is an observer fuction that is called whenever a new service instance
	// is discovered. The context passed to obs is canceled when that service
	// instance goes away. Enumeration is aborted if obs returns an error.
	EnumerateInstances(
		ctx context.Context,
		serviceType, domain string,
		obs func(ctx context.Context, i ServiceInstance) error,
	) error

	// EnumerateInstancesSelectively finds all of the instances of a specific
	// service type that are advertised within a single domain where those
	// services have a specific service sub-type.
	//
	// It blocks until ctx is canceled or an error occurs.
	//
	// obs is an observer fuction that is called whenever a new service instance
	// is discovered. The context passed to obs is canceled when that service
	// instance goes away. Enumeration is aborted if obs returns an error.
	EnumerateInstancesSelectively(
		ctx context.Context,
		subType, serviceType, domain string,
		obs func(ctx context.Context, i ServiceInstance) error,
	) error
}

Enumerator is an interface for enumerating (discovering) DNS-SD services.

type ServiceInstance

type ServiceInstance struct {
	ServiceInstanceName

	// TargetHost is the fully-qualified hostname of the machine that hosts the
	// service.
	//
	// This is not necessarily within in the same domain as the DNS-SD records.
	TargetHost string

	// TargetPort is TCP or UDP port on which the service is provided.
	TargetPort uint16

	// Priority is the priority of the instance within the pool of instances
	// that  offer the same service for the same domain.
	//
	// It controls which servers are contacted first. Lower values have a higher
	// priority.
	//
	// See https://www.rfc-editor.org/rfc/rfc2782.
	Priority uint16

	// Weight is the weight of this instance within the pool of instances that
	// offer the same service for the same domain.
	//
	// It controls the likelihood that the instance will be chosen from a pool
	// instances with the same priority. Higher values are more likely to be
	// chosen.
	//
	// See https://www.rfc-editor.org/rfc/rfc2782.
	Weight uint16

	// Attributes contains a set of attributes that provide additional
	// information about the service instance.
	//
	// Attributes are encoded in the instance's TXT record, as per
	// https://www.rfc-editor.org/rfc/rfc6763#section-6.3.
	//
	// Each element in the slice corresponds to the attributes encoded in a
	// single TXT record.
	//
	// Each instance MUST have at least one TXT record and MAY have multiple TXT
	// records, although this is rarely used in practice, see
	// https://www.rfc-editor.org/rfc/rfc6763#section-6.8.
	//
	// An empty slice is a valid representation of an instance with a single
	// empty TXT record.
	Attributes AttributeCollection

	// TTL is the time-to-live of the instance's DNS records.
	TTL time.Duration
}

ServiceInstance encapsulates information about a single DNS-SD service instance.

func (ServiceInstance) Equal added in v0.2.0

func (i ServiceInstance) Equal(inst ServiceInstance) bool

Equal returns true if i and inst are equal.

type ServiceInstanceName

type ServiceInstanceName struct {
	// Name is the service instance's unqualified name.
	//
	// For example, "Boardroom Printer".
	//
	// This is the "<instance>" portion of the "service instance name", as
	// described in https://www.rfc-editor.org/rfc/rfc6763#section-4.1.
	Name string

	// ServiceType is the type of service that the instance provides.
	//
	// For example "_http._tcp", or "_airplay._tcp".
	//
	// This is the "<service>" portion of the "service instance name", as
	// described in https://www.rfc-editor.org/rfc/rfc6763#section-4.1.
	ServiceType string

	// Domain is the domain under which the instance is advertised.
	//
	// That is, the domain name that contains the DNS-SD records SRV, PTR and
	// TXT records.
	//
	// This name is often set to "local" when using Multicast DNS (Bonjour,
	// Zerconf), but may be any valid domain name.
	//
	// This is the "<domain>" portion of the "service instance name", as
	// described in https://www.rfc-editor.org/rfc/rfc6763#section-4.1.
	Domain string
}

ServiceInstanceName encapsulates a fully-qualified DNS-SD service instance name.

func (ServiceInstanceName) Absolute added in v0.3.0

func (n ServiceInstanceName) Absolute() string

Absolute returns the fully-qualfied DNS domain name that is queried to lookup records about a single service instance.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

func (ServiceInstanceName) Equal added in v0.3.0

Equal returns true if n and name are equal.

func (ServiceInstanceName) Relative added in v0.3.0

func (n ServiceInstanceName) Relative() string

Relative returns the DNS domain name that is queried to lookup records about a single service instance, relative to the domain in which the records are published.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

type UnicastResolver

type UnicastResolver struct {
	Client *dns.Client
	Config *dns.ClientConfig
}

UnicastResolver makes DNS-SD queries using unicast DNS requests.

This is a relatively low-level interface that allows performing each type of DNS-SD query type separately.

func (*UnicastResolver) EnumerateInstances

func (r *UnicastResolver) EnumerateInstances(
	ctx context.Context,
	serviceType, domain string,
) ([]string, error)

EnumerateInstances finds all of the instances of a given service type that are advertised within a single domain.

This operation is also known as as "browsing".

serviceType is the type of service to enumerate, for example "_http._tcp".

It returns a slice of the instance names. This is the "<instance>" portion of the "service instance name", for example, "Boardroom Printer".

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

func (*UnicastResolver) EnumerateInstancesBySubType

func (r *UnicastResolver) EnumerateInstancesBySubType(
	ctx context.Context,
	subType, serviceType, domain string,
) ([]string, error)

EnumerateInstancesBySubType finds all of the instances of a given service sub-type that are advertised within a single domain.

This operation is also known as "selective instance enumeration" or less commonly "selective browsing" or "sub-type browsing".

subType is the specific service sub-type, such as "_printer". serviceType is the type of service to enumerate, for example "_http._tcp".

It returns a slice of the instance names. This is the "<instance>" portion of the "service instance name", for example, "Boardroom Printer".

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

func (*UnicastResolver) EnumerateServiceTypes

func (r *UnicastResolver) EnumerateServiceTypes(
	ctx context.Context,
	domain string,
) ([]string, error)

EnumerateServiceTypes finds all of the service types advertised within a single domain.

It returns a slice containing the discovered service types, without the domain suffix. This is the "<service>" portion of the "service instance name", For example "_http._tcp".

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

func (*UnicastResolver) LookupInstance

func (r *UnicastResolver) LookupInstance(
	ctx context.Context,
	instance, serviceType, domain string,
) (_ ServiceInstance, ok bool, _ error)

LookupInstance looks up the details about a specific service instance.

instance and serviceType are the "<instance>" and "<service>" portions of the instance name, for example "Boardroom Printer" and "_http._tcp", respectively.

ok is false if the instance can not be respolved.

See https://www.rfc-editor.org/rfc/rfc6763#section-4.1.

type UnicastServer

type UnicastServer struct {
	// Timeout is the amount of time to allow for each DNS query.
	//
	// If it is non-positive, DefaultUnicastQueryTimeout is used instead.
	Timeout time.Duration
	// contains filtered or unexported fields
}

UnicastServer is a conventional (unicast) DNS server designed specifically for serving DNS-SD records.

It does not support recursive DNS queries (i.e, it can not forward requests for unknown domains to upstream DNS servers).

func (*UnicastServer) Advertise

func (s *UnicastServer) Advertise(i ServiceInstance, options ...AdvertiseOption)

Advertise starts advertising a DNS-SD service instance.

addresses is a set of optional IP addresses. If provided, the server will also respond with the relevant A and AAAA requests when it receives a query for the hostname in i.TargetHost.

Typically, these records would be served by a separate domain name server that is authoratative for the internet domain name used in i.TargetHost.

func (*UnicastServer) Remove

func (s *UnicastServer) Remove(i ServiceInstance)

Remove stops advertising a DNS-SD service instance.

func (*UnicastServer) Run

func (s *UnicastServer) Run(ctx context.Context, network, address string) error

Run runs the server until ctx is canceled or an error occurs.

Jump to

Keyboard shortcuts

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