dnssd

package module
v0.0.0-...-721e571 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2016 License: LGPL-3.0 Imports: 17 Imported by: 1

README

dnssd

This is a LPGL license pure Go library for DNS Service Discovery.

It aims to be a fully compliant implementation of RFC6762 without any dependencies except pure go packages.

Dependencies

"context/Context"
"github.com/miekg/dns"
"github.com/stretchr/testify/assert"

License

The dnssd package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.

Usage

The library defines the funcs Browse, Resolve, Query, Register which are used in most normal operations. Each take a context.Context which can be used to cancel the operation. No channels are exposed by the API and all replies are performed using callbacks in a separate go-routine. The callback go-routines are reused and created as needed. If callabacks are handled quickly there will be only one go-routine.

For more specific needs the API exposes CreateRecordRegistrar for registering arbitrary entries.

Please see godoc via godoc github.com/ermahu/dnssd` for further information.

Examples

Browsing for a Service

ctx, cancel := context.WithCancel(context.Background())
dnssd.Browse(ctx, 0, 0, "_raop._tcp", "local",
	func(found bool, flags, ifIndex int, serviceName, regType, domain string) {
		fmt.Println("serviceName=", serviceName)
	}, func(err error) {
		fmt.Println("Error browsing: ", err)
		cancel()
	})

Resolving a serviceName

ctx, cancel := context.WithCancel(context.Background())
dnssd.Resolve(ctx, 0, 0, "rafael", "_airplay._tcp", "local",
	func(flags, ifIndex int, fullName, hostName string, port uint16, txt []string) {
		fmt.Println("Resolved: name=", fullName, ", host=", hostName, ", port=", port, ", text=", txt)
	}, func(err error) {
		fmt.Println("Error resolving: ", err)
		cancel()
	})

Registering a service

name := "testService"
regType := "_test._tcp"
port := 4711
txt := []string{"test=one", "check=two"}
ctx, cancel := context.WithCancel(context.Background())
dnssd.Register(ctx, 0, 3, name, regType, "", "", port, txt, 
    func(flags int, serviceName, regType, domain string) {
		fmt.Println("Register: serviceName=", serviceName, ", regType=", regType, ",domain=", domain)
}, func(err error) {
	fmt.Println("Error registering: ", err)
	cancel()
})

Querying for an address

ctx := context.Background()
hostname := "myserver.local."
dnssd.Query(ctx, 0, 0, &dns.Question{myserver, dns.TypeA, dns.ClassINET},
	func(flags, ifIndex int, rr dns.RR) {
		fmt.Println("Queried address is ",rr)
	}, func(err error) {
		fmt.Println("Error querying: ", err)
	})

Documentation

Overview

The dnssd package is a pure go implementation of DNS Service Discovery

also known as Bonjour(TM).

Index

Constants

View Source
const MORE_COMING = 1
View Source
const RECORD_ADDED = 8

Variables

This section is empty.

Functions

func Browse

func Browse(ctx context.Context, flags Flags, ifIndex int, regType, domain string, response ServiceUpdate, errc ErrCallback)

Browse a service. ctx is the context used to cancel a browse. flags are currently unused. ifIndex is used to indicate which interface the service should be browsed on. regType is the service type (e g _http._tcp) domain is the domain to browse for the service. If domain is set blank the default domain will be used. response is a closure called when service data has been updated. errc is called when an error has occured.

func ConstructFullName

func ConstructFullName(serviceName, regType, domain string) string

Concatenate a three-part domain name (as provided to the response funcs) into a properly-escaped full domain name.

func EnumerateDomains

func EnumerateDomains(ctx context.Context, flags Flags, ifIndex int, listener DomainUpdate, errc ErrCallback)

Asynchronously enumerate domains available for browsing and registration. Flags can be dnssd.BrowseDomains or dnssd.RegistrationDomains. ifIndex is ignored currently but may be used in the future if there are interface specific domains.

func Query

func Query(ctx context.Context, flags Flags, ifIndex int, question *dns.Question, response QueryAnswered, errc ErrCallback)

Query an arbitrary record. ctx is the query context and can be used to cancel or timeout a query. flags - Possible values are: MORE_COMING. ifIndex - If non-zero, specifies the interface on which to issue the query (the index for a given interface is determined via the if_nametoindex() family of calls.) Passing 0 causes the name to be queried for on all interfaces. Passing -1 causes the name to be queried for only on the local host. question - The question to query for. response - This closure will get called when the query completes. errc - This closure will be called when a query has an error.

func ReconfirmRecord

func ReconfirmRecord(flags Flags, ifIndex int, rr *dns.RR)

Instruct the daemon to verify the validity of a resource record that appears to be out of date.

func RepackToUTF8

func RepackToUTF8(unpacked string) string

domain names are "unpacked" using escape sequences and character escapes. Repack them to a proper UTF-8 string

func Resolve

func Resolve(ctx context.Context, flags Flags, ifIndex int, serviceName, regType, domain string, response ServiceResolved, errc ErrCallback)

Resolve a service to SRV host name and port, as well as a TXT record. When the resolve has return the wanted resolve the resolve should be stopped by calling the cancel function. This is a convencience function for resolving a single SRV and TXT record. More complex resolutions should use Query. ctx is the context for the resolve, should be cancellable. flags are unused currently, ifIndex is the index of the interface on which to resolve the service. Should normally be the same returned by a browse, if 0 it will resolve on all interfaces. The serviceName is the name of the service as returned by Browse. regType is the registration type (for example _raop._tcp) domain is the domain of the service, normally the domain returned by Browse should be used. If domain is blank it will be replaced with the local domain response is a function that will be called when a service has been resolved. May be called several times. errc is an error callback.

Types

type AddRecord

type AddRecord func(flags int, rr dns.RR)

Add an additional record to the service registration. This will be registered using the same context as the service was registered with

func Register

func Register(ctx context.Context, flags Flags, ifIndex int, serviceName, regType, domain, host string, port uint16, txt []string,
	listener ServiceRegistered, errc ErrCallback) AddRecord

Register a service. ctx is the context and is used to cancel a registration. ifIndex is the interface to publish the service on, 0 for all interfaces and -1 for localhost. serviceName is the name of the service. if left blank the computer name will be used and propagated to the ServiceRegistered callback. flags can be 0 or set to NoAutoRename. regType is the service registration type. domain is the domain of the service, usually left blank. host is the name of the server being registered. usually left blank for the local machine name. port is the port of the service. txtRecord is the content of the TXT record. listener is a closure that will be called when the service has been registered. errc is a closure that will be called if there was an error registering the service. The return from the func is an AddRecord func that can be called to add additional records that will be associated with this service.

type DomainUpdate

type DomainUpdate func(flags Flags, ifIndex int, domain string)
alled to report discovered domains. Flags can be dnssd.MoreComing and

dnssd.RecordAdded. The flag dnssd.RecordAdded should be checked to determine if a domain was found or lost.

type ErrCallback

type ErrCallback func(err error)

ErrCallback is a closure called when an error has occured in a dnssd call. err is the error that occurred.

type Flags

type Flags uint32
const (
	/*
		No flags (makes it clearer to use this symbolic constant rather than using a 0).
	*/
	None Flags = 0

	/*
		MoreComing indicates to a callback that at least one more result is queued and will be delivered
		following immediately after this one. Applications should not update their UI to display browse
		results when the MoreComing flag is set, because this would result in a great deal of ugly
		flickering on the screen. Applications should instead wait until until MoreComing is not set
		(i.e. "Finished", for now), and then update their UI. When MoreComing is not set (i.e.
		"Finished") that doesn't mean there will be no more answers EVER, just that there are no more
		answers immediately available right now at this instant. If more answers become available in
		the future they will be delivered as usual.
	*/
	MoreComing Flags = 1 << iota

	/*
		Service or domain has been added during browsing/querying or domain enumeration.
	*/
	Add Flags = 1 << iota

	/*
		Default domain has been added during domain enumeration.
	*/
	Default Flags = 1 << iota

	/*
		Auto renaming should not be performed. Only valid if a name is explicitly specified when
		registering a service (i.e. the default name is not used).
	*/
	NoAutoRename Flags = 1 << iota

	/*
		Shared flag for registering individual records on a connected DNSServiceRef. Indicates that there
		may be multiple records with this name on the network (e.g. PTR records).
	*/
	Shared Flags = 1 << iota

	/*
		Shared flag for registering individual records on a connected DNSServiceRef. Indicates that the
		record's name is to be unique on the network (e.g. SRV records).
	*/
	Unique Flags = 1 << iota

	/*
		Enumerates domains recommended for browsing.
	*/
	BrowseDomains Flags = 1 << iota

	/*
		Enumerates domains recommended for registration.
	*/
	RegistrationDomains Flags = 1 << iota

	/*
		True if a record was added. False it was lost.
	*/
	RecordAdded Flags = 1 << iota
)

func (Flags) String

func (f Flags) String() string

type QueryAnswered

type QueryAnswered func(flags Flags, ifIndex int, rr dns.RR)
This is called when a query has been resolved.

flags may be MORE_COMING or RECORD_ADDED. ifIndex is the interface the query was responden on. rr is a resource record matching the query.

type RecordRegistered

type RecordRegistered func(record dns.RR, flags int)

Callback when a record has been registered. record is the newly registered record. flags is currently unused and will be set to 0.

type RegisterRecord

type RegisterRecord func(ctx context.Context, flags Flags, ifIndex int, record dns.RR)

Registrar function, will register dns.RR records flags may be dnssd.SHARED or dnssd.UNIQUE. ifIndex The index of interface to register the record to. If 0 it will be registered on all interfaces. record is the dns.RR record to register.

func CreateRecordRegistrar

func CreateRecordRegistrar(listener RecordRegistered, errc ErrCallback) RegisterRecord

Create a DNSSDRecordRegistrar allowing efficient registration of multiple individual records. listener will be called when a record has been registered. errc will be called if there is an error with the registrar. The RegisterRecord closure returned is used to record new register entries.

type ServiceRegistered

type ServiceRegistered func(flags int, serviceName, regType, domain string)

Called when a service has been registered. Flags are currently unused and always 0, serviceName is the name registered. It may have been automatically chosen if the name was blank in the call to Register. The regType is the same as passed to Register. The domain parameter is the name of the domain the service was registered to, will be the default domain if domain was blank in the call to Register

type ServiceResolved

type ServiceResolved func(flags Flags, ifIndex int, fullName, hostName string, port uint16, txt []string)

This closure is called when a service has been resolved. flags are currently unused and set to 0. fullName is the full name of the service, e.g. <servicename>.<protocol>.<domain> The name us unpacked into a latin1/iso8859-1 string which needs to be used as argument to subsequent calls to Query. In order to see a proper UTF8 string of the full name you nedd to call RepackToUTF8. The parameter hostName is the name of the host and can be used to Query for IP-addresses using dns.TypeA and dns.TypeAAAA queries. The parameter port is the port number of the service. The TXT data is returned in txt as a string array. The form of the entries in each string is "<key>=<value>"

type ServiceUpdate

type ServiceUpdate func(found bool, flags Flags, ifIndex int, serviceName, regType, domain string)

A closure that is called when a service has been updated. found is true if a service has been discoverd, false if it has been removed. flags may be dnssd.MORE_COMING. ifIndex the index of the interface where the service was discovered. It should be passed to dnssd.Resolve. serviceName The name of the service. regType The registration type of the service, same as regType used in call to Browse. domain The domain the service was discovered on.

Jump to

Keyboard shortcuts

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