From e171a36dab67ba4fef49324e644950778fd22eb2 Mon Sep 17 00:00:00 2001 From: Kazuki Sawada Date: Sun, 30 Jun 2019 21:52:07 +0900 Subject: [PATCH] beacon: use all interface --- beacon/beacon.go | 20 +------- beacon/service.go | 125 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 122 insertions(+), 23 deletions(-) diff --git a/beacon/beacon.go b/beacon/beacon.go index 2ad3480..a804a8d 100644 --- a/beacon/beacon.go +++ b/beacon/beacon.go @@ -23,24 +23,8 @@ var ( ) func StartService(g *echo.Group) { - go func() { - for { - ch := make(chan error) - go sendBeacon(ch) - logger.Println("Beacon sending goroutine has been started") - logger.Printf("Sending beacon failed: %v\n", <-ch) - close(ch) - } - }() - go func() { - for { - ch := make(chan error) - go recvBeacon(ch) - logger.Println("Beacon receiving goroutine has been started") - logger.Printf("Receiving beacon failed: %v\n", <-ch) - close(ch) - } - }() + go startSender() + go startReceiver() g.GET("/nodes", getNodes) g.DELETE("/node", deleteNode) diff --git a/beacon/service.go b/beacon/service.go index 6e26b5d..6839271 100644 --- a/beacon/service.go +++ b/beacon/service.go @@ -7,8 +7,95 @@ import ( "github.com/kaz/flos/messaging" ) -func sendBeacon(ch chan error) { - conn, err := net.Dial("udp", UDP_ADDR) +func getNIFs() ([]net.Interface, error) { + nifs, err := net.Interfaces() + if err != nil { + return nil, err + } + + result := []net.Interface{} + for _, nif := range nifs { + if nif.Flags&net.FlagUp == 0 { + continue + } + if nif.Flags&net.FlagMulticast == 0 { + continue + } + if nif.Flags&net.FlagLoopback != 0 { + continue + } + + result = append(result, nif) + } + + return result, nil +} +func getAddrs4(nif net.Interface) ([]net.IP, error) { + addrs, err := nif.Addrs() + if err != nil { + return nil, err + } + + result := []net.IP{} + for _, addr := range addrs { + var ip net.IP = nil + + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP.To4() + case *net.IPAddr: + ip = v.IP.To4() + } + + if ip != nil { + result = append(result, ip) + } + } + + return result, nil +} + +func startSender() { + nifs, err := getNIFs() + if err != nil { + logger.Printf("failed to get interfaces: %v\n", err) + return + } + + for _, nif := range nifs { + addrs, err := getAddrs4(nif) + if err != nil { + logger.Printf("failed to get addrs: %v\n", err) + continue + } + + for _, addr := range addrs { + laddr, err := net.ResolveUDPAddr("udp", addr.String()+":11239") + if err != nil { + logger.Printf("failed to resolve addr: %v\n", err) + continue + } + + go func(nif net.Interface, laddr net.UDPAddr) { + for { + ch := make(chan error) + go sendBeacon(ch, &laddr) + logger.Printf("sending (dev=%s)\n", nif.Name) + logger.Printf("send failed (dev=%s): %v\n", nif.Name, <-ch) + close(ch) + } + }(nif, *laddr) + } + } +} +func sendBeacon(ch chan error, laddr *net.UDPAddr) { + raddr, err := net.ResolveUDPAddr("udp", UDP_ADDR) + if err != nil { + ch <- err + return + } + + conn, err := net.DialUDP("udp", laddr, raddr) if err != nil { ch <- err return @@ -30,14 +117,42 @@ func sendBeacon(ch chan error) { } } -func recvBeacon(ch chan error) { - address, err := net.ResolveUDPAddr("udp", UDP_ADDR) +func startReceiver() { + nifs, err := getNIFs() + if err != nil { + logger.Printf("failed to get interfaces: %v\n", err) + return + } + + for _, nif := range nifs { + addrs, err := getAddrs4(nif) + if err != nil { + logger.Printf("failed to get addrs: %v\n", err) + continue + } + if len(addrs) == 0 { + continue + } + + go func(nif net.Interface) { + for { + ch := make(chan error) + go recvBeacon(ch, &nif) + logger.Printf("receiving (dev=%s)\n", nif.Name) + logger.Printf("receive failed (dev=%s): %v\n", nif.Name, <-ch) + close(ch) + } + }(nif) + } +} +func recvBeacon(ch chan error, nif *net.Interface) { + raddr, err := net.ResolveUDPAddr("udp", UDP_ADDR) if err != nil { ch <- err return } - listener, err := net.ListenMulticastUDP("udp", nil, address) + listener, err := net.ListenMulticastUDP("udp", nif, raddr) if err != nil { ch <- err return