make sure multicast listeners are stopped and started if an address is changed, such as by joining a different wifi network

This commit is contained in:
Arceliar 2019-03-12 21:59:39 -05:00
parent cc0c188dc9
commit 3f1696c2b6

View file

@ -118,23 +118,13 @@ func (m *multicast) announce() {
panic(err) panic(err)
} }
for { for {
// Get the allowed interfaces and any matching link-local addresses
interfaces := m.interfaces() interfaces := m.interfaces()
// There might be interfaces that we configured listeners for but are no addresses := make(map[string]net.IPAddr)
// longer up - if that's the case then we should stop the listeners
for name, listener := range m.listeners {
if _, ok := interfaces[name]; !ok {
listener.stop <- true
delete(m.listeners, name)
m.core.log.Debugln("No longer multicasting on", name)
}
}
// Now that we have a list of valid interfaces from the operating system,
// we can start checking if we can send multicasts on them
for _, iface := range interfaces { for _, iface := range interfaces {
// Find interface addresses
addrs, err := iface.Addrs() addrs, err := iface.Addrs()
if err != nil { if err != nil {
panic(err) m.core.log.Debugln("Failed to get addresses for interface", iface.Name, "due to error:", err)
} }
for _, addr := range addrs { for _, addr := range addrs {
addrIP, _, _ := net.ParseCIDR(addr.String()) addrIP, _, _ := net.ParseCIDR(addr.String())
@ -146,24 +136,43 @@ func (m *multicast) announce() {
if !addrIP.IsLinkLocalUnicast() { if !addrIP.IsLinkLocalUnicast() {
continue continue
} }
// Join the multicast group ipAddr := net.IPAddr{
IP: addrIP,
Zone: iface.Name,
}
addresses[ipAddr.String()] = ipAddr
}
}
// There might be interfaces that we configured listeners for but are no
// longer up - if that's the case then we should stop the listeners
for name, listener := range m.listeners {
if _, ok := addresses[name]; !ok {
listener.stop <- true
delete(m.listeners, name)
m.core.log.Debugln("No longer multicasting on", name)
}
}
// Now that we have a list of valid addresses from the operating system,
// we can start checking if we can send multicasts on them
for addr, ipAddr := range addresses {
iface := interfaces[ipAddr.Zone]
m.sock.JoinGroup(&iface, groupAddr) m.sock.JoinGroup(&iface, groupAddr)
// Try and see if we already have a TCP listener for this interface // Try and see if we already have a TCP listener for this interface
var listener *tcpListener var listener *tcpListener
if l, ok := m.listeners[iface.Name]; !ok || l.listener == nil { if l, ok := m.listeners[addr]; !ok || l.listener == nil {
// No listener was found - let's create one // No listener was found - let's create one
listenaddr := fmt.Sprintf("[%s%%%s]:%d", addrIP, iface.Name, m.listenPort) listenaddr := fmt.Sprintf("[%s%%%s]:%d", ipAddr.IP.String(), ipAddr.Zone, m.listenPort)
if li, err := m.core.link.tcp.listen(listenaddr); err == nil { if li, err := m.core.link.tcp.listen(listenaddr); err == nil {
m.core.log.Debugln("Started multicasting on", iface.Name) m.core.log.Debugln("Started multicasting on", iface.Name, "with address", addr)
// Store the listener so that we can stop it later if needed // Store the listener so that we can stop it later if needed
m.listeners[iface.Name] = li m.listeners[addr] = li
listener = li listener = li
} else { } else {
m.core.log.Warnln("Not multicasting on", iface.Name, "due to error:", err) m.core.log.Warnln("Not multicasting on", iface.Name, "with address", addr, "due to error:", err)
} }
} else { } else {
// An existing listener was found // An existing listener was found
listener = m.listeners[iface.Name] listener = m.listeners[addr]
} }
// Make sure nothing above failed for some reason // Make sure nothing above failed for some reason
if listener == nil { if listener == nil {
@ -179,7 +188,6 @@ func (m *multicast) announce() {
} }
break break
} }
}
time.Sleep(time.Second * 15) time.Sleep(time.Second * 15)
} }
} }