From a12b948350756e63b9c1a3acca45443436a3cb3f Mon Sep 17 00:00:00 2001 From: Red Daly Date: Thu, 9 Apr 2015 12:22:53 -0700 Subject: [PATCH 1/2] New option in server config: DisableMulticastLoopback. Setting this option to false (default) sets the IP_MULTICAST_LOOP socket option to true on the multicast sockets opened by the mDNS server. This is necessary for other sockets on the same machine to receive packets sent by the server and thus discover the service. --- server.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/server.go b/server.go index 55988c4..77be93f 100644 --- a/server.go +++ b/server.go @@ -7,6 +7,8 @@ import ( "strings" "sync" + "github.com/hashicorp/go.net/ipv4" + "github.com/hashicorp/go.net/ipv6" "github.com/miekg/dns" ) @@ -37,6 +39,12 @@ type Config struct { // interface. If not provided, the system default multicase interface // is used. Iface *net.Interface + + // Whether to set the IP_MULTICAST_LOOP socket option on the multicast sockets + // opened. Setting this to false allows mDNS clients on the same machine to + // discover the service. See + // http://stackoverflow.com/questions/1719156/is-there-a-way-to-test-multicast-ip-on-same-box + DisableMulticastLoopback bool } // mDNS server is used to listen for mDNS queries and respond if we @@ -55,9 +63,23 @@ type Server struct { // NewServer is used to create a new mDNS server from a config func NewServer(config *Config) (*Server, error) { // Create the listeners + // TODO(reddaly): Handle errors returned by ListenMulticastUDP ipv4List, _ := net.ListenMulticastUDP("udp4", config.Iface, ipv4Addr) ipv6List, _ := net.ListenMulticastUDP("udp6", config.Iface, ipv6Addr) + { + p := ipv4.NewPacketConn(ipv4List) + if err := p.SetMulticastLoopback(!config.DisableMulticastLoopback); err != nil { + return nil, err + } + } + { + p := ipv6.NewPacketConn(ipv6List) + if err := p.SetMulticastLoopback(!config.DisableMulticastLoopback); err != nil { + return nil, err + } + } + // Check if we have any listener if ipv4List == nil && ipv6List == nil { return nil, fmt.Errorf("No multicast listeners could be started") From 80d6231fdbd687ca14a58f62c3bd0290306da493 Mon Sep 17 00:00:00 2001 From: Red Daly Date: Tue, 21 Apr 2015 14:06:31 -0400 Subject: [PATCH 2/2] Only set multicast loopback property of valid connections in mdns server. --- server.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/server.go b/server.go index 77be93f..588ed6c 100644 --- a/server.go +++ b/server.go @@ -63,20 +63,27 @@ type Server struct { // NewServer is used to create a new mDNS server from a config func NewServer(config *Config) (*Server, error) { // Create the listeners - // TODO(reddaly): Handle errors returned by ListenMulticastUDP - ipv4List, _ := net.ListenMulticastUDP("udp4", config.Iface, ipv4Addr) - ipv6List, _ := net.ListenMulticastUDP("udp6", config.Iface, ipv6Addr) + ipv4List, err := net.ListenMulticastUDP("udp4", config.Iface, ipv4Addr) + if err != nil { + // TODO(reddaly): Handle this error beyond printing a log message. + log.Printf("[ERR] mdns: Failed to listen to IPv4 mdns multicast address: %v", err) + } + ipv6List, err := net.ListenMulticastUDP("udp6", config.Iface, ipv6Addr) + if err != nil { + // TODO(reddaly): Handle this error beyond printing a log message. + log.Printf("[ERR] mdns: Failed to listen to IPv6 mdns multicast address: %v", err) + } - { + if ipv4List != nil { p := ipv4.NewPacketConn(ipv4List) if err := p.SetMulticastLoopback(!config.DisableMulticastLoopback); err != nil { - return nil, err + return nil, fmt.Errorf("could not set multicast loopback attribute of ipv4 connection: %v", err) } } - { + if ipv6List != nil { p := ipv6.NewPacketConn(ipv6List) if err := p.SetMulticastLoopback(!config.DisableMulticastLoopback); err != nil { - return nil, err + return nil, fmt.Errorf("could not set multicast loopback attribute of ipv6 connection: %v", err) } }