Skip to content

Commit

Permalink
Merge pull request #32 from eelcocramer/fix-mcast-origin
Browse files Browse the repository at this point in the history
Fixes issue where the multicast is not send from the listen IP address
  • Loading branch information
clockworksoul committed Jul 22, 2018
2 parents a9b55e6 + ff1a2e5 commit 339e936
Showing 1 changed file with 36 additions and 5 deletions.
41 changes: 36 additions & 5 deletions membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,31 @@ func guessMulticastAddress() string {
return multicastAddress
}

// getListenInterface gets the network interface for the listen IP
func getListenInterface() (*net.Interface, error) {
ifaces, err := net.Interfaces()
if err == nil {
for _, iface := range ifaces {
addrs, err := iface.Addrs()
if err != nil {
logfWarn("Can not get addresses of interface %s", iface.Name)
continue
}
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
if err != nil {
continue
}
if ip.String() == GetListenIP().String() {
logfInfo("Found interface with listen IP: %s", iface.Name)
return &iface, nil
}
}
}
}
return nil, errors.New("Could not determine the interface of the listen IP address")
}

// Returns a random slice of valid ping/forward request targets; i.e., not
// this node, and not dead.
func getTargetNodes(count int, exclude ...*Node) []*Node {
Expand Down Expand Up @@ -346,7 +371,11 @@ func listenUDPMulticast(port int) error {
}

/* Now listen at selected port */
c, err := net.ListenMulticastUDP("udp", nil, listenAddress)
iface, err := getListenInterface()
if err != nil {
return err
}
c, err := net.ListenMulticastUDP("udp", iface, listenAddress)
if err != nil {
return err
}
Expand Down Expand Up @@ -402,14 +431,16 @@ func multicastAnnounce(addr string) error {
logError(err)
return err
}

laddr := &net.UDPAddr{
IP: GetListenIP(),
Port: 0,
}
for {
c, err := net.DialUDP("udp", nil, address)
c, err := net.DialUDP("udp", laddr, address)
if err != nil {
logError(err)
return err
}

// Compose and send the multicast announcement
msgBytes := encodeMulticastAnnounceBytes()
_, err = c.Write(msgBytes)
Expand All @@ -418,7 +449,7 @@ func multicastAnnounce(addr string) error {
return err
}

logfTrace("Sent announcement multicast to %v", fullAddr)
logfTrace("Sent announcement multicast from %v to %v", laddr, fullAddr)

if GetMulticastAnnounceIntervalSeconds() > 0 {
time.Sleep(time.Second * time.Duration(GetMulticastAnnounceIntervalSeconds()))
Expand Down

0 comments on commit 339e936

Please sign in to comment.