Code Monkey home page Code Monkey logo

go-avahi's People

Contributors

alexpevzner avatar andytzuen avatar derandereandi avatar makon avatar mhill-holoplot avatar phhusson avatar svenfoo avatar zonque avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-avahi's Issues

infinite loop on bus loss

hi,

it seems that the avahi Server signal handler in https://github.com/holoplot/go-avahi/blob/master/server.go#L50 will check for the closure of the dbus Signal channel, but if it is closed, it simply continues the loop. the loop isn't cleaned up until an explicit Server.Close().

this leads to the inner signal handler spinning tightly on select if one did not call Close on dbus connection loss. how are users of this library expected to handle bus loss? for now my best guess is that a caller needs to register their own Signal channel to the dbus Conn and wait for it to close, and then Close the avahi Server. is that right? this seems like a big footgun.

in the following example we spin forever inside of ServerNew's anonymous function, unless you uncomment the two lines in the select{} with the explicit Server.Close() triggered by the dbus.Signal channel closure.

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)

	// Register a DBus signal handler
	sig := make(chan *dbus.Signal)
	conn.Signal(sig)

	// Terminate the dbus connection, or otherwise simulate loss of the bus (e.g., dbus restarted).
	log.Println("Conn.Close():", conn.Close())

	doit := true
	for doit {
		select {
		case _, ok := <-sig:
			if !ok {
				//server.Close()
				//doit = false
			}
		}
	}
}

Handling avahi-daemon restarts for announced services

It seems that if avahi-daemon has been restarted and therefore service registration is lost, go-avahi does not currently handle such events. Am I right? And if yes, what is the most straightforward way to handle such event in order to update/re-add the service on avahi-daemon?

Service.Port overflows if Port > 32767

Hi,

Service.Port is defined as int16, but TCP port number can be larger that 32767. At this case, Service.Port becomes negative.

Please, redefine it as uint16 or int.

How to create multiple ServiceBrowser instances with one server

Hi,
I would like to write a go program which can search for multiple services in parallel (with the same service name as well as with different names). For that purpose I made some tests to get familiar with this library:

func searchService(sb *avahi.ServiceBrowser, srv *avahi.Server, t int) (avahi.Service, error) {
	var s avahi.Service
	for {
		select {
		case s = <-sb.AddChannel:
			s, err := srv.ResolveService(s.Interface, s.Protocol, s.Name,
				s.Type, s.Domain, avahi.ProtoUnspec, 0)
			if err != nil {
				return s, err
			}
			return s, err
		case <-time.After(time.Duration(t) * time.Second):
			err := errors.New("could not find instance or service")
			return s, err
		}
	}
}

func main() {
	serviceName := "_service1._tcp"
	serviceName2 := "_service2._tcp"

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

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

	s, err := searchService(sb, server, 3)
	if err != nil {
		log.Fatalf("searchService() failed: %v", err)
	}
        fmt.Println(s)

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

	fmt.Println("sb2 created!")

	s2, err := searchService(sb2, server, 3)
	if err != nil {
		log.Fatalf("searchService() failed: %v", err)
	}

	fmt.Println(s2)

I got never the output "sb2 created". The second call of ServiceBrowserNew stucks in c.mutex.Lock(), because the go routine in ServerNew hangs in obj.dispatchSignal(signal).
Is it not intended to have multiple ServiceBrowser per server?

Thank you in advance :)

Deadlock around ServiceBrowserNew

On my Debian stretch system server.ServiceBrowserNew() does often not return, about 9 out of 10 times.
It blocks at err := c.object.Call(c.interfaceForMember("ServiceBrowserNew"), 0, iface, protocol, serviceType, domain, flags).Store(&o) with c.mutex.Lock() held.

Do you have an idea what could cause this?

ServerNew uses invalid interface name

I just realized that calling ServerNew tries to add match with an invalid interface name 'org.freedesktop.Avahi.*'. I guess the * is not valid.

go-avahi/server.go

Lines 35 to 45 in c53ad34

func ServerNew(conn *dbus.Conn) (*Server, error) {
c := new(Server)
c.conn = conn
c.object = conn.Object("org.freedesktop.Avahi", dbus.ObjectPath("/"))
c.signalChannel = make(chan *dbus.Signal, 10)
c.quitChannel = make(chan struct{})
c.conn.Signal(c.signalChannel)
c.conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, "type='signal',interface='org.freedesktop.Avahi.*'")
c.signalEmitters = make(map[dbus.ObjectPath]signalEmitter)

Results from busctl monitor:

Type=method_call  Endian=l  Flags=0  Version=1  Priority=0 Cookie=3
  Sender=:1.981  Destination=org.freedesktop.DBus  Path=/org/freedesktop/DBus  Interface=org.freedesktop.DBus  Member=AddMatch
  UniqueName=:1.981
  MESSAGE "s" {
          STRING "type='signal',interface='org.freedesktop.Avahi.*'";
  };

‣ Type=error  Endian=l  Flags=1  Version=1  Priority=0 Cookie=5  ReplyCookie=3
  Sender=org.freedesktop.DBus  Destination=:1.981
  ErrorName=org.freedesktop.DBus.Error.MatchRuleInvalid  ErrorMessage="Interface name 'org.freedesktop.Avahi.*' is invalid
"
  MESSAGE "s" {
          STRING "Interface name 'org.freedesktop.Avahi.*' is invalid
";
  };

Create Release

Any chance to upgrade the dbus v5 dependency to v5.0.4 and create a tag for go-avahi? e.g. v1.0.0?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.