rpc implement setban
, listbanned
, clearbanned
#85
7 changed files with 371 additions and 11 deletions
|
@ -48,6 +48,15 @@ func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd {
|
|||
}
|
||||
}
|
||||
|
||||
// ClearBannedCmd defines the clearbanned JSON-RPC command.
|
||||
type ClearBannedCmd struct{}
|
||||
|
||||
// NewClearBannedCmd returns a new instance which can be used to issue an clearbanned
|
||||
// JSON-RPC command.
|
||||
func NewClearBannedCmd() *ClearBannedCmd {
|
||||
return &ClearBannedCmd{}
|
||||
}
|
||||
|
||||
// TransactionInput represents the inputs to a transaction. Specifically a
|
||||
// transaction hash and output number pair.
|
||||
type TransactionInput struct {
|
||||
|
@ -757,6 +766,15 @@ func NewInvalidateBlockCmd(blockHash string) *InvalidateBlockCmd {
|
|||
}
|
||||
}
|
||||
|
||||
// ListBannedCmd defines the listbanned JSON-RPC command.
|
||||
type ListBannedCmd struct{}
|
||||
|
||||
// NewListBannedCmd returns a new instance which can be used to issue a listbanned
|
||||
// JSON-RPC command.
|
||||
func NewListBannedCmd() *ListBannedCmd {
|
||||
return &ListBannedCmd{}
|
||||
}
|
||||
|
||||
// PingCmd defines the ping JSON-RPC command.
|
||||
type PingCmd struct{}
|
||||
|
||||
|
@ -903,6 +921,39 @@ func NewBitcoindSendRawTransactionCmd(hexTx string, maxFeeRate int32) *SendRawTr
|
|||
}
|
||||
}
|
||||
|
||||
// SetBanSubCmd defines the type used in the setban JSON-RPC command for the
|
||||
// sub command field.
|
||||
type SetBanSubCmd string
|
||||
|
||||
const (
|
||||
// SBAdd indicates the specified host should be added as a persistent
|
||||
// peer.
|
||||
SBAdd SetBanSubCmd = "add"
|
||||
|
||||
// SBRemove indicates the specified peer should be removed.
|
||||
SBRemove SetBanSubCmd = "remove"
|
||||
)
|
||||
|
||||
// SetBanCmd defines the setban JSON-RPC command.
|
||||
type SetBanCmd struct {
|
||||
Addr string
|
||||
SubCmd SetBanSubCmd `jsonrpcusage:"\"add|remove\""`
|
||||
BanTime *int `jsonrpcdefault:"0"`
|
||||
Absolute *bool `jsonrpcdefault:"false"`
|
||||
}
|
||||
|
||||
// NewSetBanCmd returns a new instance which can be used to issue an setban
|
||||
// JSON-RPC command.
|
||||
func NewSetBanCmd(addr string, subCmd SetBanSubCmd, banTime *int,
|
||||
absolute *bool) *SetBanCmd {
|
||||
return &SetBanCmd{
|
||||
Addr: addr,
|
||||
SubCmd: subCmd,
|
||||
BanTime: banTime,
|
||||
Absolute: absolute,
|
||||
}
|
||||
}
|
||||
|
||||
// SetGenerateCmd defines the setgenerate JSON-RPC command.
|
||||
type SetGenerateCmd struct {
|
||||
Generate bool
|
||||
|
@ -1080,6 +1131,9 @@ func init() {
|
|||
MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags)
|
||||
MustRegisterCmd("getnodeaddresses", (*GetNodeAddressesCmd)(nil), flags)
|
||||
MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags)
|
||||
MustRegisterCmd("listbanned", (*ListBannedCmd)(nil), flags)
|
||||
MustRegisterCmd("setban", (*SetBanCmd)(nil), flags)
|
||||
MustRegisterCmd("clearbanned", (*ClearBannedCmd)(nil), flags)
|
||||
MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags)
|
||||
MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags)
|
||||
MustRegisterCmd("gettxout", (*GetTxOutCmd)(nil), flags)
|
||||
|
|
|
@ -721,6 +721,15 @@ type InfoChainResult struct {
|
|||
Errors string `json:"errors"`
|
||||
}
|
||||
|
||||
// ListBannedResult models the data returned from the listbanned command.
|
||||
type ListBannedResult struct {
|
||||
Address string `json:"address"`
|
||||
BanCreated int64 `json:"ban_created"`
|
||||
BannedUntil int64 `json:"banned_until"`
|
||||
BanDuration int64 `json:"ban_duration"`
|
||||
TimeRemaining int64 `json:"time_remaining"`
|
||||
}
|
||||
|
||||
// TxRawResult models the data from the getrawtransaction command.
|
||||
type TxRawResult struct {
|
||||
Hex string `json:"hex"`
|
||||
|
|
|
@ -6,6 +6,7 @@ package main
|
|||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/lbryio/lbcd/blockchain"
|
||||
"github.com/lbryio/lbcd/chaincfg/chainhash"
|
||||
|
@ -181,6 +182,57 @@ func (cm *rpcConnManager) ConnectedPeers() []rpcserverPeer {
|
|||
return peers
|
||||
}
|
||||
|
||||
// BannedPeers returns a map consisting of all banned host with banned period.
|
||||
//
|
||||
// This function is safe for concurrent access and is part of the
|
||||
// rpcserverConnManager interface implementation.
|
||||
func (cm *rpcConnManager) BannedPeers() map[string]bannedPeriod {
|
||||
replyChan := make(chan map[string]bannedPeriod)
|
||||
cm.server.query <- listBannedPeersMsg{reply: replyChan}
|
||||
return <-replyChan
|
||||
}
|
||||
|
||||
// SetBan removes the peer associated with the provided address from the
|
||||
// list of persistent peers.
|
||||
//
|
||||
// This function is safe for concurrent access and is part of the
|
||||
// rpcserverConnManager interface implementation.
|
||||
func (cm *rpcConnManager) SetBan(addr string, since, until time.Time) error {
|
||||
replyChan := make(chan error)
|
||||
cm.server.query <- setBanMsg{
|
||||
addr: addr,
|
||||
since: since,
|
||||
until: until,
|
||||
reply: replyChan,
|
||||
}
|
||||
return <-replyChan
|
||||
}
|
||||
|
||||
// RemoveBan removes a host from banned list.
|
||||
//
|
||||
// This function is safe for concurrent access and is part of the
|
||||
// rpcserverConnManager interface implementation.
|
||||
func (cm *rpcConnManager) RemoveBan(addr string) error {
|
||||
replyChan := make(chan error)
|
||||
cm.server.query <- removeBanMsg{
|
||||
addr: addr,
|
||||
reply: replyChan,
|
||||
}
|
||||
return <-replyChan
|
||||
}
|
||||
|
||||
// ClearBanned removes all banned host with banned period.
|
||||
//
|
||||
// This function is safe for concurrent access and is part of the
|
||||
// rpcserverConnManager interface implementation.
|
||||
func (cm *rpcConnManager) ClearBanned() error {
|
||||
replyChan := make(chan error)
|
||||
cm.server.query <- clearBannedMsg{
|
||||
reply: replyChan,
|
||||
}
|
||||
return <-replyChan
|
||||
}
|
||||
|
||||
// PersistentPeers returns an array consisting of all the added persistent
|
||||
// peers.
|
||||
//
|
||||
|
|
|
@ -355,6 +355,75 @@ func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) {
|
|||
return c.GetPeerInfoAsync().Receive()
|
||||
}
|
||||
|
||||
// FutureListBannedResult is a future promise to deliver the result of a
|
||||
// ListBannedAsync RPC invocation (or an applicable error).
|
||||
type FutureListBannedResult chan *Response
|
||||
|
||||
// Receive waits for the Response promised by the future and returns data about
|
||||
// each connected network peer.
|
||||
func (r FutureListBannedResult) Receive() ([]btcjson.ListBannedResult, error) {
|
||||
res, err := ReceiveFuture(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Unmarshal result as an array of ListBanned result objects.
|
||||
var bannedPeers []btcjson.ListBannedResult
|
||||
err = json.Unmarshal(res, &bannedPeers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bannedPeers, nil
|
||||
}
|
||||
|
||||
// SetBanCommand enumerates the available commands that the SetBanCommand function
|
||||
// accepts.
|
||||
type SetBanCommand string
|
||||
|
||||
// Constants used to indicate the command for the SetBanCommand function.
|
||||
const (
|
||||
// SBAdd indicates the specified host should be added as a banned
|
||||
// peer.
|
||||
SBAdd SetBanCommand = "add"
|
||||
|
||||
// SBRemove indicates the specified peer should be removed.
|
||||
SBRemove SetBanCommand = "remove"
|
||||
)
|
||||
|
||||
// String returns the SetBanCommand in human-readable form.
|
||||
func (cmd SetBanCommand) String() string {
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
// FutureSetBanResult is a future promise to deliver the result of an
|
||||
// SetBanAsync RPC invocation (or an applicable error).
|
||||
type FutureSetBanResult chan *Response
|
||||
|
||||
// Receive waits for the Response promised by the future and returns an error if
|
||||
// any occurred when performing the specified command.
|
||||
func (r FutureSetBanResult) Receive() error {
|
||||
_, err := ReceiveFuture(r)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetBanAsync returns an instance of a type that can be used to get the result
|
||||
// of the RPC at some future time by invoking the Receive function on the
|
||||
// returned instance.
|
||||
func (c *Client) SetBanAsync(addr string, command string, banTime *int,
|
||||
absolute *bool) FutureSetBanResult {
|
||||
cmd := btcjson.NewSetBanCmd(addr, btcjson.SetBanSubCmd(command), banTime,
|
||||
absolute)
|
||||
return c.SendCmd(cmd)
|
||||
}
|
||||
|
||||
// SetBan attempts to perform the passed command on the passed persistent peer.
|
||||
// For example, it can be used to add or a remove a banned peer.
|
||||
func (c *Client) SetBan(addr string, command string, banTime *int,
|
||||
absolute *bool) error {
|
||||
return c.SetBanAsync(addr, command, banTime, absolute).Receive()
|
||||
}
|
||||
|
||||
// FutureGetNetTotalsResult is a future promise to deliver the result of a
|
||||
// GetNetTotalsAsync RPC invocation (or an applicable error).
|
||||
type FutureGetNetTotalsResult chan *Response
|
||||
|
|
105
rpcserver.go
105
rpcserver.go
|
@ -134,6 +134,7 @@ type commandHandler func(*rpcServer, interface{}, <-chan struct{}) (interface{},
|
|||
var rpcHandlers map[string]commandHandler
|
||||
var rpcHandlersBeforeInit = map[string]commandHandler{
|
||||
"addnode": handleAddNode,
|
||||
"clearbanned": handleClearBanned,
|
||||
"createrawtransaction": handleCreateRawTransaction,
|
||||
"debuglevel": handleDebugLevel,
|
||||
"decoderawtransaction": handleDecodeRawTransaction,
|
||||
|
@ -150,10 +151,10 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
|||
"getblockcount": handleGetBlockCount,
|
||||
"getblockhash": handleGetBlockHash,
|
||||
"getblockheader": handleGetBlockHeader,
|
||||
"getchaintips": handleGetChainTips,
|
||||
"getblocktemplate": handleGetBlockTemplate,
|
||||
"getcfilter": handleGetCFilter,
|
||||
"getcfilterheader": handleGetCFilterHeader,
|
||||
"getchaintips": handleGetChainTips,
|
||||
"getconnectioncount": handleGetConnectionCount,
|
||||
"getcurrentnet": handleGetCurrentNet,
|
||||
"getdifficulty": handleGetDifficulty,
|
||||
|
@ -161,8 +162,8 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
|||
"gethashespersec": handleGetHashesPerSec,
|
||||
"getheaders": handleGetHeaders,
|
||||
"getinfo": handleGetInfo,
|
||||
"getmempoolinfo": handleGetMempoolInfo,
|
||||
"getmempoolentry": handleGetMempoolEntry,
|
||||
"getmempoolinfo": handleGetMempoolInfo,
|
||||
"getmininginfo": handleGetMiningInfo,
|
||||
"getnettotals": handleGetNetTotals,
|
||||
"getnetworkhashps": handleGetNetworkHashPS,
|
||||
|
@ -174,11 +175,13 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
|||
"gettxout": handleGetTxOut,
|
||||
"help": handleHelp,
|
||||
"invalidateblock": handleInvalidateBlock,
|
||||
"listbanned": handleListBanned,
|
||||
"node": handleNode,
|
||||
"ping": handlePing,
|
||||
"reconsiderblock": handleReconsiderBlock,
|
||||
"searchrawtransactions": handleSearchRawTransactions,
|
||||
"sendrawtransaction": handleSendRawTransaction,
|
||||
"setban": handleSetBan,
|
||||
"setgenerate": handleSetGenerate,
|
||||
"signmessagewithprivkey": handleSignMessageWithPrivKey,
|
||||
"stop": handleStop,
|
||||
|
@ -398,6 +401,21 @@ func handleAddNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// handleClearBanned handles clearbanned commands.
|
||||
func handleClearBanned(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
|
||||
err := s.cfg.ConnMgr.ClearBanned()
|
||||
if err != nil {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidParameter,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
// no data returned unless an error.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// handleNode handles node commands.
|
||||
func handleNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
c := cmd.(*btcjson.NodeCmd)
|
||||
|
@ -3146,6 +3164,24 @@ func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter
|
|||
return help, nil
|
||||
}
|
||||
|
||||
// handleListBanned handles the listbanned command.
|
||||
func handleListBanned(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
banned := s.cfg.ConnMgr.BannedPeers()
|
||||
reply := make([]*btcjson.ListBannedResult, 0, len(banned))
|
||||
for address, period := range banned {
|
||||
since, until := period.since, period.until
|
||||
r := btcjson.ListBannedResult{
|
||||
Address: address,
|
||||
BanCreated: since.Unix(),
|
||||
BannedUntil: until.Unix(),
|
||||
BanDuration: int64(until.Sub(since).Seconds()),
|
||||
TimeRemaining: int64(time.Until(until).Seconds()),
|
||||
}
|
||||
reply = append(reply, &r)
|
||||
}
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
// handlePing implements the ping command.
|
||||
func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
// Ask server to ping \o_
|
||||
|
@ -3749,6 +3785,59 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
|
|||
return tx.Hash().String(), nil
|
||||
}
|
||||
|
||||
// handleSetBan handles the setban command.
|
||||
func handleSetBan(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
c := cmd.(*btcjson.SetBanCmd)
|
||||
|
||||
addr := net.ParseIP(c.Addr)
|
||||
if addr == nil {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidParameter,
|
||||
Message: "invalid addr for setban",
|
||||
}
|
||||
}
|
||||
|
||||
since := time.Now()
|
||||
until := since.Add(time.Second * time.Duration(*c.BanTime))
|
||||
if *c.BanTime == 0 {
|
||||
until = since.Add(defaultBanDuration)
|
||||
}
|
||||
if *c.Absolute {
|
||||
until = time.Unix(int64(*c.BanTime), 0)
|
||||
}
|
||||
|
||||
var err error
|
||||
switch c.SubCmd {
|
||||
case "add":
|
||||
err = s.cfg.ConnMgr.SetBan(addr.String(), since, until)
|
||||
addr := addr.String()
|
||||
peers := s.cfg.ConnMgr.ConnectedPeers()
|
||||
for _, peer := range peers {
|
||||
p := peer.ToPeer()
|
||||
if p.NA().IP.String() == addr {
|
||||
p.Disconnect()
|
||||
}
|
||||
}
|
||||
case "remove":
|
||||
err = s.cfg.ConnMgr.RemoveBan(addr.String())
|
||||
default:
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidParameter,
|
||||
Message: "invalid subcommand for setban",
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidParameter,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
// no data returned unless an error.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// handleSetGenerate implements the setgenerate command.
|
||||
func handleSetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
c := cmd.(*btcjson.SetGenerateCmd)
|
||||
|
@ -4806,6 +4895,18 @@ type rpcserverConnManager interface {
|
|||
// ConnectedPeers returns an array consisting of all connected peers.
|
||||
ConnectedPeers() []rpcserverPeer
|
||||
|
||||
// BannedPeers returns an array consisting of all Banned peers.
|
||||
BannedPeers() map[string]bannedPeriod
|
||||
|
||||
// SetBan add the addr to the ban list.
|
||||
SetBan(addr string, since time.Time, until time.Time) error
|
||||
|
||||
// RemoveBan remove the subnet from the ban list.
|
||||
RemoveBan(subnet string) error
|
||||
|
||||
// ClearBanned removes all banned IPs.
|
||||
ClearBanned() error
|
||||
|
||||
// PersistentPeers returns an array consisting of all the persistent
|
||||
// peers.
|
||||
PersistentPeers() []rpcserverPeer
|
||||
|
|
|
@ -56,6 +56,9 @@ var helpDescsEnUS = map[string]string{
|
|||
"createrawtransaction-locktime": "Locktime value; a non-zero value will also locktime-activate the inputs",
|
||||
"createrawtransaction--result0": "Hex-encoded bytes of the serialized transaction",
|
||||
|
||||
// ClearBannedCmd help.
|
||||
"clearbanned--synopsis": "Clear all banned IPs.",
|
||||
|
||||
// ScriptSig help.
|
||||
"scriptsig-asm": "Disassembly of the script",
|
||||
"scriptsig-hex": "Hex-encoded bytes of the script",
|
||||
|
@ -636,6 +639,16 @@ var helpDescsEnUS = map[string]string{
|
|||
"ping--synopsis": "Queues a ping to be sent to each connected peer.\n" +
|
||||
"Ping times are provided by getpeerinfo via the pingtime and pingwait fields.",
|
||||
|
||||
// ListBannedCmd help.
|
||||
"listbanned--synopsis": "List all banned IPs.",
|
||||
|
||||
// ListBannedResult help.
|
||||
"listbannedresult-address": "The IP of the banned node.",
|
||||
"listbannedresult-ban_created": "The UNIX epoch time the ban was created.",
|
||||
"listbannedresult-banned_until": "The UNIX epoch time the ban expires.",
|
||||
"listbannedresult-ban_duration": "The duration of the ban, in seconds.",
|
||||
"listbannedresult-time_remaining": "The time remaining on the ban, in seconds",
|
||||
|
||||
// ReconsiderBlockCmd
|
||||
"reconsiderblock--synopsis": "Reconsider a block for validation.",
|
||||
"reconsiderblock-blockhash": "Hash of the block you want to reconsider",
|
||||
|
@ -664,6 +677,13 @@ var helpDescsEnUS = map[string]string{
|
|||
"sendrawtransaction--result0": "The hash of the transaction",
|
||||
"allowhighfeesormaxfeerate-value": "Either the boolean value for the allowhighfees parameter in bitcoind < v0.19.0 or the numerical value for the maxfeerate field in bitcoind v0.19.0 and later",
|
||||
|
||||
// SetBanCmd help.
|
||||
"setban--synopsis": "Add or remove an IP from the banned list. (Currently, subnet is not supported.)",
|
||||
"setban-addr": "The IP to ban. (Currently, subnet is not supported.)",
|
||||
"setban-subcmd": "'add' to add an IP to the list, 'remove' to remove an IP from the list",
|
||||
"setban-bantime": "Time in seconds the IP is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)",
|
||||
"setban-absolute": "If set, the bantime must be an absolute timestamp expressed in UNIX epoch time; default to false.",
|
||||
|
||||
// SetGenerateCmd help.
|
||||
"setgenerate--synopsis": "Set the server to generate coins (mine) or not.",
|
||||
"setgenerate-generate": "Use true to enable generation, false to disable it",
|
||||
|
@ -880,6 +900,7 @@ var helpDescsEnUS = map[string]string{
|
|||
// pointer to the type (or nil to indicate no return value).
|
||||
var rpcResultTypes = map[string][]interface{}{
|
||||
"addnode": nil,
|
||||
"clearbanned": nil,
|
||||
"createrawtransaction": {(*string)(nil)},
|
||||
"debuglevel": {(*string)(nil), (*string)(nil)},
|
||||
"decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)},
|
||||
|
@ -892,11 +913,11 @@ var rpcResultTypes = map[string][]interface{}{
|
|||
"getbestblock": {(*btcjson.GetBestBlockResult)(nil)},
|
||||
"getbestblockhash": {(*string)(nil)},
|
||||
"getblock": {(*string)(nil), (*btcjson.GetBlockVerboseResult)(nil)},
|
||||
"getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)},
|
||||
"getblockcount": {(*int64)(nil)},
|
||||
"getblockhash": {(*string)(nil)},
|
||||
"getblockheader": {(*string)(nil), (*btcjson.GetBlockHeaderVerboseResult)(nil)},
|
||||
"getblocktemplate": {(*btcjson.GetBlockTemplateResult)(nil), (*string)(nil), nil},
|
||||
"getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)},
|
||||
"getcfilter": {(*string)(nil)},
|
||||
"getcfilterheader": {(*string)(nil)},
|
||||
"getchaintips": {(*[]btcjson.GetChainTipsResult)(nil)},
|
||||
|
@ -918,13 +939,15 @@ var rpcResultTypes = map[string][]interface{}{
|
|||
"getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)},
|
||||
"getrawtransaction": {(*string)(nil), (*btcjson.TxRawResult)(nil)},
|
||||
"gettxout": {(*btcjson.GetTxOutResult)(nil)},
|
||||
"node": nil,
|
||||
"help": {(*string)(nil), (*string)(nil)},
|
||||
"invalidateblock": nil,
|
||||
"listbanned": {(*[]btcjson.ListBannedResult)(nil)},
|
||||
"node": nil,
|
||||
"ping": nil,
|
||||
"reconsiderblock": nil,
|
||||
"searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)},
|
||||
"sendrawtransaction": {(*string)(nil)},
|
||||
"setban": nil,
|
||||
"setgenerate": nil,
|
||||
"signmessagewithprivkey": {(*string)(nil)},
|
||||
"stop": {(*string)(nil)},
|
||||
|
|
66
server.go
66
server.go
|
@ -156,13 +156,18 @@ type updatePeerHeightsMsg struct {
|
|||
originPeer *peer.Peer
|
||||
}
|
||||
|
||||
type bannedPeriod struct {
|
||||
since time.Time
|
||||
until time.Time
|
||||
}
|
||||
|
||||
// peerState maintains state of inbound, persistent, outbound peers as well
|
||||
// as banned peers and outbound groups.
|
||||
type peerState struct {
|
||||
inboundPeers map[int32]*serverPeer
|
||||
outboundPeers map[int32]*serverPeer
|
||||
persistentPeers map[int32]*serverPeer
|
||||
banned map[string]time.Time
|
||||
banned map[string]bannedPeriod
|
||||
outboundGroups map[string]int
|
||||
}
|
||||
|
||||
|
@ -1656,10 +1661,10 @@ func (s *server) handleAddPeerMsg(state *peerState, sp *serverPeer) bool {
|
|||
sp.Disconnect()
|
||||
return false
|
||||
}
|
||||
if banEnd, ok := state.banned[host]; ok {
|
||||
if time.Now().Before(banEnd) {
|
||||
srvrLog.Debugf("Peer %s is banned for another %v - disconnecting",
|
||||
host, time.Until(banEnd))
|
||||
if ban, ok := state.banned[host]; ok {
|
||||
if time.Now().Before(ban.until) {
|
||||
srvrLog.Infof("Peer %s is banned for another %v - disconnecting",
|
||||
host, time.Until(ban.until))
|
||||
sp.Disconnect()
|
||||
return false
|
||||
}
|
||||
|
@ -1781,7 +1786,12 @@ func (s *server) handleBanPeerMsg(state *peerState, sp *serverPeer) {
|
|||
direction := directionString(sp.Inbound())
|
||||
srvrLog.Infof("Banned peer %s (%s) for %v", host, direction,
|
||||
cfg.BanDuration)
|
||||
state.banned[host] = time.Now().Add(cfg.BanDuration)
|
||||
|
||||
since := time.Now()
|
||||
state.banned[host] = bannedPeriod{
|
||||
since: since,
|
||||
until: since.Add(cfg.BanDuration),
|
||||
}
|
||||
}
|
||||
|
||||
// handleRelayInvMsg deals with relaying inventory to peers that are not already
|
||||
|
@ -1876,6 +1886,25 @@ type getPeersMsg struct {
|
|||
reply chan []*serverPeer
|
||||
}
|
||||
|
||||
type listBannedPeersMsg struct {
|
||||
reply chan map[string]bannedPeriod
|
||||
}
|
||||
|
||||
type setBanMsg struct {
|
||||
addr string
|
||||
since time.Time
|
||||
until time.Time
|
||||
reply chan error
|
||||
}
|
||||
|
||||
type removeBanMsg struct {
|
||||
addr string
|
||||
reply chan error
|
||||
}
|
||||
|
||||
type clearBannedMsg struct {
|
||||
reply chan error
|
||||
}
|
||||
type getOutboundGroup struct {
|
||||
key string
|
||||
reply chan int
|
||||
|
@ -1924,6 +1953,29 @@ func (s *server) handleQuery(state *peerState, querymsg interface{}) {
|
|||
})
|
||||
msg.reply <- peers
|
||||
|
||||
case listBannedPeersMsg:
|
||||
banned := map[string]bannedPeriod{}
|
||||
for host, ban := range state.banned {
|
||||
banned[host] = ban
|
||||
}
|
||||
msg.reply <- banned
|
||||
|
||||
case setBanMsg:
|
||||
ban := bannedPeriod{
|
||||
since: msg.since,
|
||||
until: msg.until,
|
||||
}
|
||||
state.banned[msg.addr] = ban
|
||||
msg.reply <- nil
|
||||
|
||||
case removeBanMsg:
|
||||
delete(state.banned, msg.addr)
|
||||
msg.reply <- nil
|
||||
|
||||
case clearBannedMsg:
|
||||
state.banned = map[string]bannedPeriod{}
|
||||
msg.reply <- nil
|
||||
|
||||
case connectNodeMsg:
|
||||
// TODO: duplicate oneshots?
|
||||
// Limit max number of total peers.
|
||||
|
@ -2161,7 +2213,7 @@ func (s *server) peerHandler() {
|
|||
inboundPeers: make(map[int32]*serverPeer),
|
||||
persistentPeers: make(map[int32]*serverPeer),
|
||||
outboundPeers: make(map[int32]*serverPeer),
|
||||
banned: make(map[string]time.Time),
|
||||
banned: make(map[string]bannedPeriod),
|
||||
outboundGroups: make(map[string]int),
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue