zeroconf icon indicating copy to clipboard operation
zeroconf copied to clipboard

Fix client multicast sending on Windows

Open davidflowerday opened this issue 5 years ago • 8 comments

I'm attempting to use go-chromecast on Windows which leverages this library. Unfortunately mDNS wasn't working. I was able to fix it by replacing the code that used ControlMessage in WriteTo() with a call to SetMulticastInterface() instead. I think this may be related to issues #54 #69 and #75. I've tested this change on Windows and Linux and I will test on macOS shortly as well. I only changed client.go but it's possible a similar change is needed in server.go as well.

In the docs for the ipv4 package under Bugs there is this note:

On Windows, the ControlMessage for ReadFrom and WriteTo methods of PacketConn is not implemented.

Additionally, the ipv4 docs on Multicasting here show an example using SetMulticastInterface() as I've done in this PR which suggests to me that this is an OK way to handle this issue, but if you'd prefer something else I'd be happy to change it.

Thanks for making zeroconf and for considering this PR.

davidflowerday avatar Feb 04 '21 01:02 davidflowerday

Thanks for this contribution. Would you mind rebasing this Pr to latest master?

grandcat avatar Jul 05 '21 17:07 grandcat

I'm not sure about this. It might be worth doing on Windows only.

FYI I also opened PRs to golang to implement these methods on Windows, but they were not merged.

tmm1 avatar Jul 05 '21 18:07 tmm1

I know this is a bit old but it's still causing problems for me. I can work on making it Windows-only per @tmm1's suggestion if you prefer.

davidflowerday avatar Apr 13 '22 20:04 davidflowerday

I can confirm that @davidflowerday solution fixes this issue for me on windows. Before his changes I can only get mDns services that are registered locally on my computer, after his changes I can now see all mDns services on my local network. I do urge you to consider his changes.

I am running Windows 11 Go version 1.18.3

cpuchip avatar Jul 26 '22 19:07 cpuchip

a fix will probably need to be applied to https://github.com/grandcat/zeroconf/blob/master/server.go#L718 too since I cannot receive mDns message from my windows box across the network using this library but I can from off the shelf devices like _googlecast and _airplay devices.

cpuchip avatar Jul 26 '22 19:07 cpuchip

I have no experience in writing network safe go code here, but these changes worked for me to see services registered with this library across the network. Definitely some optimizations could be applied.... but the idea works.

wow code block isn't working... I'll try and post this as a PR later unless someone beats me to it.

`// multicastResponse us used to send a multicast response packet func (s *Server) multicastResponse(msg *dns.Msg, ifIndex int) error { buf, err := msg.Pack() if err != nil { return err } if s.ipv4conn != nil { var wcm ipv4.ControlMessage if ifIndex != 0 { iface, _ := net.InterfaceByIndex(ifIndex) if err := s.ipv4conn.SetMulticastInterface(iface); err != nil { log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) } wcm.IfIndex = ifIndex s.ipv4conn.WriteTo(buf, &wcm, ipv4Addr) } else { for _, intf := range s.ifaces { iface, _ := net.InterfaceByIndex(intf.Index) if err := s.ipv4conn.SetMulticastInterface(iface); err != nil { log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) continue } wcm.IfIndex = intf.Index s.ipv4conn.WriteTo(buf, &wcm, ipv4Addr) } } }

if s.ipv6conn != nil {
	var wcm ipv6.ControlMessage
	if ifIndex != 0 {
		iface, _ := net.InterfaceByIndex(ifIndex)
		if err := s.ipv6conn.SetMulticastInterface(iface); err != nil {
			log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err)
		}
		wcm.IfIndex = ifIndex
		s.ipv6conn.WriteTo(buf, &wcm, ipv6Addr)
	} else {
		for _, intf := range s.ifaces {
			iface, _ := net.InterfaceByIndex(intf.Index)
			if err := s.ipv6conn.SetMulticastInterface(iface); err != nil {
				log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err)
				continue
			}
			wcm.IfIndex = intf.Index
			s.ipv6conn.WriteTo(buf, &wcm, ipv6Addr)
		}
	}
}
return nil

}`

cpuchip avatar Jul 26 '22 23:07 cpuchip

I've opened up a new PR with platform specific changes https://github.com/grandcat/zeroconf/pull/110

cpuchip avatar Jul 27 '22 18:07 cpuchip

@davidflowerday I don't know if you just needed an active repo with this fix in it, but on my fork: https://github.com/cpuchip/zeroconf I went ahead and pulled in those changes to my master branch and tagged it v2.2.0 It's a mashup of grandcat/zeroconf master and libp2p/zeroconf master I've just barely started using it and it seems to be working alright on windows.

I honestly do not understand the inners of this library well at the moment, and your find with SetMulticastInterface was brilliant, I was pulling my hair our trying to get a project working on windows/linux. So thank you for that work.

cpuchip avatar Jul 29 '22 17:07 cpuchip

Superseded by https://github.com/grandcat/zeroconf/pull/110.

grandcat avatar Jan 21 '23 21:01 grandcat