avahi

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2022 License: MIT Imports: 3 Imported by: 15

README

Golang bindings for Avahi

Avahi is an implementation of the mDNS protocol. Refer to the Wikipedia article, the website and the GitHub project for further information.

This Go package provides bindings for DBus interfaces exposed by the Avahi daemon.

Install

Install the package like this:

go get https://github.com/holoplot/go-avahi

And then use it in your source code.

import "github.com/holoplot/go-avahi"

Examples

Below are some examples to illustrate the usage of this package. Note that you will need to have a working Avahi installation.

Browsing and resolving

package main

import (
	"log"

	"github.com/godbus/dbus/v5"
	"github.com/holoplot/go-avahi"
)

func main() {
	conn, err := dbus.SystemBus()
	if err != nil {
		log.Fatalf("Cannot get system bus: %v", err)
	}

	server, err := avahi.ServerNew(conn)
	if err != nil {
		log.Fatalf("Avahi new failed: %v", err)
	}

	host, err := server.GetHostName()
	if err != nil {
		log.Fatalf("GetHostName() failed: %v", err)
	}
	log.Println("GetHostName()", host)

	fqdn, err := server.GetHostNameFqdn()
	if err != nil {
		log.Fatalf("GetHostNameFqdn() failed: %v", err)
	}
	log.Println("GetHostNameFqdn()", fqdn)

	s, err := server.GetAlternativeHostName(host)
	if err != nil {
		log.Fatalf("GetAlternativeHostName() failed: %v", err)
	}
	log.Println("GetAlternativeHostName()", s)

	i, err := server.GetAPIVersion()
	if err != nil {
		log.Fatalf("GetAPIVersion() failed: %v", err)
	}
	log.Println("GetAPIVersion()", i)

	hn, err := server.ResolveHostName(avahi.InterfaceUnspec, avahi.ProtoUnspec, fqdn, avahi.ProtoUnspec, 0)
	if err != nil {
		log.Fatalf("ResolveHostName() failed: %v", err)
	}
	log.Println("ResolveHostName:", hn)

	db, err := server.DomainBrowserNew(avahi.InterfaceUnspec, avahi.ProtoUnspec, "", avahi.DomainBrowserTypeBrowseDefault, 0)
	if err != nil {
		log.Fatalf("DomainBrowserNew() failed: %v", err)
	}

	stb, err := server.ServiceTypeBrowserNew(avahi.InterfaceUnspec, avahi.ProtoUnspec, "local", 0)
	if err != nil {
		log.Fatalf("ServiceTypeBrowserNew() failed: %v", err)
	}

	sb, err := server.ServiceBrowserNew(avahi.InterfaceUnspec, avahi.ProtoUnspec, "_my-nifty-service._tcp", "local", 0)
	if err != nil {
		log.Fatalf("ServiceBrowserNew() failed: %v", err)
	}

	sr, err := server.ServiceResolverNew(avahi.InterfaceUnspec, avahi.ProtoUnspec, "", "_my-nifty-service._tcp", "local", avahi.ProtoUnspec, 0)
	if err != nil {
		log.Fatalf("ServiceResolverNew() failed: %v", err)
	}

	var domain avahi.Domain
	var service avahi.Service
	var serviceType avahi.ServiceType

	for {
		select {
		case domain = <-db.AddChannel:
			log.Println("DomainBrowser ADD: ", domain)
		case domain = <-db.RemoveChannel:
			log.Println("DomainBrowser REMOVE: ", domain)
		case serviceType = <-stb.AddChannel:
			log.Println("ServiceTypeBrowser ADD: ", serviceType)
		case serviceType = <-stb.RemoveChannel:
			log.Println("ServiceTypeBrowser REMOVE: ", serviceType)
		case service = <-sb.AddChannel:
			log.Println("ServiceBrowser ADD: ", service)

			service, err := server.ResolveService(service.Interface, service.Protocol, service.Name,
				service.Type, service.Domain, avahi.ProtoUnspec, 0)
			if err == nil {
				log.Println(" RESOLVED >>", service.Address)
			}
		case service = <-sb.RemoveChannel:
			log.Println("ServiceBrowser REMOVE: ", service)
		case service = <-sr.FoundChannel:
			log.Println("ServiceResolver FOUND: ", service)
		}
	}
}

Publishing

package main

