From 55efa5f8bc5b2fde36606dcabf27ade4574aebed Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Thu, 29 Jun 2017 19:06:53 +0200 Subject: [PATCH] [TASK] split interfaces by listen, send multicast and send unicast (needed by babel) --- cmd/yanic-query/main.go | 7 ++++-- cmd/yanic/main.go | 8 ++++++- config_example.toml | 7 +++++- respond/collector.go | 53 ++++++++++++++++++++++------------------- runtime/config.go | 12 ++++++---- runtime/config_test.go | 2 +- 6 files changed, 54 insertions(+), 35 deletions(-) diff --git a/cmd/yanic-query/main.go b/cmd/yanic-query/main.go index f981c25..69cc74e 100644 --- a/cmd/yanic-query/main.go +++ b/cmd/yanic-query/main.go @@ -19,8 +19,11 @@ func main() { nodes := runtime.NewNodes(&runtime.Config{}) - collector := respond.NewCollector(nil, nodes, iface, 0) - collector.SendPacket(net.ParseIP(dstAddress)) + collector := respond.NewCollector(nil, nodes, iface, iface, iface, 0) + collector.SendPacket(net.UDPAddr{ + IP: net.ParseIP(dstAddress), + Zone: iface, + }) time.Sleep(time.Second) diff --git a/cmd/yanic/main.go b/cmd/yanic/main.go index 115cb48..8f9526d 100644 --- a/cmd/yanic/main.go +++ b/cmd/yanic/main.go @@ -42,6 +42,12 @@ func main() { if err != nil { panic(err) } + if config.Respondd.InterfaceSendUnicast == "" { + config.Respondd.InterfaceSendUnicast = config.Respondd.InterfaceListen + } + if config.Respondd.InterfaceSendMulticast == "" { + config.Respondd.InterfaceSendMulticast = config.Respondd.InterfaceListen + } connections, err = all.Connect(config.Database.Connection) if err != nil { @@ -74,7 +80,7 @@ func main() { time.Sleep(delay) } - collector = respond.NewCollector(connections, nodes, config.Respondd.Interface, config.Respondd.Port) + collector = respond.NewCollector(connections, nodes, config.Respondd.InterfaceListen, config.Respondd.InterfaceSendMulticast, config.Respondd.InterfaceSendUnicast, config.Respondd.Port) collector.Start(config.Respondd.CollectInterval.Duration) defer collector.Close() } diff --git a/config_example.toml b/config_example.toml index 34ebcf7..3c8b628 100644 --- a/config_example.toml +++ b/config_example.toml @@ -5,8 +5,13 @@ enable = true synchronize = "1m" # how oftern request per multicast collect_interval = "1m" -# on which interface +# on which interface to listen interface = "eth0" +# send unicast request (default: see interface) +## interface_send_unicast = "eth0" +# send multicast request (default: see interface) +# interface_send_multicast = "eth1" + # define a port to listen # (no or 0 would choose at port at his own) #port = 10001 diff --git a/respond/collector.go b/respond/collector.go index b5406c1..46c807e 100644 --- a/respond/collector.go +++ b/respond/collector.go @@ -17,18 +17,19 @@ import ( // Collector for a specificle respond messages type Collector struct { - connection *net.UDPConn // UDP socket - queue chan *Response // received responses - iface string - db database.Connection - nodes *runtime.Nodes - interval time.Duration // Interval for multicast packets - stop chan interface{} + connection *net.UDPConn // UDP socket + queue chan *Response // received responses + ifaceSendUnicast string + ifaceSendMulticast string + db database.Connection + nodes *runtime.Nodes + interval time.Duration // Interval for multicast packets + stop chan interface{} } // NewCollector creates a Collector struct -func NewCollector(db database.Connection, nodes *runtime.Nodes, iface string, port int) *Collector { - linkLocalAddr, err := getLinkLocalAddr(iface) +func NewCollector(db database.Connection, nodes *runtime.Nodes, ifaceListen string, ifaceSendUnicast string, ifaceSendMulticast string, port int) *Collector { + linkLocalAddr, err := getLinkLocalAddr(ifaceListen) if err != nil { log.Panic(err) } @@ -37,7 +38,7 @@ func NewCollector(db database.Connection, nodes *runtime.Nodes, iface string, po conn, err := net.ListenUDP("udp", &net.UDPAddr{ IP: linkLocalAddr, Port: port, - Zone: iface, + Zone: ifaceListen, }) if err != nil { log.Panic(err) @@ -45,12 +46,13 @@ func NewCollector(db database.Connection, nodes *runtime.Nodes, iface string, po conn.SetReadBuffer(maxDataGramSize) collector := &Collector{ - connection: conn, - db: db, - nodes: nodes, - iface: iface, - queue: make(chan *Response, 400), - stop: make(chan interface{}), + connection: conn, + db: db, + nodes: nodes, + ifaceSendUnicast: ifaceSendUnicast, + ifaceSendMulticast: ifaceSendMulticast, + queue: make(chan *Response, 400), + stop: make(chan interface{}), } go collector.receiver() @@ -117,7 +119,10 @@ func (coll *Collector) sendOnce() { func (coll *Collector) sendMulticast() { log.Println("sending multicast") - coll.SendPacket(net.ParseIP(multiCastGroup)) + coll.SendPacket(net.UDPAddr{ + IP: net.ParseIP(multiCastGroup), + Zone: coll.ifaceSendMulticast, + }) } // Send unicast packets to nodes that did not answer the multicast @@ -132,19 +137,17 @@ func (coll *Collector) sendUnicasts(seenBefore jsontime.Time) { // Send unicast packets log.Printf("sending unicast to %d nodes", len(nodes)) for _, node := range nodes { - coll.SendPacket(node.Address) + coll.SendPacket(net.UDPAddr{ + IP: node.Address, + Zone: coll.ifaceSendUnicast, + }) time.Sleep(10 * time.Millisecond) } } // SendPacket sends a UDP request to the given unicast or multicast address -func (coll *Collector) SendPacket(address net.IP) { - addr := net.UDPAddr{ - IP: address, - Port: port, - Zone: coll.iface, - } - +func (coll *Collector) SendPacket(addr net.UDPAddr) { + addr.Port = port if _, err := coll.connection.WriteToUDP([]byte("GET nodeinfo statistics neighbours"), &addr); err != nil { log.Println("WriteToUDP failed:", err) } diff --git a/runtime/config.go b/runtime/config.go index b6b3846..13427db 100644 --- a/runtime/config.go +++ b/runtime/config.go @@ -9,11 +9,13 @@ import ( //Config the config File of this daemon type Config struct { Respondd struct { - Enable bool `toml:"enable"` - Synchronize Duration `toml:"synchronize"` - Interface string `toml:"interface"` - Port int `toml:"port"` - CollectInterval Duration `toml:"collect_interval"` + Enable bool `toml:"enable"` + Synchronize Duration `toml:"synchronize"` + InterfaceListen string `toml:"interface"` + InterfaceSendMulticast string `toml:"interface_send_multicast"` + InterfaceSendUnicast string `toml:"interface_send_unicast"` + Port int `toml:"port"` + CollectInterval Duration `toml:"collect_interval"` } Webserver struct { Enable bool `toml:"enable"` diff --git a/runtime/config_test.go b/runtime/config_test.go index a5110a3..4461d8b 100644 --- a/runtime/config_test.go +++ b/runtime/config_test.go @@ -15,7 +15,7 @@ func TestReadConfig(t *testing.T) { assert.NotNil(config) assert.True(config.Respondd.Enable) - assert.Equal("eth0", config.Respondd.Interface) + assert.Equal("eth0", config.Respondd.InterfaceListen) assert.Equal(time.Minute, config.Respondd.CollectInterval.Duration) assert.Equal(2, config.Meshviewer.Version)