|
|
@@ -169,6 +169,8 @@ type Server struct {
|
|
|
quit chan struct{}
|
|
|
addstatic chan *discover.Node
|
|
|
removestatic chan *discover.Node
|
|
|
+ addtrusted chan *discover.Node
|
|
|
+ removetrusted chan *discover.Node
|
|
|
posthandshake chan *conn
|
|
|
addpeer chan *conn
|
|
|
delpeer chan peerDrop
|
|
|
@@ -300,6 +302,23 @@ func (srv *Server) RemovePeer(node *discover.Node) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// AddTrustedPeer adds the given node to a reserved whitelist which allows the
|
|
|
+// node to always connect, even if the slot are full.
|
|
|
+func (srv *Server) AddTrustedPeer(node *discover.Node) {
|
|
|
+ select {
|
|
|
+ case srv.addtrusted <- node:
|
|
|
+ case <-srv.quit:
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// RemoveTrustedPeer removes the given node from the trusted peer set.
|
|
|
+func (srv *Server) RemoveTrustedPeer(node *discover.Node) {
|
|
|
+ select {
|
|
|
+ case srv.removetrusted <- node:
|
|
|
+ case <-srv.quit:
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// SubscribePeers subscribes the given channel to peer events
|
|
|
func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription {
|
|
|
return srv.peerFeed.Subscribe(ch)
|
|
|
@@ -410,6 +429,8 @@ func (srv *Server) Start() (err error) {
|
|
|
srv.posthandshake = make(chan *conn)
|
|
|
srv.addstatic = make(chan *discover.Node)
|
|
|
srv.removestatic = make(chan *discover.Node)
|
|
|
+ srv.addtrusted = make(chan *discover.Node)
|
|
|
+ srv.removetrusted = make(chan *discover.Node)
|
|
|
srv.peerOp = make(chan peerOpFunc)
|
|
|
srv.peerOpDone = make(chan struct{})
|
|
|
|
|
|
@@ -546,8 +567,7 @@ func (srv *Server) run(dialstate dialer) {
|
|
|
queuedTasks []task // tasks that can't run yet
|
|
|
)
|
|
|
// Put trusted nodes into a map to speed up checks.
|
|
|
- // Trusted peers are loaded on startup and cannot be
|
|
|
- // modified while the server is running.
|
|
|
+ // Trusted peers are loaded on startup or added via AddTrustedPeer RPC.
|
|
|
for _, n := range srv.TrustedNodes {
|
|
|
trusted[n.ID] = true
|
|
|
}
|
|
|
@@ -599,12 +619,32 @@ running:
|
|
|
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
|
|
|
+ // stop keeping the node connected.
|
|
|
srv.log.Trace("Removing static node", "node", n)
|
|
|
dialstate.removeStatic(n)
|
|
|
if p, ok := peers[n.ID]; ok {
|
|
|
p.Disconnect(DiscRequested)
|
|
|
}
|
|
|
+ case n := <-srv.addtrusted:
|
|
|
+ // This channel is used by AddTrustedPeer to add an enode
|
|
|
+ // to the trusted node set.
|
|
|
+ srv.log.Trace("Adding trusted node", "node", n)
|
|
|
+ trusted[n.ID] = true
|
|
|
+ // Mark any already-connected peer as trusted
|
|
|
+ if p, ok := peers[n.ID]; ok {
|
|
|
+ p.rw.flags |= trustedConn
|
|
|
+ }
|
|
|
+ case n := <-srv.removetrusted:
|
|
|
+ // This channel is used by RemoveTrustedPeer to remove an enode
|
|
|
+ // from the trusted node set.
|
|
|
+ srv.log.Trace("Removing trusted node", "node", n)
|
|
|
+ if _, ok := trusted[n.ID]; ok {
|
|
|
+ delete(trusted, n.ID)
|
|
|
+ }
|
|
|
+ // Unmark any already-connected peer as trusted
|
|
|
+ if p, ok := peers[n.ID]; ok {
|
|
|
+ p.rw.flags &= ^trustedConn
|
|
|
+ }
|
|
|
case op := <-srv.peerOp:
|
|
|
// This channel is used by Peers and PeerCount.
|
|
|
op(peers)
|