From e955e3f798c4447f3a7b1378104ce70024e53c81 Mon Sep 17 00:00:00 2001 From: Milos Gajdos Date: Fri, 30 Aug 2019 00:04:46 +0100 Subject: [PATCH] Avoid routes that route back to node without its being direct GW to dest --- network/default.go | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/network/default.go b/network/default.go index e5830e21..186513db 100644 --- a/network/default.go +++ b/network/default.go @@ -14,7 +14,7 @@ import ( "github.com/micro/go-micro/server" "github.com/micro/go-micro/transport" "github.com/micro/go-micro/tunnel" - trn "github.com/micro/go-micro/tunnel/transport" + tun "github.com/micro/go-micro/tunnel/transport" "github.com/micro/go-micro/util/log" ) @@ -84,8 +84,8 @@ func newNetwork(opts ...Option) Network { ) // create tunnel client with tunnel transport - tunTransport := trn.NewTransport( - trn.WithTunnel(options.Tunnel), + tunTransport := tun.NewTransport( + tun.WithTunnel(options.Tunnel), ) // server is network server @@ -439,11 +439,42 @@ func (n *network) processCtrlChan(l tunnel.Listener) { case "advert": pbRtrAdvert := &pbRtr.Advert{} if err := proto.Unmarshal(m.Body, pbRtrAdvert); err != nil { + log.Debugf("Network fail to unmarshal advert message: %v", err) continue } + // loookup advertising node in our neighbourhood + n.RLock() + advertNode, ok := n.neighbours[pbRtrAdvert.Id] + if !ok { + // advertising node has not been registered as our neighbour, yet + // let's add it to the map of our neighbours + advertNode = &node{ + id: pbRtrAdvert.Id, + neighbours: make(map[string]*node), + } + n.neighbours[pbRtrAdvert.Id] = advertNode + } + n.RUnlock() + var events []*router.Event for _, event := range pbRtrAdvert.Events { + // set the address of the advertising node + // we know Route.Gateway is the address of advertNode + // NOTE: this is true only when advertNode had not been registered + // as our neighbour when we received the advert from it + if advertNode.address == "" { + advertNode.address = event.Route.Gateway + } + // if advertising node id is not the same as Route.Router + // we know the advertising node is not the origin of the route + if advertNode.id != event.Route.Router { + // if the origin router is not in the advertising node neighbourhood + // we can't rule out potential routing loops so we bail here + if _, ok := advertNode.neighbours[event.Route.Router]; !ok { + continue + } + } route := router.Route{ Service: event.Route.Service, Address: event.Route.Address,