Browse Source

setban: rewrite to UniValue, allow absolute bantime

0.13
Jonas Schnelli 10 years ago
parent
commit
4e36e9bcc7
  1. 8
      src/net.cpp
  2. 4
      src/net.h
  3. 1
      src/rpcclient.cpp
  4. 27
      src/rpcnet.cpp
  5. 6
      src/rpcserver.h
  6. 25
      src/test/rpc_tests.cpp

8
src/net.cpp

@ -484,15 +484,15 @@ bool CNode::IsBanned(CSubNet subnet)
return fResult; return fResult;
} }
void CNode::Ban(const CNetAddr& addr, int64_t bantimeoffset) { void CNode::Ban(const CNetAddr& addr, int64_t bantimeoffset, bool sinceUnixEpoch) {
CSubNet subNet(addr.ToString()+(addr.IsIPv4() ? "/32" : "/128")); CSubNet subNet(addr.ToString()+(addr.IsIPv4() ? "/32" : "/128"));
Ban(subNet, bantimeoffset); Ban(subNet, bantimeoffset, sinceUnixEpoch);
} }
void CNode::Ban(const CSubNet& subNet, int64_t bantimeoffset) { void CNode::Ban(const CSubNet& subNet, int64_t bantimeoffset, bool sinceUnixEpoch) {
int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
if (bantimeoffset > 0) if (bantimeoffset > 0)
banTime = GetTime()+bantimeoffset; banTime = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset;
LOCK(cs_setBanned); LOCK(cs_setBanned);
if (setBanned[subNet] < banTime) if (setBanned[subNet] < banTime)

4
src/net.h

@ -608,8 +608,8 @@ public:
static void ClearBanned(); // needed for unit testing static void ClearBanned(); // needed for unit testing
static bool IsBanned(CNetAddr ip); static bool IsBanned(CNetAddr ip);
static bool IsBanned(CSubNet subnet); static bool IsBanned(CSubNet subnet);
static void Ban(const CNetAddr &ip, int64_t bantimeoffset = 0); static void Ban(const CNetAddr &ip, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
static void Ban(const CSubNet &subNet, int64_t bantimeoffset = 0); static void Ban(const CSubNet &subNet, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
static bool Unban(const CNetAddr &ip); static bool Unban(const CNetAddr &ip);
static bool Unban(const CSubNet &ip); static bool Unban(const CSubNet &ip);
static void GetBanned(std::map<CSubNet, int64_t> &banmap); static void GetBanned(std::map<CSubNet, int64_t> &banmap);

1
src/rpcclient.cpp

@ -94,6 +94,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "prioritisetransaction", 1 }, { "prioritisetransaction", 1 },
{ "prioritisetransaction", 2 }, { "prioritisetransaction", 2 },
{ "setban", 2 }, { "setban", 2 },
{ "setban", 3 },
}; };
class CRPCConvertTable class CRPCConvertTable

27
src/rpcnet.cpp

@ -466,7 +466,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp)
return obj; return obj;
} }
Value setban(const Array& params, bool fHelp) UniValue setban(const UniValue& params, bool fHelp)
{ {
string strCommand; string strCommand;
if (params.size() >= 2) if (params.size() >= 2)
@ -474,12 +474,13 @@ Value setban(const Array& params, bool fHelp)
if (fHelp || params.size() < 2 || if (fHelp || params.size() < 2 ||
(strCommand != "add" && strCommand != "remove")) (strCommand != "add" && strCommand != "remove"))
throw runtime_error( throw runtime_error(
"setban \"ip(/netmask)\" \"add|remove\" (bantime)\n" "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n"
"\nAttempts add or remove a IP/Subnet from the banned list.\n" "\nAttempts add or remove a IP/Subnet from the banned list.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\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" "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" "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) 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"
"4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
+ HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
@ -507,10 +508,14 @@ Value setban(const Array& params, bool fHelp)
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned"); throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
int64_t banTime = 0; //use standard bantime if not specified int64_t banTime = 0; //use standard bantime if not specified
if (params.size() == 3 && !params[2].is_null()) if (params.size() >= 3 && !params[2].isNull())
banTime = params[2].get_int64(); banTime = params[2].get_int64();
isSubnet ? CNode::Ban(subNet, banTime) : CNode::Ban(netAddr, banTime); bool absolute = false;
if (params.size() == 4 && params[3].isTrue())
absolute = true;
isSubnet ? CNode::Ban(subNet, banTime, absolute) : CNode::Ban(netAddr, banTime, absolute);
//disconnect possible nodes //disconnect possible nodes
while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr))) while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr)))
@ -522,10 +527,10 @@ Value setban(const Array& params, bool fHelp)
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Unban failed"); throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Unban failed");
} }
return Value::null; return NullUniValue;
} }
Value listbanned(const Array& params, bool fHelp) UniValue listbanned(const UniValue& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
@ -539,10 +544,10 @@ Value listbanned(const Array& params, bool fHelp)
std::map<CSubNet, int64_t> banMap; std::map<CSubNet, int64_t> banMap;
CNode::GetBanned(banMap); CNode::GetBanned(banMap);
Array bannedAddresses; UniValue bannedAddresses(UniValue::VARR);
for (std::map<CSubNet, int64_t>::iterator it = banMap.begin(); it != banMap.end(); it++) for (std::map<CSubNet, int64_t>::iterator it = banMap.begin(); it != banMap.end(); it++)
{ {
Object rec; UniValue rec(UniValue::VOBJ);
rec.push_back(Pair("address", (*it).first.ToString())); rec.push_back(Pair("address", (*it).first.ToString()));
rec.push_back(Pair("banned_untill", (*it).second)); rec.push_back(Pair("banned_untill", (*it).second));
bannedAddresses.push_back(rec); bannedAddresses.push_back(rec);
@ -551,7 +556,7 @@ Value listbanned(const Array& params, bool fHelp)
return bannedAddresses; return bannedAddresses;
} }
Value clearbanned(const Array& params, bool fHelp) UniValue clearbanned(const UniValue& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
@ -564,5 +569,5 @@ Value clearbanned(const Array& params, bool fHelp)
CNode::ClearBanned(); CNode::ClearBanned();
return Value::null; return NullUniValue;
} }

