From 433fb1a95d7a96a033d7454e198d274e92108865 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 25 May 2015 20:03:51 +0200 Subject: [RPC] extend setban to allow subnets --- src/rpcnet.cpp | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'src/rpcnet.cpp') diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 6157a2d0a..e6c33e1d0 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -474,39 +474,51 @@ Value setban(const Array& params, bool fHelp) if (fHelp || params.size() < 2 || (strCommand != "add" && strCommand != "remove")) throw runtime_error( - "setban \"node\" \"add|remove\" (bantime)\n" - "\nAttempts add or remove a IP from the banned list.\n" + "setban \"ip(/netmask)\" \"add|remove\" (bantime)\n" + "\nAttempts add or remove a IP/Subnet from the banned list.\n" "\nArguments:\n" - "1. \"ip\" (string, required) The IP (see getpeerinfo for nodes ip)\n" - "2. \"command\" (string, required) 'add' to add a IP to the list, 'remove' to remove a IP from the list\n" - "1. \"bantime\" (numeric, optional) time in seconds how long the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" + "1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n" + "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n" + "1. \"bantime\" (numeric, optional) time in seconds how long the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" "\nExamples:\n" + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") + + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400") ); - CNetAddr netAddr(params[0].get_str()); - if (!netAddr.IsValid()) - throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP Address"); + CSubNet subNet; + CNetAddr netAddr; + bool isSubnet = false; + + if (params[0].get_str().find("/") != string::npos) + isSubnet = true; + + if (!isSubnet) + netAddr = CNetAddr(params[0].get_str()); + else + subNet = CSubNet(params[0].get_str()); + + if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) ) + throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet"); if (strCommand == "add") { - if (CNode::IsBanned(netAddr)) - throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP already banned"); + if (isSubnet ? CNode::IsBanned(subNet) : CNode::IsBanned(netAddr)) + throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned"); int64_t banTime = 0; //use standard bantime if not specified if (params.size() == 3 && !params[2].is_null()) banTime = params[2].get_int64(); - CNode::Ban(netAddr, banTime); + isSubnet ? CNode::Ban(subNet, banTime) : CNode::Ban(netAddr, banTime); //disconnect possible nodes - while(CNode *bannedNode = FindNode(netAddr)) + while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr))) bannedNode->CloseSocketDisconnect(); } else if(strCommand == "remove") { - if (!CNode::Unban(netAddr)) + if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) )) throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Unban failed"); } @@ -518,17 +530,17 @@ Value listbanned(const Array& params, bool fHelp) if (fHelp || params.size() != 0) throw runtime_error( "listbanned\n" - "\nList all banned IPs.\n" + "\nList all banned IPs/Subnets.\n" "\nExamples:\n" + HelpExampleCli("listbanned", "") + HelpExampleRpc("listbanned", "") ); - std::map banMap; + std::map banMap; CNode::GetBanned(banMap); Array bannedAddresses; - for (std::map::iterator it = banMap.begin(); it != banMap.end(); it++) + for (std::map::iterator it = banMap.begin(); it != banMap.end(); it++) { Object rec; rec.push_back(Pair("address", (*it).first.ToString())); -- cgit v1.2.3