mask the route before sending

This commit is contained in:
Asim Aslam 2020-01-15 23:06:58 +00:00
parent 6562154573
commit 33a9b3bc17

View File

@ -277,10 +277,37 @@ func (n *network) acceptCtrlConn(l tunnel.Listener, recv chan *message) {
} }
} }
// maskRoute will mask the route so that we apply the right values
func (n *network) maskRoute(r *pbRtr.Route) {
hasher := fnv.New64()
// the routes service address
address := r.Address
// only hash the address if we're advertising our own local routes
// avoid hashing * based routes
if r.Router == n.Id() && r.Address != "*" {
// hash the service before advertising it
hasher.Reset()
// routes for multiple instances of a service will be collapsed here.
// TODO: once we store labels in the table this may need to change
// to include the labels in case they differ but highly unlikely
hasher.Write([]byte(r.Service + n.Address()))
address = fmt.Sprintf("%d", hasher.Sum64())
}
// calculate route metric to advertise
metric := n.getRouteMetric(r.Router, r.Gateway, r.Link)
// NOTE: we override Gateway, Link and Address here
r.Address = address
r.Gateway = n.Address()
r.Link = DefaultLink
r.Metric = metric
}
// advertise advertises routes to the network // advertise advertises routes to the network
func (n *network) advertise(advertChan <-chan *router.Advert) { func (n *network) advertise(advertChan <-chan *router.Advert) {
rnd := rand.New(rand.NewSource(time.Now().UnixNano())) rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
hasher := fnv.New64()
for { for {
select { select {
// process local adverts and randomly fire them at other nodes // process local adverts and randomly fire them at other nodes
@ -289,36 +316,26 @@ func (n *network) advertise(advertChan <-chan *router.Advert) {
var events []*pbRtr.Event var events []*pbRtr.Event
for _, event := range advert.Events { for _, event := range advert.Events {
// the routes service address // make a copy of the route
address := event.Route.Address
// only hash the address if we're advertising our own local routes
if event.Route.Router == advert.Id && event.Route.Address != "*" {
// hash the service before advertising it
hasher.Reset()
// routes for multiple instances of a service will be collapsed here.
// TODO: once we store labels in the table this may need to change
// to include the labels in case they differ but highly unlikely
hasher.Write([]byte(event.Route.Service + n.node.Address()))
address = fmt.Sprintf("%d", hasher.Sum64())
}
// calculate route metric to advertise
metric := n.getRouteMetric(event.Route.Router, event.Route.Gateway, event.Route.Link)
// NOTE: we override Gateway, Link and Address here
route := &pbRtr.Route{ route := &pbRtr.Route{
Service: event.Route.Service, Service: event.Route.Service,
Address: address, Address: event.Route.Address,
Gateway: n.node.Address(), Gateway: event.Route.Gateway,
Network: event.Route.Network, Network: event.Route.Network,
Router: event.Route.Router, Router: event.Route.Router,
Link: DefaultLink, Link: event.Route.Link,
Metric: metric, Metric: event.Route.Metric,
} }
// override the various values
n.maskRoute(route)
e := &pbRtr.Event{ e := &pbRtr.Event{
Type: pbRtr.EventType(event.Type), Type: pbRtr.EventType(event.Type),
Timestamp: event.Timestamp.UnixNano(), Timestamp: event.Timestamp.UnixNano(),
Route: route, Route: route,
} }
events = append(events, e) events = append(events, e)
} }
@ -365,8 +382,20 @@ func (n *network) advertise(advertChan <-chan *router.Advert) {
default: default:
// get a list of node peers // get a list of node peers
peers := n.Peers() peers := n.Peers()
// only proceed if we have a peer
if len(peers) == 0 {
continue
}
// pick a random peer from the list of peers // pick a random peer from the list of peers
if peer := n.node.GetPeerNode(peers[rnd.Intn(len(peers))].Id()); peer != nil { peer := n.node.GetPeerNode(peers[rnd.Intn(len(peers))].Id())
// only proceed with a peer
if peer == nil {
continue
}
// attempt to send the advert to the peer
if err := n.sendTo("advert", ControlChannel, peer, msg); err != nil { if err := n.sendTo("advert", ControlChannel, peer, msg); err != nil {
log.Debugf("Network failed to advertise routes to %s: %v, sending multicast", peer.Id(), err) log.Debugf("Network failed to advertise routes to %s: %v, sending multicast", peer.Id(), err)
// send a multicast message if we fail to send Unicast message // send a multicast message if we fail to send Unicast message
@ -375,7 +404,6 @@ func (n *network) advertise(advertChan <-chan *router.Advert) {
} }
} }
} }
}
case <-n.closed: case <-n.closed:
return return
} }
@ -829,7 +857,11 @@ func (n *network) processNetChan(listener tunnel.Listener) {
// encode the routes to protobuf // encode the routes to protobuf
pbRoutes := make([]*pbRtr.Route, 0, len(routes)) pbRoutes := make([]*pbRtr.Route, 0, len(routes))
for _, route := range routes { for _, route := range routes {
// generate new route proto
pbRoute := pbUtil.RouteToProto(route) pbRoute := pbUtil.RouteToProto(route)
// mask the route before outbounding
n.maskRoute(pbRoute)
// add to list of routes
pbRoutes = append(pbRoutes, pbRoute) pbRoutes = append(pbRoutes, pbRoute)
} }
// pack the routes into the sync message // pack the routes into the sync message