Explorar o código

node, p2p, internal: Add ability to remove peers via admin interface

Firescar96 %!s(int64=9) %!d(string=hai) anos
pai
achega
4c3da0f2e1
Modificáronse 5 ficheiros con 48 adicións e 0 borrados
  1. 5 0
      internal/web3ext/web3ext.go
  2. 16 0
      node/api.go
  3. 5 0
      p2p/dial.go
  4. 20 0
      p2p/server.go
  5. 2 0
      p2p/server_test.go

+ 5 - 0
internal/web3ext/web3ext.go

@@ -39,6 +39,11 @@ web3._extend({
 			call: 'admin_addPeer',
 			params: 1
 		}),
+		new web3._extend.Method({
+			name: 'removePeer',
+			call: 'admin_removePeer',
+			params: 1
+		}),
 		new web3._extend.Method({
 			name: 'exportChain',
 			call: 'admin_exportChain',

+ 16 - 0
node/api.go

@@ -58,6 +58,22 @@ func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) {
 	return true, nil
 }
 
+// RemovePeer disconnects from a a remote node if the connection exists
+func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) {
+	// Make sure the server is running, fail otherwise
+	server := api.node.Server()
+	if server == nil {
+		return false, ErrNodeStopped
+	}
+	// Try to remove the url as a static peer and return
+	node, err := discover.ParseNode(url)
+	if err != nil {
+		return false, fmt.Errorf("invalid enode: %v", err)
+	}
+	server.RemovePeer(node)
+	return true, nil
+}
+
 // StartRPC starts the HTTP RPC API server.
 func (api *PrivateAdminAPI) StartRPC(host *string, port *rpc.HexNumber, cors *string, apis *string) (bool, error) {
 	api.node.lock.Lock()

+ 5 - 0
p2p/dial.go

@@ -121,6 +121,11 @@ func (s *dialstate) addStatic(n *discover.Node) {
 	s.static[n.ID] = &dialTask{flags: staticDialedConn, dest: n}
 }
 
+func (s *dialstate) removeStatic(n *discover.Node) {
+	// This removes a task so future attempts to connect will not be made.
+	delete(s.static, n.ID)
+}
+
 func (s *dialstate) newTasks(nRunning int, peers map[discover.NodeID]*Peer, now time.Time) []task {
 	var newtasks []task
 	isDialing := func(id discover.NodeID) bool {

+ 20 - 0
p2p/server.go

@@ -142,6 +142,7 @@ type Server struct {
 
 	quit          chan struct{}
 	addstatic     chan *discover.Node
+	removestatic  chan *discover.Node
 	posthandshake chan *conn
 	addpeer       chan *conn
 	delpeer       chan *Peer
@@ -257,6 +258,14 @@ func (srv *Server) AddPeer(node *discover.Node) {
 	}
 }
 
+// RemovePeer disconnects from the given node
+func (srv *Server) RemovePeer(node *discover.Node) {
+	select {
+	case srv.removestatic <- node:
+	case <-srv.quit:
+	}
+}
+
 // Self returns the local node's endpoint information.
 func (srv *Server) Self() *discover.Node {
 	srv.lock.Lock()
@@ -327,6 +336,7 @@ func (srv *Server) Start() (err error) {
 	srv.delpeer = make(chan *Peer)
 	srv.posthandshake = make(chan *conn)
 	srv.addstatic = make(chan *discover.Node)
+	srv.removestatic = make(chan *discover.Node)
 	srv.peerOp = make(chan peerOpFunc)
 	srv.peerOpDone = make(chan struct{})
 
@@ -395,6 +405,7 @@ type dialer interface {
 	newTasks(running int, peers map[discover.NodeID]*Peer, now time.Time) []task
 	taskDone(task, time.Time)
 	addStatic(*discover.Node)
+	removeStatic(*discover.Node)
 }
 
 func (srv *Server) run(dialstate dialer) {
@@ -458,6 +469,15 @@ running:
 			// it will keep the node connected.
 			glog.V(logger.Detail).Infoln("<-addstatic:", n)
 			dialstate.addStatic(n)
+		case n := <-srv.removestatic:
+			// This channel is used by RemovePeer to send a
+			// disconnect request to a peer and begin the
+			// stop keeping the node connected
+			glog.V(logger.Detail).Infoln("<-removestatic:", n)
+			dialstate.removeStatic(n)
+			if p, ok := peers[n.ID]; ok {
+				p.Disconnect(DiscRequested)
+			}
 		case op := <-srv.peerOp:
 			// This channel is used by Peers and PeerCount.
 			op(peers)

+ 2 - 0
p2p/server_test.go

@@ -301,6 +301,8 @@ func (tg taskgen) taskDone(t task, now time.Time) {
 }
 func (tg taskgen) addStatic(*discover.Node) {
 }
+func (tg taskgen) removeStatic(*discover.Node) {
+}
 
 type testTask struct {
 	index  int