Prune routes routable via dead node.
This commit is contained in:
parent
364c5a4861
commit
2599ee8591
@ -331,10 +331,15 @@ func (n *network) processNetChan(client transport.Client, listener tunnel.Listen
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Debugf("Network received close message from: %s", pbNetClose.Node.Id)
|
log.Debugf("Network received close message from: %s", pbNetClose.Node.Id)
|
||||||
if err := n.pruneNode(pbNetClose.Node.Id); err != nil {
|
n.node.Lock()
|
||||||
log.Debugf("Network failed to prune the node %s: %v", pbNetClose.Node.Id, err)
|
peer := &node{
|
||||||
continue
|
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:
|
case <-n.closed:
|
||||||
return
|
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.
|
// pruneRoutes prunes routes return by given query
|
||||||
func (n *network) pruneNode(id string) error {
|
func (n *network) pruneRoutes(q router.Query) error {
|
||||||
// DeletePeer serializes access
|
|
||||||
n.node.DeletePeer(id)
|
|
||||||
// lookup all the routes originated at this node
|
|
||||||
q := router.NewQuery(
|
|
||||||
router.QueryRouter(id),
|
|
||||||
)
|
|
||||||
routes, err := n.Router.Table().Query(q)
|
routes, err := n.Router.Table().Query(q)
|
||||||
if err != nil && err != router.ErrRouteNotFound {
|
if err != nil && err != router.ErrRouteNotFound {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// delete the found routes
|
|
||||||
log.Logf("Network deleting routes originated by router: %s", id)
|
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if err := n.Router.Table().Delete(route); err != nil && err != router.ErrRouteNotFound {
|
if err := n.Router.Table().Delete(route); err != nil && err != router.ErrRouteNotFound {
|
||||||
return err
|
return err
|
||||||
@ -416,8 +414,41 @@ func (n *network) pruneNode(id string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// prune the nodes that have not been seen for certain period of time defined by PruneTime
|
// pruneNodeRoutes prunes routes that were either originated by or routable via given node
|
||||||
// Additionally, prune also removes all the routes originated by these nodes
|
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() {
|
func (n *network) prune() {
|
||||||
prune := time.NewTicker(PruneTime)
|
prune := time.NewTicker(PruneTime)
|
||||||
defer prune.Stop()
|
defer prune.Stop()
|
||||||
@ -427,20 +458,19 @@ func (n *network) prune() {
|
|||||||
case <-n.closed:
|
case <-n.closed:
|
||||||
return
|
return
|
||||||
case <-prune.C:
|
case <-prune.C:
|
||||||
n.Lock()
|
n.node.Lock()
|
||||||
for id, node := range n.peers {
|
for id, peer := range n.peers {
|
||||||
if id == n.options.Id {
|
if id == n.options.Id {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if time.Since(node.lastSeen) > PruneTime {
|
if time.Since(peer.lastSeen) > PruneTime {
|
||||||
log.Debugf("Network deleting node %s: reached prune time threshold", id)
|
log.Debugf("Network peer exceeded prune time: %s", id)
|
||||||
if err := n.pruneNode(id); err != nil {
|
if err := n.prunePeer(peer); err != nil {
|
||||||
log.Debugf("Network failed to prune the node %s: %v", id, err)
|
log.Debugf("Network failed to prune %s: %s", id, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n.Unlock()
|
n.node.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,12 +71,15 @@ func (n *node) UpdatePeer(peer *node) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeletePeer deletes a peer if it exists
|
// DeletePeer deletes a peer from node peers
|
||||||
func (n *node) DeletePeer(id string) {
|
// It returns true if the peers has been deleted
|
||||||
|
func (n *node) DeletePeer(id string) bool {
|
||||||
n.Lock()
|
n.Lock()
|
||||||
defer n.Unlock()
|
defer n.Unlock()
|
||||||
|
|
||||||
delete(n.peers, id)
|
delete(n.peers, id)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasPeer returns true if node has peer with given id
|
// HasPeer returns true if node has peer with given id
|
||||||
@ -106,6 +109,7 @@ func (n *node) RefreshPeer(id string, now time.Time) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// walk walks the node graph until some condition is met
|
||||||
func (n *node) walk(until func(peer *node) bool) map[string]*node {
|
func (n *node) walk(until func(peer *node) bool) map[string]*node {
|
||||||
// track the visited nodes
|
// track the visited nodes
|
||||||
visited := make(map[string]*node)
|
visited := make(map[string]*node)
|
||||||
@ -139,7 +143,7 @@ func (n *node) walk(until func(peer *node) bool) map[string]*node {
|
|||||||
return visited
|
return visited
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes returns a slice if all nodes in node topology
|
// Nodes returns a slice of all nodes in the whole node topology
|
||||||
func (n *node) Nodes() []Node {
|
func (n *node) Nodes() []Node {
|
||||||
// we need to freeze the network graph here
|
// we need to freeze the network graph here
|
||||||
// otherwise we might get inconsisten results
|
// otherwise we might get inconsisten results
|
||||||
@ -162,8 +166,8 @@ func (n *node) Nodes() []Node {
|
|||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPeerNode returns a peer from node topology i.e. up to MaxDepth
|
// GetPeerNode returns a node from node MaxDepth topology
|
||||||
// It returns nil if the peer was not found in the node topology
|
// It returns nil if the peer was not found
|
||||||
func (n *node) GetPeerNode(id string) *node {
|
func (n *node) GetPeerNode(id string) *node {
|
||||||
n.RLock()
|
n.RLock()
|
||||||
defer n.RUnlock()
|
defer n.RUnlock()
|
||||||
@ -185,7 +189,8 @@ func (n *node) GetPeerNode(id string) *node {
|
|||||||
return peerNode
|
return peerNode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Topology returns a copy of th node topology down to given depth
|
// Topology returns a copy of the node topology down to given depth
|
||||||
|
// NOTE: the returned node is a node graph - not a single node
|
||||||
func (n *node) Topology(depth uint) *node {
|
func (n *node) Topology(depth uint) *node {
|
||||||
n.RLock()
|
n.RLock()
|
||||||
defer n.RUnlock()
|
defer n.RUnlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user