Prune routes routable via dead node.
This commit is contained in:
		| @@ -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() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user