From 1e642e955496ccee198251b16e1435406a2f133f Mon Sep 17 00:00:00 2001 From: Eric Daniels Date: Thu, 19 Jan 2023 12:56:48 -0500 Subject: [PATCH] Properly add fix from https://github.com/grandcat/zeroconf/pull/110 --- client.go | 24 ++++++++++++++++++++++++ server.go | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index 93de3de0..4d8e1ceb 100644 --- a/client.go +++ b/client.go @@ -4,7 +4,9 @@ import ( "context" "errors" "fmt" + "log" "net" + "runtime" "strings" "sync" "time" @@ -511,16 +513,38 @@ func (c *client) sendQuery(msg *dns.Msg) error { return err } if c.ipv4conn != nil { + // See https://pkg.go.dev/golang.org/x/net/ipv4#pkg-note-BUG + // As of Golang 1.18.4 + // On Windows, the ControlMessage for ReadFrom and WriteTo methods of PacketConn is not implemented. var wcm ipv4.ControlMessage for ifi := range c.ifaces { wcm.IfIndex = c.ifaces[ifi].Index + switch runtime.GOOS { + case "darwin", "ios", "linux": + wcm.IfIndex = c.ifaces[ifi].Index + default: + if err := c.ipv4conn.SetMulticastInterface(&c.ifaces[ifi]); err != nil { + log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) + } + } c.ipv4conn.WriteTo(buf, &wcm, ipv4Addr) } } if c.ipv6conn != nil { + // See https://pkg.go.dev/golang.org/x/net/ipv6#pkg-note-BUG + // As of Golang 1.18.4 + // On Windows, the ControlMessage for ReadFrom and WriteTo methods of PacketConn is not implemented. var wcm ipv6.ControlMessage for ifi := range c.ifaces { wcm.IfIndex = c.ifaces[ifi].Index + switch runtime.GOOS { + case "darwin", "ios", "linux": + wcm.IfIndex = c.ifaces[ifi].Index + default: + if err := c.ipv6conn.SetMulticastInterface(&c.ifaces[ifi]); err != nil { + log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) + } + } c.ipv6conn.WriteTo(buf, &wcm, ipv6Addr) } } diff --git a/server.go b/server.go index 01c9ff66..b8ef489f 100644 --- a/server.go +++ b/server.go @@ -8,6 +8,7 @@ import ( "math/rand" "net" "os" + "runtime" "strings" "sync" "time" @@ -561,7 +562,7 @@ func (s *Server) serviceTypeName(resp *dns.Msg, ttl uint32) { } // Perform probing & announcement -//TODO: implement a proper probing & conflict resolution +// TODO: implement a proper probing & conflict resolution func (s *Server) probe() { q := new(dns.Msg) q.SetQuestion(s.service.ServiceInstanceName(), dns.TypePTR) @@ -765,26 +766,66 @@ func (s *Server) multicastResponse(msg *dns.Msg, ifIndex int) error { return err } if s.ipv4conn != nil { + // See https://pkg.go.dev/golang.org/x/net/ipv4#pkg-note-BUG + // As of Golang 1.18.4 + // On Windows, the ControlMessage for ReadFrom and WriteTo methods of PacketConn is not implemented. var wcm ipv4.ControlMessage if ifIndex != 0 { wcm.IfIndex = ifIndex + switch runtime.GOOS { + case "darwin", "ios", "linux": + wcm.IfIndex = ifIndex + default: + iface, _ := net.InterfaceByIndex(ifIndex) + if err := s.ipv4conn.SetMulticastInterface(iface); err != nil { + log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) + } + } s.ipv4conn.WriteTo(buf, &wcm, ipv4Addr) } else { for _, intf := range s.ifaces { wcm.IfIndex = intf.Index + switch runtime.GOOS { + case "darwin", "ios", "linux": + wcm.IfIndex = intf.Index + default: + if err := s.ipv4conn.SetMulticastInterface(&intf); err != nil { + log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) + } + } s.ipv4conn.WriteTo(buf, &wcm, ipv4Addr) } } } if s.ipv6conn != nil { + // See https://pkg.go.dev/golang.org/x/net/ipv6#pkg-note-BUG + // As of Golang 1.18.4 + // On Windows, the ControlMessage for ReadFrom and WriteTo methods of PacketConn is not implemented. var wcm ipv6.ControlMessage if ifIndex != 0 { wcm.IfIndex = ifIndex + switch runtime.GOOS { + case "darwin", "ios", "linux": + wcm.IfIndex = ifIndex + default: + iface, _ := net.InterfaceByIndex(ifIndex) + if err := s.ipv6conn.SetMulticastInterface(iface); err != nil { + log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) + } + } s.ipv6conn.WriteTo(buf, &wcm, ipv6Addr) } else { for _, intf := range s.ifaces { wcm.IfIndex = intf.Index + switch runtime.GOOS { + case "darwin", "ios", "linux": + wcm.IfIndex = intf.Index + default: + if err := s.ipv6conn.SetMulticastInterface(&intf); err != nil { + log.Printf("[WARN] mdns: Failed to set multicast interface: %v", err) + } + } s.ipv6conn.WriteTo(buf, &wcm, ipv6Addr) } }