Prune routes routable via dead node.

This commit is contained in:
Milos Gajdos
2019-09-15 12:16:08 +01:00
parent 364c5a4861
commit 2599ee8591
2 changed files with 64 additions and 29 deletions

View File

@@ -331,10 +331,15 @@ func (n *network) processNetChan(client transport.Client, listener tunnel.Listen
continue
}
log.Debugf("Network received close message from: %s", pbNetClose.Node.Id)
if err := n.pruneNode(pbNetClose.Node.Id); err != nil {
log.Debugf("Network failed to prune the node %s: %v", pbNetClose.Node.Id, err)
continue
n.node.Lock()
peer := &node{
id: pbNetClose.Node.Id,
address: pbNetClose.Node.Address,
}
if err := n.prunePeer(peer); err != nil {
log.Debugf("Network failed to prune node %s routes: %v", peer.id, err)
}
n.node.Unlock()
}
case <-n.closed:
return
@@ -393,20 +398,13 @@ func (n *network) announce(client transport.Client) {
}
}
// pruneNode removes a node with given id from the list of peers. It also removes all routes originted by this node.
func (n *network) pruneNode(id string) error {
// DeletePeer serializes access
n.node.DeletePeer(id)
// lookup all the routes originated at this node
q := router.NewQuery(
router.QueryRouter(id),
)
// pruneRoutes prunes routes return by given query
func (n *network) pruneRoutes(q router.Query) error {
routes, err := n.Router.Table().Query(q)
if err != nil && err != router.ErrRouteNotFound {
return err
}
// delete the found routes
log.Logf("Network deleting routes originated by router: %s", id)
for _, route := range routes {
if err := n.Router.Table().Delete(route); err != nil && err != router.ErrRouteNotFound {
return err
@@ -416,8 +414,41 @@ func (n *network) pruneNode(id string) error {
return nil
}
// prune the nodes that have not been seen for certain period of time defined by PruneTime
// Additionally, prune also removes all the routes originated by these nodes
// pruneNodeRoutes prunes routes that were either originated by or routable via given node
func (n *network) prunePeerRoutes(peer *node) error {
// lookup all routes originated by router
q := router.NewQuery(
router.QueryRouter(peer.id),
)
if err := n.pruneRoutes(q); err != nil {
log.Debugf("Network failed deleting routes originated by %s: %s", peer.id, err)
return err
}
// lookup all routes routable via gw
q = router.NewQuery(
router.QueryGateway(peer.address),
)
if err := n.pruneRoutes(q); err != nil {
log.Debugf("Network failed deleting routes routable via gateway %s: %s", peer.address, err)
return err
}
return nil
}
// prunePeer prune peer from network node as well as all all the routes associated with it
func (n *network) prunePeer(peer *node) error {
delete(n.node.peers, peer.id)
if err := n.prunePeerRoutes(peer); err != nil {
log.Debugf("Network failed to prune %s routes: %v", peer.id, err)
return err
}
return nil
}
// prune deltes node peers that have not been seen for longer than PruneTime seconds
// prune also removes all the routes either originated by or routable by the stale nodes
func (n *network) prune() {
prune := time.NewTicker(PruneTime)
defer prune.Stop()
@@ -427,20 +458,19 @@ func (n *network) prune() {
case <-n.closed:
return
case <-prune.C:
n.Lock()
for id, node := range n.peers {
n.node.Lock()
for id, peer := range n.peers {
if id == n.options.Id {
continue
}
if time.Since(node.lastSeen) > PruneTime {
log.Debugf("Network deleting node %s: reached prune time threshold", id)
if err := n.pruneNode(id); err != nil {
log.Debugf("Network failed to prune the node %s: %v", id, err)
continue
if time.Since(peer.lastSeen) > PruneTime {
log.Debugf("Network peer exceeded prune time: %s", id)
if err := n.prunePeer(peer); err != nil {
log.Debugf("Network failed to prune %s: %s", id, err)
}
}
}
n.Unlock()
n.node.Unlock()
}
}
}