diff options
Diffstat (limited to 'src/rpcnet.cpp')
| -rw-r--r-- | src/rpcnet.cpp | 225 |
1 files changed, 184 insertions, 41 deletions
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 2886f7ada..dd631905f 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -16,12 +16,11 @@ #include <boost/foreach.hpp> -#include "json/json_spirit_value.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; -Value getconnectioncount(const Array& params, bool fHelp) +UniValue getconnectioncount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -34,11 +33,12 @@ Value getconnectioncount(const Array& params, bool fHelp) + HelpExampleRpc("getconnectioncount", "") ); - LOCK(cs_vNodes); + LOCK2(cs_main, cs_vNodes); + return (int)vNodes.size(); } -Value ping(const Array& params, bool fHelp) +UniValue ping(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -52,12 +52,13 @@ Value ping(const Array& params, bool fHelp) ); // Request that each node send a ping during next message processing pass - LOCK(cs_vNodes); + LOCK2(cs_main, cs_vNodes); + BOOST_FOREACH(CNode* pNode, vNodes) { pNode->fPingQueued = true; } - return Value::null; + return NullUniValue; } static void CopyNodeStats(std::vector<CNodeStats>& vstats) @@ -73,7 +74,7 @@ static void CopyNodeStats(std::vector<CNodeStats>& vstats) } } -Value getpeerinfo(const Array& params, bool fHelp) +UniValue getpeerinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -91,6 +92,7 @@ Value getpeerinfo(const Array& params, bool fHelp) " \"bytessent\": n, (numeric) The total bytes sent\n" " \"bytesrecv\": n, (numeric) The total bytes received\n" " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"timeoffset\": ttt, (numeric) The time offset in seconds\n" " \"pingtime\": n, (numeric) ping time\n" " \"pingwait\": n, (numeric) ping wait\n" " \"version\": v, (numeric) The peer version, such as 7001\n" @@ -112,13 +114,15 @@ Value getpeerinfo(const Array& params, bool fHelp) + HelpExampleRpc("getpeerinfo", "") ); + LOCK(cs_main); + vector<CNodeStats> vstats; CopyNodeStats(vstats); - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(const CNodeStats& stats, vstats) { - Object obj; + UniValue obj(UniValue::VOBJ); CNodeStateStats statestats; bool fStateStats = GetNodeStateStats(stats.nodeid, statestats); obj.push_back(Pair("id", stats.nodeid)); @@ -131,6 +135,7 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("bytessent", stats.nSendBytes)); obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); obj.push_back(Pair("conntime", stats.nTimeConnected)); + obj.push_back(Pair("timeoffset", stats.nTimeOffset)); obj.push_back(Pair("pingtime", stats.dPingTime)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); @@ -145,7 +150,7 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("banscore", statestats.nMisbehavior)); obj.push_back(Pair("synced_headers", statestats.nSyncHeight)); obj.push_back(Pair("synced_blocks", statestats.nCommonHeight)); - Array heights; + UniValue heights(UniValue::VARR); BOOST_FOREACH(int height, statestats.vHeightInFlight) { heights.push_back(height); } @@ -159,7 +164,7 @@ Value getpeerinfo(const Array& params, bool fHelp) return ret; } -Value addnode(const Array& params, bool fHelp) +UniValue addnode(const UniValue& params, bool fHelp) { string strCommand; if (params.size() == 2) @@ -184,7 +189,7 @@ Value addnode(const Array& params, bool fHelp) { CAddress addr; OpenNetworkConnection(addr, NULL, strNode.c_str()); - return Value::null; + return NullUniValue; } LOCK(cs_vAddedNodes); @@ -206,10 +211,32 @@ Value addnode(const Array& params, bool fHelp) vAddedNodes.erase(it); } - return Value::null; + return NullUniValue; } -Value getaddednodeinfo(const Array& params, bool fHelp) +UniValue disconnectnode(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "disconnectnode \"node\" \n" + "\nImmediately disconnects from the specified node.\n" + "\nArguments:\n" + "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n" + "\nExamples:\n" + + HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"") + + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"") + ); + + CNode* pNode = FindNode(params[0].get_str()); + if (pNode == NULL) + throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes"); + + pNode->fDisconnect = true; + + return NullUniValue; +} + +UniValue getaddednodeinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -248,29 +275,29 @@ Value getaddednodeinfo(const Array& params, bool fHelp) if (params.size() == 1) { LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) laddedNodes.push_back(strAddNode); } else { string strNode = params[1].get_str(); LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) { if (strAddNode == strNode) { laddedNodes.push_back(strAddNode); break; } + } if (laddedNodes.size() == 0) throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added."); } - Array ret; + UniValue ret(UniValue::VARR); if (!fDns) { - BOOST_FOREACH(string& strAddNode, laddedNodes) - { - Object obj; + BOOST_FOREACH (const std::string& strAddNode, laddedNodes) { + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); ret.push_back(obj); } @@ -278,17 +305,16 @@ Value getaddednodeinfo(const Array& params, bool fHelp) } list<pair<string, vector<CService> > > laddedAddreses(0); - BOOST_FOREACH(string& strAddNode, laddedNodes) - { + BOOST_FOREACH(const std::string& strAddNode, laddedNodes) { vector<CService> vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) laddedAddreses.push_back(make_pair(strAddNode, vservNode)); else { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); obj.push_back(Pair("connected", false)); - Array addresses; + UniValue addresses(UniValue::VARR); obj.push_back(Pair("addresses", addresses)); } } @@ -296,17 +322,16 @@ Value getaddednodeinfo(const Array& params, bool fHelp) LOCK(cs_vNodes); for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", it->first)); - Array addresses; + UniValue addresses(UniValue::VARR); bool fConnected = false; - BOOST_FOREACH(CService& addrNode, it->second) - { + BOOST_FOREACH(const CService& addrNode, it->second) { bool fFound = false; - Object node; + UniValue node(UniValue::VOBJ); node.push_back(Pair("address", addrNode.ToString())); - BOOST_FOREACH(CNode* pnode, vNodes) + BOOST_FOREACH(CNode* pnode, vNodes) { if (pnode->addr == addrNode) { fFound = true; @@ -314,6 +339,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp) node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound")); break; } + } if (!fFound) node.push_back(Pair("connected", "false")); addresses.push_back(node); @@ -326,7 +352,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp) return ret; } -Value getnettotals(const Array& params, bool fHelp) +UniValue getnettotals(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 0) throw runtime_error( @@ -344,34 +370,35 @@ Value getnettotals(const Array& params, bool fHelp) + HelpExampleRpc("getnettotals", "") ); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); obj.push_back(Pair("timemillis", GetTimeMillis())); return obj; } -static Array GetNetworksInfo() +static UniValue GetNetworksInfo() { - Array networks; + UniValue networks(UniValue::VARR); for(int n=0; n<NET_MAX; ++n) { enum Network network = static_cast<enum Network>(n); if(network == NET_UNROUTABLE) continue; proxyType proxy; - Object obj; + UniValue obj(UniValue::VOBJ); GetProxy(network, proxy); obj.push_back(Pair("name", GetNetworkName(network))); obj.push_back(Pair("limited", IsLimited(network))); obj.push_back(Pair("reachable", IsReachable(network))); - obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.ToStringIPPort() : string())); + obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())); + obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials)); networks.push_back(obj); } return networks; } -Value getnetworkinfo(const Array& params, bool fHelp) +UniValue getnetworkinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -403,13 +430,16 @@ Value getnetworkinfo(const Array& params, bool fHelp) " }\n" " ,...\n" " ]\n" + " \"warnings\": \"...\" (string) any network warnings (such as alert messages) \n" "}\n" "\nExamples:\n" + HelpExampleCli("getnetworkinfo", "") + HelpExampleRpc("getnetworkinfo", "") ); - Object obj; + LOCK(cs_main); + + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("subversion", FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()))); @@ -419,12 +449,12 @@ Value getnetworkinfo(const Array& params, bool fHelp) obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("networks", GetNetworksInfo())); obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); - Array localAddresses; + UniValue localAddresses(UniValue::VARR); { LOCK(cs_mapLocalHost); BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost) { - Object rec; + UniValue rec(UniValue::VOBJ); rec.push_back(Pair("address", item.first.ToString())); rec.push_back(Pair("port", item.second.nPort)); rec.push_back(Pair("score", item.second.nScore)); @@ -432,5 +462,118 @@ Value getnetworkinfo(const Array& params, bool fHelp) } } obj.push_back(Pair("localaddresses", localAddresses)); + obj.push_back(Pair("warnings", GetWarnings("statusbar"))); return obj; } + +UniValue setban(const UniValue& params, bool fHelp) +{ + string strCommand; + if (params.size() >= 2) + strCommand = params[1].get_str(); + if (fHelp || params.size() < 2 || + (strCommand != "add" && strCommand != "remove")) + throw runtime_error( + "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n" + "\nAttempts add or remove a IP/Subnet from the banned list.\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" + "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\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" + + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") + + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") + + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400") + ); + + 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 (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].isNull()) + banTime = params[2].get_int64(); + + bool absolute = false; + if (params.size() == 4 && params[3].isTrue()) + absolute = true; + + isSubnet ? CNode::Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : CNode::Ban(netAddr, BanReasonManuallyAdded, banTime, absolute); + + //disconnect possible nodes + while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr))) + bannedNode->fDisconnect = true; + } + else if(strCommand == "remove") + { + if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) )) + throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed"); + } + + DumpBanlist(); //store banlist to disk + return NullUniValue; +} + +UniValue listbanned(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "listbanned\n" + "\nList all banned IPs/Subnets.\n" + "\nExamples:\n" + + HelpExampleCli("listbanned", "") + + HelpExampleRpc("listbanned", "") + ); + + banmap_t banMap; + CNode::GetBanned(banMap); + + UniValue bannedAddresses(UniValue::VARR); + for (banmap_t::iterator it = banMap.begin(); it != banMap.end(); it++) + { + CBanEntry banEntry = (*it).second; + UniValue rec(UniValue::VOBJ); + rec.push_back(Pair("address", (*it).first.ToString())); + rec.push_back(Pair("banned_until", banEntry.nBanUntil)); + rec.push_back(Pair("ban_created", banEntry.nCreateTime)); + rec.push_back(Pair("ban_reason", banEntry.banReasonToString())); + + bannedAddresses.push_back(rec); + } + + return bannedAddresses; +} + +UniValue clearbanned(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "clearbanned\n" + "\nClear all banned IPs.\n" + "\nExamples:\n" + + HelpExampleCli("clearbanned", "") + + HelpExampleRpc("clearbanned", "") + ); + + CNode::ClearBanned(); + DumpBanlist(); //store banlist to disk + + return NullUniValue; +} |