import (
	"log"

	"github.com/godbus/dbus/v5"
	"github.com/holoplot/go-avahi"
)

func main() {
	conn, err := dbus.SystemBus()
	if err != nil {
		log.Fatalf("Cannot get system bus: %v", err)
	}

	a, err := avahi.ServerNew(conn)
	if err != nil {
		log.Fatalf("Avahi new failed: %v", err)
	}

	eg, err := a.EntryGroupNew()
	if err != nil {
		log.Fatalf("EntryGroupNew() failed: %v", err)
	}

	hostname, err := a.GetHostName()
	if err != nil {
		log.Fatalf("GetHostName() failed: %v", err)
	}

	fqdn, err := a.GetHostNameFqdn()
	if err != nil {
		log.Fatalf("GetHostNameFqdn() failed: %v", err)
	}

	err = eg.AddService(avahi.InterfaceUnspec, avahi.ProtoUnspec, 0, hostname, "_my-nifty-service._tcp", "local", fqdn, 1234, nil)
	if err != nil {
		log.Fatalf("AddService() failed: %v", err)
	}

	err = eg.Commit()
	if err != nil {
		log.Fatalf("Commit() failed: %v", err)
	}

	log.Println("Entry published. Hit ^C to exit.")

	for {
		select {}
	}
}

MIT License

See file LICENSE for details.

Documentation

Index

Constants

