setban: rewrite to UniValue, allow absolute bantime
This commit is contained in:
parent
3de24d7647
commit
4e36e9bcc7
6 changed files with 46 additions and 25 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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")));
|
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");
|
||||||
|
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(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")));
|
||||||
|
ar = r.get_array();
|
||||||
|
o1 = ar[0].get_obj();
|
||||||
|
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");
|
||||||
|
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…
Reference in a new issue