aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--internal/web3ext/web3ext.go5
-rw-r--r--node/api.go16
-rw-r--r--p2p/dial.go5
-rw-r--r--p2p/server.go20
-rw-r--r--p2p/server_test.go2
5 files changed, 48 insertions, 0 deletions
diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go
index 190fd57d2..e76e15177 100644
--- a/internal/web3ext/web3ext.go
+++ b/internal/web3ext/web3ext.go
@@ -40,6 +40,11 @@ web3._extend({
params: 1
}),
new web3._extend.Method({
+ name: 'removePeer',
+ call: 'admin_removePeer',
+ params: 1
+ }),
+ new web3._extend.Method({
name: 'exportChain',
call: 'admin_exportChain',
params: 1,
diff --git a/node/api.go b/node/api.go
index 9b2be9c2e..3523874ab 100644
--- a/node/api.go
+++ b/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()
diff --git a/p2p/dial.go b/p2p/dial.go
index c0e703d7d..691b8539e 100644
--- a/p2p/dial.go
+++ b/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 {
diff --git a/p2p/server.go b/p2p/server.go
index 880aa7cf1..8e3cd93f9 100644
--- a/p2p/server.go
+++ b/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)
diff --git a/p2p/server_test.go b/p2p/server_test.go
index deb34f5bb..313d086ec 100644
--- a/p2p/server_test.go
+++ b/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