View Source
const (
	// DomainBrowserTypeBrowse - Browse for a list of available browsing domains
	DomainBrowserTypeBrowse = 0
	// DomainBrowserTypeBrowseDefault - Browse for the default browsing domain
	DomainBrowserTypeBrowseDefault = 1
	// DomainBrowserTypeRegister - Browse for a list of available registering domains
	DomainBrowserTypeRegister = 2
	// DomainBrowserTypeRegisterDefault - Browse for the default registering domain
	DomainBrowserTypeRegisterDefault = 3
	// DomainBrowserTypeBrowseLegacy - Legacy browse domain - see DNS-SD spec for more information
	DomainBrowserTypeBrowseLegacy = 4
)
View Source
const (
	// EntryGroupUncommited - The group has not yet been commited, the user must still call Commit()
	EntryGroupUncommited = 0
	// EntryGroupRegistering - The entries of the group are currently being registered
	EntryGroupRegistering = 1
	// EntryGroupEstablished - The entries have successfully been established
	EntryGroupEstablished = 2
	// EntryGroupCollision - A name collision for one of the entries in the group has been detected, the entries have been withdrawn
	EntryGroupCollision = 3
	// EntryGroupFailure - Some kind of failure happened, the entries have been withdrawn
	EntryGroupFailure = 4
)
View Source
const (
	// ServerInvalid - Invalid state (initial)
	ServerInvalid = 0
	// ServerRegistering - Host RRs are being registered
	ServerRegistering = 1
	// ServerRunning - All host RRs have been established
	ServerRunning = 2
	// ServerCollision - There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via SetHostname()
	ServerCollision = 3
	// ServerFailure - Some fatal failure happened, the server is unable to proceed
	ServerFailure = 4
)
View Source
const (
	// ProtoInet - IPv4
	ProtoInet = 0
	// ProtoInet6 - IPv6
	ProtoInet6 = 1
	// ProtoUnspec - Unspecified/all protocol(s)
	ProtoUnspec = -1
)
View Source
const (
	// PublishUnique - The RRset is intended to be unique
	PublishUnique = 1
	// PublishNoProbe - Though the RRset is intended to be unique no probes shall be sent
	PublishNoProbe = 2
	// PublishNoAnnouce - Do not announce this RR to other hosts
	PublishNoAnnouce = 4
	// PublishAllowMultiple - Allow multiple local records of this type, even if they are intended to be unique
	PublishAllowMultiple = 8
	// PublishNoReverse - don't create a reverse (PTR) entry
	PublishNoReverse = 16
	// PublishNoCookie - do not implicitly add the local service cookie to TXT data
	PublishNoCookie = 32
	// PublishUpdate - Update existing records instead of adding new ones
	PublishUpdate = 64
	// PublishUseWideArea - Register the record using wide area DNS (i.e. unicast DNS update)
	PublishUseWideArea = 128
	// PublishUseMulticast - Register the record using multicast DNS
	PublishUseMulticast = 256
)
View Source
const (
	// LookupUseWideArea - Force lookup via wide area DNS
	LookupUseWideArea = 1
	// LookupUseMulticast - Force lookup via multicast DNS
	LookupUseMulticast = 2
	// LookupNoTXT - When doing service resolving, don't lookup TXT record
	LookupNoTXT = 4
	// LookupNoAddreess - When doing service resolving, don't lookup A/AAAA record
	LookupNoAddreess = 8
)
View Source
const (
	// LookupResultCached - This response originates from the cache
	LookupResultCached = 1
	// LookupResultWideArea - This response originates from wide area DNS
	LookupResultWideArea = 2
	// LookupResultMulticast  - This response originates from multicast DNS
	LookupResultMulticast = 4
	// LookupResultLocal - This record/service resides on and was announced by the local host. Only available in service and record browsers and only on AVAHI_BROWSER_NEW.
	LookupResultLocal = 8
	// LookupResultOurOwn - This service belongs to the same local client as the browser object. Only available in avahi-client, and only for service browsers and only on AVAHI_BROWSER_NEW.
	LookupResultOurOwn = 16
	// LookupResultStatic - The returned data has been defined statically by some configuration option
	LookupResultStatic = 32
)
View Source
const (
	// InterfaceUnspec - Unspecified/all interface(s)
	InterfaceUnspec = -1
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Address

type Address struct {
	Interface int32
	Protocol  int32
	Aprotocol int32
	Address   string
	Name      string
	Flags     uint32
}

Address ...

type AddressResolver

type AddressResolver struct {
	FoundChannel chan Address
	// contains filtered or unexported fields
}

An AddressResolver resolves Address to IP addresses

func AddressResolverNew

func AddressResolverNew(conn *dbus.Conn, path dbus.ObjectPath) (*AddressResolver, error)

AddressResolverNew creates a new AddressResolver

type Domain

type Domain struct {
	Interface int32
	Protocol  int32
	Domain    string
	Flags     uint32
}

Domain ...

type DomainBrowser

type DomainBrowser struct {
	AddChannel    chan Domain
	RemoveChannel chan Domain
	// contains filtered or unexported fields
}

A DomainBrowser is used to browse for mDNS domains

func DomainBrowserNew

func DomainBrowserNew(conn *dbus.Conn, path dbus.ObjectPath) (*DomainBrowser, error)

DomainBrowserNew returns a new domain browser

type EntryGroup

type EntryGroup struct {
	StateChangeChannel chan EntryGroupState
	// contains filtered or unexported fields
}

An EntryGroup describes a group of records for services

func EntryGroupNew

func EntryGroupNew(conn *dbus.Conn, path dbus.ObjectPath) (*EntryGroup, error)

EntryGroupNew creates a new entry group

func (*EntryGroup) AddAddress

func (c *EntryGroup) AddAddress(iface, protocol int32, flags uint32, name, address string) error

AddAddress add a host/address pair to the entry group

func (*EntryGroup) AddRecord

func (c *EntryGroup) AddRecord(iface, protocol int32, flags uint32, name string, class, recordType uint16, ttl uint32, rdata []byte) error

AddRecord adds an arbitrary record. I hope you know what you do.

func (*EntryGroup) AddService

func (c *EntryGroup) AddService(iface, protocol int32, flags uint32, name, serviceType, domain, host string, port uint16, txt [][]byte) error

AddService adds a service. Takes a list of TXT record strings as last arguments. Please note that this service is not announced on the network before Commit() is called.

func (*EntryGroup) AddServiceSubtype added in v1.0.1

func (c *EntryGroup) AddServiceSubtype(iface, protocol int32, flags uint32, name, serviceType, domain, subtype string) error

AddServiceSubtype adds a subtype for a service. The service should already be existent in the entry group. You may add as many subtypes for a service as you wish.

func (*EntryGroup) Commit

func (c *EntryGroup) Commit() error

Commit an AvahiEntryGroup. The entries in the entry group are now registered on the network. Commiting empty entry groups is considered an error.

func (*EntryGroup) GetState

func (c *EntryGroup) GetState() (int32, error)

GetState gets an AvahiEntryGroup's state

func (*EntryGroup) IsEmpty

func (c *EntryGroup) IsEmpty() (bool, error)

IsEmpty checks if an AvahiEntryGroup is empty

func (*EntryGroup) Reset

func (c *EntryGroup) Reset() error

Reset an AvahiEntryGroup. This takes effect immediately.

func (*EntryGroup) UpdateServiceTxt

func (c *EntryGroup) UpdateServiceTxt(iface, protocol int32, flags uint32, name, serviceType, domain string, txt [][]byte) error

UpdateServiceTxt apdates a TXT record for an existing service. The service should already be existent in the entry group.

type EntryGroupState

type EntryGroupState struct {
	State int32
	Error string
}

An EntryGroupState describes the current state of an entry group

type HostName

type HostName struct {
	Interface int32
	Protocol  int32
	Name      string
	Aprotocol int32
	Address   string
	Flags     uint32
}

HostName ...

type HostNameResolver

type HostNameResolver struct {
	FoundChannel chan HostName
	// contains filtered or unexported fields
}

A HostNameResolver can resolve host names

func HostNameResolverNew

func HostNameResolverNew(conn *dbus.Conn, path dbus.ObjectPath) (*HostNameResolver, error)

HostNameResolverNew returns a new HostNameResolver

type Record

type Record struct {
	Interface int32
	Protocol  int32
	Name      string
	Class     int16
	Type      int16
	Rdata     []byte
	Flags     uint32
}

Record ...

type RecordBrowser

type RecordBrowser struct {
	AddChannel    chan Record
	RemoveChannel chan Record
	// contains filtered or unexported fields
}

A RecordBrowser is a browser for mDNS records

func RecordBrowserNew

func RecordBrowserNew(conn *dbus.Conn, path dbus.ObjectPath) (*RecordBrowser, error)

RecordBrowserNew creates a new mDNS record browser

type Server

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

A Server is the cental object of an Avahi connection

func ServerNew

func ServerNew(conn *dbus.Conn) (*Server, error)

ServerNew returns a new Server object

func (*Server) AddressResolverFree

func (c *Server) AddressResolverFree(r *AddressResolver)

AddressResolverFree ...

func (*Server) AddressResolverNew

func (c *Server) AddressResolverNew(iface, protocol int32, address string, flags uint32) (*AddressResolver, error)

AddressResolverNew ...

func (*Server) Close

func (c *Server) Close()

Close closes the connection to a server

func (*Server) DomainBrowserFree

func (c *Server) DomainBrowserFree(r *DomainBrowser)

DomainBrowserFree ...

func (*Server) DomainBrowserNew

func (c *Server) DomainBrowserNew(iface, protocol int32, domain string, btype int32, flags uint32) (*DomainBrowser, error)

DomainBrowserNew ...

func (*Server) EntryGroupFree

func (c *Server) EntryGroupFree(r *EntryGroup)

EntryGroupFree frees an entry group and releases its resources on the service

func (*Server) EntryGroupNew

func (c *Server) EntryGroupNew() (*EntryGroup, error)

EntryGroupNew returns a new and empty EntryGroup

func (*Server) GetAPIVersion

func (c *Server) GetAPIVersion() (int32, error)

GetAPIVersion ...

func (*Server) GetAlternativeHostName

func (c *Server) GetAlternativeHostName(name string) (string, error)

GetAlternativeHostName ...

func (*Server) GetAlternativeServiceName

func (c *Server) GetAlternativeServiceName(name string) (string, error)

GetAlternativeServiceName ...

func (*Server) GetDomainName

func (c *Server) GetDomainName() (string, error)

GetDomainName ...

func (*Server) GetHostName

func (c *Server) GetHostName() (string, error)

GetHostName ...

func (*Server) GetHostNameFqdn

func (c *Server) GetHostNameFqdn() (string, error)

GetHostNameFqdn ...

func (*Server) GetLocalServiceCookie

func (c *Server) GetLocalServiceCookie() (int32, error)

GetLocalServiceCookie ...

func (*Server) GetNetworkInterfaceIndexByName

func (c *Server) GetNetworkInterfaceIndexByName(name string) (int32, error)

GetNetworkInterfaceIndexByName -...

func (*Server) GetNetworkInterfaceNameByIndex

func (c *Server) GetNetworkInterfaceNameByIndex(index int32) (string, error)

GetNetworkInterfaceNameByIndex ...

func (*Server) GetState

func (c *Server) GetState() (int32, error)

GetState ...

func (*Server) GetVersionString

func (c *Server) GetVersionString() (string, error)

GetVersionString ...

func (*Server) HostNameResolverNew

func (c *Server) HostNameResolverNew(iface, protocol int32, name string, aprotocol int32, flags uint32) (*HostNameResolver, error)

HostNameResolverNew ...

func (*Server) IsNSSSupportAvailable

func (c *Server) IsNSSSupportAvailable() (bool, error)

IsNSSSupportAvailable ...

func (*Server) RecordBrowserFree

func (c *Server) RecordBrowserFree(r *RecordBrowser)

RecordBrowserFree ...

func (*Server) RecordBrowserNew

func (c *Server) RecordBrowserNew(iface, protocol int32, name string, class int16, recordType int16, flags uint32) (*RecordBrowser, error)

RecordBrowserNew ...

func (*Server) ResolveAddress

func (c *Server) ResolveAddress(iface, protocol int32, address string, flags uint32) (reply Address, err error)

ResolveAddress ...

func (*Server) ResolveHostName

func (c *Server) ResolveHostName(iface, protocol int32, name string, aprotocol int32, flags uint32) (reply HostName, err error)

ResolveHostName ...

func (*Server) ResolveService

func (c *Server) ResolveService(iface, protocol int32, name, serviceType, domain string, aprotocol int32, flags uint32) (reply Service, err error)

ResolveService ...

func (*Server) ServiceBrowserFree

func (c *Server) ServiceBrowserFree(r *ServiceBrowser)

ServiceBrowserFree ...

func (*Server) ServiceBrowserNew

func (c *Server) ServiceBrowserNew(iface, protocol int32, serviceType string, domain string, flags uint32) (*ServiceBrowser, error)

ServiceBrowserNew ...

func (*Server) ServiceResolverFree

func (c *Server) ServiceResolverFree(r *ServiceResolver)

ServiceResolverFree ...

func (*Server) ServiceResolverNew

func (c *Server) ServiceResolverNew(iface, protocol int32, name, serviceType, domain string, aprotocol int32, flags uint32) (*ServiceResolver, error)

ServiceResolverNew ...

func (*Server) ServiceTypeBrowserFree

func (c *Server) ServiceTypeBrowserFree(r *ServiceTypeBrowser)

ServiceTypeBrowserFree ...

func (*Server) ServiceTypeBrowserNew

func (c *Server) ServiceTypeBrowserNew(iface, protocol int32, domain string, flags uint32) (*ServiceTypeBrowser, error)

ServiceTypeBrowserNew ...

func (*Server) SetServerName

func (c *Server) SetServerName(name string) error

SetServerName ...

type Service

type Service struct {
	Interface int32
	Protocol  int32
	Name      string
	Type      string
	Domain    string
	Host      string
	Aprotocol int32
	Address   string
	Port      uint16
	Txt       [][]byte
	Flags     uint32
}

Service ...

type ServiceBrowser

type ServiceBrowser struct {
	AddChannel    chan Service
	RemoveChannel chan Service
	// contains filtered or unexported fields
}

A ServiceBrowser browses for mDNS services

func ServiceBrowserNew

func ServiceBrowserNew(conn *dbus.Conn, path dbus.ObjectPath) (*ServiceBrowser, error)

ServiceBrowserNew creates a new browser for mDNS records

type ServiceResolver

type ServiceResolver struct {
	FoundChannel chan Service
	// contains filtered or unexported fields
}

A ServiceResolver resolves mDNS services to IP addresses

func ServiceResolverNew

func ServiceResolverNew(conn *dbus.Conn, path dbus.ObjectPath) (*ServiceResolver, error)

ServiceResolverNew returns a new mDNS service resolver

type ServiceType

type ServiceType struct {
	Interface int32
	Protocol  int32
	Type      string
	Domain    string
	Flags     uint32
}

ServiceType ...

type ServiceTypeBrowser

type ServiceTypeBrowser struct {
	AddChannel    chan ServiceType
	RemoveChannel chan ServiceType
	// contains filtered or unexported fields
}

A ServiceTypeBrowser is used to browser the mDNS network for services of a specific type

func ServiceTypeBrowserNew

func ServiceTypeBrowserNew(conn *dbus.Conn, path dbus.ObjectPath) (*ServiceTypeBrowser, error)

ServiceTypeBrowserNew creates a new browser for mDNS service types

Jump to

Keyboard shortcuts

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