6
src/rpcserver.h

@ -154,9 +154,9 @@ extern UniValue addnode(const UniValue& params, bool fHelp);
extern UniValue disconnectnode(const UniValue& params, bool fHelp); extern UniValue disconnectnode(const UniValue& params, bool fHelp);
extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp); extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp);
extern UniValue getnettotals(const UniValue& params, bool fHelp); extern UniValue getnettotals(const UniValue& params, bool fHelp);
extern UniValue setban(const json_spirit::Array& params, bool fHelp); extern UniValue setban(const UniValue& params, bool fHelp);
extern UniValue listbanned(const json_spirit::Array& params, bool fHelp); extern UniValue listbanned(const UniValue& params, bool fHelp);
extern UniValue clearbanned(const json_spirit::Array& params, bool fHelp); extern UniValue clearbanned(const UniValue& params, bool fHelp);
extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
extern UniValue importprivkey(const UniValue& params, bool fHelp); extern UniValue importprivkey(const UniValue& params, bool fHelp);

25
src/test/rpc_tests.cpp

@ -181,25 +181,40 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
{ {
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
Value r; UniValue r;
BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0 add"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0 add")));
BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.0:8334")), runtime_error); //portnumber for setban not allowed BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.0:8334")), runtime_error); //portnumber for setban not allowed
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
Array ar = r.get_array(); UniValue ar = r.get_array();
Object o1 = ar[0].get_obj(); UniValue o1 = ar[0].get_obj();
Value adr = find_value(o1, "address"); UniValue adr = find_value(o1, "address");
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.255"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.255");
BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));; BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));;
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
ar = r.get_array(); ar = r.get_array();
BOOST_CHECK_EQUAL(ar.size(), 0); BOOST_CHECK_EQUAL(ar.size(), 0);
BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/24 add"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/24 add 1607731200 true")));
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
UniValue banned_until = find_value(o1, "banned_untill");
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0");
BOOST_CHECK_EQUAL(banned_until.get_int64(), 1607731200); // absolute time check
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/24 add 200")));
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
ar = r.get_array(); ar = r.get_array();
o1 = ar[0].get_obj(); o1 = ar[0].get_obj();
adr = find_value(o1, "address"); adr = find_value(o1, "address");
banned_until = find_value(o1, "banned_untill");
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0");
int64_t now = GetTime();
BOOST_CHECK(banned_until.get_int64() > now);
BOOST_CHECK(banned_until.get_int64()-now <= 200);
// must throw an exception because 127.0.0.1 is in already banned suubnet range // must throw an exception because 127.0.0.1 is in already banned suubnet range
BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error); BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error);

Loading…
Cancel
Save