Merge #10502: scripted-diff: Remove BOOST_FOREACH, Q_FOREACH and PAIRTYPE
[bitcoinplatinum.git] / src / rpc / net.cpp
blobd6f9f0059c40303dd1e8dd5b7e35e132214c01ca
1 // Copyright (c) 2009-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "rpc/server.h"
7 #include "chainparams.h"
8 #include "clientversion.h"
9 #include "validation.h"
10 #include "net.h"
11 #include "net_processing.h"
12 #include "netbase.h"
13 #include "policy/policy.h"
14 #include "protocol.h"
15 #include "sync.h"
16 #include "timedata.h"
17 #include "ui_interface.h"
18 #include "util.h"
19 #include "utilstrencodings.h"
20 #include "version.h"
22 #include <boost/foreach.hpp>
24 #include <univalue.h>
26 UniValue getconnectioncount(const JSONRPCRequest& request)
28 if (request.fHelp || request.params.size() != 0)
29 throw std::runtime_error(
30 "getconnectioncount\n"
31 "\nReturns the number of connections to other nodes.\n"
32 "\nResult:\n"
33 "n (numeric) The connection count\n"
34 "\nExamples:\n"
35 + HelpExampleCli("getconnectioncount", "")
36 + HelpExampleRpc("getconnectioncount", "")
39 if(!g_connman)
40 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
42 return (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL);
45 UniValue ping(const JSONRPCRequest& request)
47 if (request.fHelp || request.params.size() != 0)
48 throw std::runtime_error(
49 "ping\n"
50 "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
51 "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
52 "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
53 "\nExamples:\n"
54 + HelpExampleCli("ping", "")
55 + HelpExampleRpc("ping", "")
58 if(!g_connman)
59 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
61 // Request that each node send a ping during next message processing pass
62 g_connman->ForEachNode([](CNode* pnode) {
63 pnode->fPingQueued = true;
64 });
65 return NullUniValue;
68 UniValue getpeerinfo(const JSONRPCRequest& request)
70 if (request.fHelp || request.params.size() != 0)
71 throw std::runtime_error(
72 "getpeerinfo\n"
73 "\nReturns data about each connected network node as a json array of objects.\n"
74 "\nResult:\n"
75 "[\n"
76 " {\n"
77 " \"id\": n, (numeric) Peer index\n"
78 " \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
79 " \"addrbind\":\"ip:port\", (string) Bind address of the connection to the peer\n"
80 " \"addrlocal\":\"ip:port\", (string) Local address as reported by the peer\n"
81 " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
82 " \"relaytxes\":true|false, (boolean) Whether peer has asked us to relay transactions to it\n"
83 " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
84 " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
85 " \"bytessent\": n, (numeric) The total bytes sent\n"
86 " \"bytesrecv\": n, (numeric) The total bytes received\n"
87 " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
88 " \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
89 " \"pingtime\": n, (numeric) ping time (if available)\n"
90 " \"minping\": n, (numeric) minimum observed ping time (if any at all)\n"
91 " \"pingwait\": n, (numeric) ping wait (if non-zero)\n"
92 " \"version\": v, (numeric) The peer version, such as 7001\n"
93 " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
94 " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
95 " \"addnode\": true|false, (boolean) Whether connection was due to addnode and is using an addnode slot\n"
96 " \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
97 " \"banscore\": n, (numeric) The ban score\n"
98 " \"synced_headers\": n, (numeric) The last header we have in common with this peer\n"
99 " \"synced_blocks\": n, (numeric) The last block we have in common with this peer\n"
100 " \"inflight\": [\n"
101 " n, (numeric) The heights of blocks we're currently asking from this peer\n"
102 " ...\n"
103 " ],\n"
104 " \"whitelisted\": true|false, (boolean) Whether the peer is whitelisted\n"
105 " \"bytessent_per_msg\": {\n"
106 " \"addr\": n, (numeric) The total bytes sent aggregated by message type\n"
107 " ...\n"
108 " },\n"
109 " \"bytesrecv_per_msg\": {\n"
110 " \"addr\": n, (numeric) The total bytes received aggregated by message type\n"
111 " ...\n"
112 " }\n"
113 " }\n"
114 " ,...\n"
115 "]\n"
116 "\nExamples:\n"
117 + HelpExampleCli("getpeerinfo", "")
118 + HelpExampleRpc("getpeerinfo", "")
121 if(!g_connman)
122 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
124 std::vector<CNodeStats> vstats;
125 g_connman->GetNodeStats(vstats);
127 UniValue ret(UniValue::VARR);
129 for (const CNodeStats& stats : vstats) {
130 UniValue obj(UniValue::VOBJ);
131 CNodeStateStats statestats;
132 bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
133 obj.push_back(Pair("id", stats.nodeid));
134 obj.push_back(Pair("addr", stats.addrName));
135 if (!(stats.addrLocal.empty()))
136 obj.push_back(Pair("addrlocal", stats.addrLocal));
137 if (stats.addrBind.IsValid())
138 obj.push_back(Pair("addrbind", stats.addrBind.ToString()));
139 obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
140 obj.push_back(Pair("relaytxes", stats.fRelayTxes));
141 obj.push_back(Pair("lastsend", stats.nLastSend));
142 obj.push_back(Pair("lastrecv", stats.nLastRecv));
143 obj.push_back(Pair("bytessent", stats.nSendBytes));
144 obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
145 obj.push_back(Pair("conntime", stats.nTimeConnected));
146 obj.push_back(Pair("timeoffset", stats.nTimeOffset));
147 if (stats.dPingTime > 0.0)
148 obj.push_back(Pair("pingtime", stats.dPingTime));
149 if (stats.dMinPing < std::numeric_limits<int64_t>::max()/1e6)
150 obj.push_back(Pair("minping", stats.dMinPing));
151 if (stats.dPingWait > 0.0)
152 obj.push_back(Pair("pingwait", stats.dPingWait));
153 obj.push_back(Pair("version", stats.nVersion));
154 // Use the sanitized form of subver here, to avoid tricksy remote peers from
155 // corrupting or modifying the JSON output by putting special characters in
156 // their ver message.
157 obj.push_back(Pair("subver", stats.cleanSubVer));
158 obj.push_back(Pair("inbound", stats.fInbound));
159 obj.push_back(Pair("addnode", stats.fAddnode));
160 obj.push_back(Pair("startingheight", stats.nStartingHeight));
161 if (fStateStats) {
162 obj.push_back(Pair("banscore", statestats.nMisbehavior));
163 obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
164 obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
165 UniValue heights(UniValue::VARR);
166 for (int height : statestats.vHeightInFlight) {
167 heights.push_back(height);
169 obj.push_back(Pair("inflight", heights));
171 obj.push_back(Pair("whitelisted", stats.fWhitelisted));
173 UniValue sendPerMsgCmd(UniValue::VOBJ);
174 for (const mapMsgCmdSize::value_type &i : stats.mapSendBytesPerMsgCmd) {
175 if (i.second > 0)
176 sendPerMsgCmd.push_back(Pair(i.first, i.second));
178 obj.push_back(Pair("bytessent_per_msg", sendPerMsgCmd));
180 UniValue recvPerMsgCmd(UniValue::VOBJ);
181 for (const mapMsgCmdSize::value_type &i : stats.mapRecvBytesPerMsgCmd) {
182 if (i.second > 0)
183 recvPerMsgCmd.push_back(Pair(i.first, i.second));
185 obj.push_back(Pair("bytesrecv_per_msg", recvPerMsgCmd));
187 ret.push_back(obj);
190 return ret;
193 UniValue addnode(const JSONRPCRequest& request)
195 std::string strCommand;
196 if (request.params.size() == 2)
197 strCommand = request.params[1].get_str();
198 if (request.fHelp || request.params.size() != 2 ||
199 (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
200 throw std::runtime_error(
201 "addnode \"node\" \"add|remove|onetry\"\n"
202 "\nAttempts add or remove a node from the addnode list.\n"
203 "Or try a connection to a node once.\n"
204 "\nArguments:\n"
205 "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
206 "2. \"command\" (string, required) 'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once\n"
207 "\nExamples:\n"
208 + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
209 + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
212 if(!g_connman)
213 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
215 std::string strNode = request.params[0].get_str();
217 if (strCommand == "onetry")
219 CAddress addr;
220 g_connman->OpenNetworkConnection(addr, false, NULL, strNode.c_str());
221 return NullUniValue;
224 if (strCommand == "add")
226 if(!g_connman->AddNode(strNode))
227 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
229 else if(strCommand == "remove")
231 if(!g_connman->RemoveAddedNode(strNode))
232 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
235 return NullUniValue;
238 UniValue disconnectnode(const JSONRPCRequest& request)
240 if (request.fHelp || request.params.size() == 0 || request.params.size() >= 3)
241 throw std::runtime_error(
242 "disconnectnode \"[address]\" [nodeid]\n"
243 "\nImmediately disconnects from the specified peer node.\n"
244 "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
245 "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n"
246 "\nArguments:\n"
247 "1. \"address\" (string, optional) The IP address/port of the node\n"
248 "2. \"nodeid\" (number, optional) The node ID (see getpeerinfo for node IDs)\n"
249 "\nExamples:\n"
250 + HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"")
251 + HelpExampleCli("disconnectnode", "\"\" 1")
252 + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
253 + HelpExampleRpc("disconnectnode", "\"\", 1")
256 if(!g_connman)
257 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
259 bool success;
260 const UniValue &address_arg = request.params[0];
261 const UniValue &id_arg = request.params.size() < 2 ? NullUniValue : request.params[1];
263 if (!address_arg.isNull() && id_arg.isNull()) {
264 /* handle disconnect-by-address */
265 success = g_connman->DisconnectNode(address_arg.get_str());
266 } else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
267 /* handle disconnect-by-id */
268 NodeId nodeid = (NodeId) id_arg.get_int64();
269 success = g_connman->DisconnectNode(nodeid);
270 } else {
271 throw JSONRPCError(RPC_INVALID_PARAMS, "Only one of address and nodeid should be provided.");
274 if (!success) {
275 throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
278 return NullUniValue;
281 UniValue getaddednodeinfo(const JSONRPCRequest& request)
283 if (request.fHelp || request.params.size() > 1)
284 throw std::runtime_error(
285 "getaddednodeinfo ( \"node\" )\n"
286 "\nReturns information about the given added node, or all added nodes\n"
287 "(note that onetry addnodes are not listed here)\n"
288 "\nArguments:\n"
289 "1. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
290 "\nResult:\n"
291 "[\n"
292 " {\n"
293 " \"addednode\" : \"192.168.0.201\", (string) The node ip address or name (as provided to addnode)\n"
294 " \"connected\" : true|false, (boolean) If connected\n"
295 " \"addresses\" : [ (list of objects) Only when connected = true\n"
296 " {\n"
297 " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server IP and port we're connected to\n"
298 " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
299 " }\n"
300 " ]\n"
301 " }\n"
302 " ,...\n"
303 "]\n"
304 "\nExamples:\n"
305 + HelpExampleCli("getaddednodeinfo", "true")
306 + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
307 + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
310 if(!g_connman)
311 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
313 std::vector<AddedNodeInfo> vInfo = g_connman->GetAddedNodeInfo();
315 if (request.params.size() == 1) {
316 bool found = false;
317 for (const AddedNodeInfo& info : vInfo) {
318 if (info.strAddedNode == request.params[0].get_str()) {
319 vInfo.assign(1, info);
320 found = true;
321 break;
324 if (!found) {
325 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
329 UniValue ret(UniValue::VARR);
331 for (const AddedNodeInfo& info : vInfo) {
332 UniValue obj(UniValue::VOBJ);
333 obj.push_back(Pair("addednode", info.strAddedNode));
334 obj.push_back(Pair("connected", info.fConnected));
335 UniValue addresses(UniValue::VARR);
336 if (info.fConnected) {
337 UniValue address(UniValue::VOBJ);
338 address.push_back(Pair("address", info.resolvedAddress.ToString()));
339 address.push_back(Pair("connected", info.fInbound ? "inbound" : "outbound"));
340 addresses.push_back(address);
342 obj.push_back(Pair("addresses", addresses));
343 ret.push_back(obj);
346 return ret;
349 UniValue getnettotals(const JSONRPCRequest& request)
351 if (request.fHelp || request.params.size() > 0)
352 throw std::runtime_error(
353 "getnettotals\n"
354 "\nReturns information about network traffic, including bytes in, bytes out,\n"
355 "and current time.\n"
356 "\nResult:\n"
357 "{\n"
358 " \"totalbytesrecv\": n, (numeric) Total bytes received\n"
359 " \"totalbytessent\": n, (numeric) Total bytes sent\n"
360 " \"timemillis\": t, (numeric) Current UNIX time in milliseconds\n"
361 " \"uploadtarget\":\n"
362 " {\n"
363 " \"timeframe\": n, (numeric) Length of the measuring timeframe in seconds\n"
364 " \"target\": n, (numeric) Target in bytes\n"
365 " \"target_reached\": true|false, (boolean) True if target is reached\n"
366 " \"serve_historical_blocks\": true|false, (boolean) True if serving historical blocks\n"
367 " \"bytes_left_in_cycle\": t, (numeric) Bytes left in current time cycle\n"
368 " \"time_left_in_cycle\": t (numeric) Seconds left in current time cycle\n"
369 " }\n"
370 "}\n"
371 "\nExamples:\n"
372 + HelpExampleCli("getnettotals", "")
373 + HelpExampleRpc("getnettotals", "")
375 if(!g_connman)
376 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
378 UniValue obj(UniValue::VOBJ);
379 obj.push_back(Pair("totalbytesrecv", g_connman->GetTotalBytesRecv()));
380 obj.push_back(Pair("totalbytessent", g_connman->GetTotalBytesSent()));
381 obj.push_back(Pair("timemillis", GetTimeMillis()));
383 UniValue outboundLimit(UniValue::VOBJ);
384 outboundLimit.push_back(Pair("timeframe", g_connman->GetMaxOutboundTimeframe()));
385 outboundLimit.push_back(Pair("target", g_connman->GetMaxOutboundTarget()));
386 outboundLimit.push_back(Pair("target_reached", g_connman->OutboundTargetReached(false)));
387 outboundLimit.push_back(Pair("serve_historical_blocks", !g_connman->OutboundTargetReached(true)));
388 outboundLimit.push_back(Pair("bytes_left_in_cycle", g_connman->GetOutboundTargetBytesLeft()));
389 outboundLimit.push_back(Pair("time_left_in_cycle", g_connman->GetMaxOutboundTimeLeftInCycle()));
390 obj.push_back(Pair("uploadtarget", outboundLimit));
391 return obj;
394 static UniValue GetNetworksInfo()
396 UniValue networks(UniValue::VARR);
397 for(int n=0; n<NET_MAX; ++n)
399 enum Network network = static_cast<enum Network>(n);
400 if(network == NET_UNROUTABLE)
401 continue;
402 proxyType proxy;
403 UniValue obj(UniValue::VOBJ);
404 GetProxy(network, proxy);
405 obj.push_back(Pair("name", GetNetworkName(network)));
406 obj.push_back(Pair("limited", IsLimited(network)));
407 obj.push_back(Pair("reachable", IsReachable(network)));
408 obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string()));
409 obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
410 networks.push_back(obj);
412 return networks;
415 UniValue getnetworkinfo(const JSONRPCRequest& request)
417 if (request.fHelp || request.params.size() != 0)
418 throw std::runtime_error(
419 "getnetworkinfo\n"
420 "Returns an object containing various state info regarding P2P networking.\n"
421 "\nResult:\n"
422 "{\n"
423 " \"version\": xxxxx, (numeric) the server version\n"
424 " \"subversion\": \"/Satoshi:x.x.x/\", (string) the server subversion string\n"
425 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
426 " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
427 " \"localrelay\": true|false, (bool) true if transaction relay is requested from peers\n"
428 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
429 " \"connections\": xxxxx, (numeric) the number of connections\n"
430 " \"networkactive\": true|false, (bool) whether p2p networking is enabled\n"
431 " \"networks\": [ (array) information per network\n"
432 " {\n"
433 " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
434 " \"limited\": true|false, (boolean) is the network limited using -onlynet?\n"
435 " \"reachable\": true|false, (boolean) is the network reachable?\n"
436 " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
437 " \"proxy_randomize_credentials\": true|false, (string) Whether randomized credentials are used\n"
438 " }\n"
439 " ,...\n"
440 " ],\n"
441 " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB\n"
442 " \"incrementalfee\": x.xxxxxxxx, (numeric) minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB\n"
443 " \"localaddresses\": [ (array) list of local addresses\n"
444 " {\n"
445 " \"address\": \"xxxx\", (string) network address\n"
446 " \"port\": xxx, (numeric) network port\n"
447 " \"score\": xxx (numeric) relative score\n"
448 " }\n"
449 " ,...\n"
450 " ]\n"
451 " \"warnings\": \"...\" (string) any network warnings\n"
452 "}\n"
453 "\nExamples:\n"
454 + HelpExampleCli("getnetworkinfo", "")
455 + HelpExampleRpc("getnetworkinfo", "")
458 LOCK(cs_main);
459 UniValue obj(UniValue::VOBJ);
460 obj.push_back(Pair("version", CLIENT_VERSION));
461 obj.push_back(Pair("subversion", strSubVersion));
462 obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
463 if(g_connman)
464 obj.push_back(Pair("localservices", strprintf("%016x", g_connman->GetLocalServices())));
465 obj.push_back(Pair("localrelay", fRelayTxes));
466 obj.push_back(Pair("timeoffset", GetTimeOffset()));
467 if (g_connman) {
468 obj.push_back(Pair("networkactive", g_connman->GetNetworkActive()));
469 obj.push_back(Pair("connections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL)));
471 obj.push_back(Pair("networks", GetNetworksInfo()));
472 obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
473 obj.push_back(Pair("incrementalfee", ValueFromAmount(::incrementalRelayFee.GetFeePerK())));
474 UniValue localAddresses(UniValue::VARR);
476 LOCK(cs_mapLocalHost);
477 for (const std::pair<CNetAddr, LocalServiceInfo> &item : mapLocalHost)
479 UniValue rec(UniValue::VOBJ);
480 rec.push_back(Pair("address", item.first.ToString()));
481 rec.push_back(Pair("port", item.second.nPort));
482 rec.push_back(Pair("score", item.second.nScore));
483 localAddresses.push_back(rec);
486 obj.push_back(Pair("localaddresses", localAddresses));
487 obj.push_back(Pair("warnings", GetWarnings("statusbar")));
488 return obj;
491 UniValue setban(const JSONRPCRequest& request)
493 std::string strCommand;
494 if (request.params.size() >= 2)
495 strCommand = request.params[1].get_str();
496 if (request.fHelp || request.params.size() < 2 ||
497 (strCommand != "add" && strCommand != "remove"))
498 throw std::runtime_error(
499 "setban \"subnet\" \"add|remove\" (bantime) (absolute)\n"
500 "\nAttempts add or remove a IP/Subnet from the banned list.\n"
501 "\nArguments:\n"
502 "1. \"subnet\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
503 "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
504 "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"
505 "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
506 "\nExamples:\n"
507 + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
508 + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
509 + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400")
511 if(!g_connman)
512 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
514 CSubNet subNet;
515 CNetAddr netAddr;
516 bool isSubnet = false;
518 if (request.params[0].get_str().find("/") != std::string::npos)
519 isSubnet = true;
521 if (!isSubnet) {
522 CNetAddr resolved;
523 LookupHost(request.params[0].get_str().c_str(), resolved, false);
524 netAddr = resolved;
526 else
527 LookupSubNet(request.params[0].get_str().c_str(), subNet);
529 if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
530 throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Invalid IP/Subnet");
532 if (strCommand == "add")
534 if (isSubnet ? g_connman->IsBanned(subNet) : g_connman->IsBanned(netAddr))
535 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
537 int64_t banTime = 0; //use standard bantime if not specified
538 if (request.params.size() >= 3 && !request.params[2].isNull())
539 banTime = request.params[2].get_int64();
541 bool absolute = false;
542 if (request.params.size() == 4 && request.params[3].isTrue())
543 absolute = true;
545 isSubnet ? g_connman->Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : g_connman->Ban(netAddr, BanReasonManuallyAdded, banTime, absolute);
547 else if(strCommand == "remove")
549 if (!( isSubnet ? g_connman->Unban(subNet) : g_connman->Unban(netAddr) ))
550 throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Unban failed. Requested address/subnet was not previously banned.");
552 return NullUniValue;
555 UniValue listbanned(const JSONRPCRequest& request)
557 if (request.fHelp || request.params.size() != 0)
558 throw std::runtime_error(
559 "listbanned\n"
560 "\nList all banned IPs/Subnets.\n"
561 "\nExamples:\n"
562 + HelpExampleCli("listbanned", "")
563 + HelpExampleRpc("listbanned", "")
566 if(!g_connman)
567 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
569 banmap_t banMap;
570 g_connman->GetBanned(banMap);
572 UniValue bannedAddresses(UniValue::VARR);
573 for (banmap_t::iterator it = banMap.begin(); it != banMap.end(); it++)
575 CBanEntry banEntry = (*it).second;
576 UniValue rec(UniValue::VOBJ);
577 rec.push_back(Pair("address", (*it).first.ToString()));
578 rec.push_back(Pair("banned_until", banEntry.nBanUntil));
579 rec.push_back(Pair("ban_created", banEntry.nCreateTime));
580 rec.push_back(Pair("ban_reason", banEntry.banReasonToString()));
582 bannedAddresses.push_back(rec);
585 return bannedAddresses;
588 UniValue clearbanned(const JSONRPCRequest& request)
590 if (request.fHelp || request.params.size() != 0)
591 throw std::runtime_error(
592 "clearbanned\n"
593 "\nClear all banned IPs.\n"
594 "\nExamples:\n"
595 + HelpExampleCli("clearbanned", "")
596 + HelpExampleRpc("clearbanned", "")
598 if(!g_connman)
599 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
601 g_connman->ClearBanned();
603 return NullUniValue;
606 UniValue setnetworkactive(const JSONRPCRequest& request)
608 if (request.fHelp || request.params.size() != 1) {
609 throw std::runtime_error(
610 "setnetworkactive true|false\n"
611 "\nDisable/enable all p2p network activity.\n"
612 "\nArguments:\n"
613 "1. \"state\" (boolean, required) true to enable networking, false to disable\n"
617 if (!g_connman) {
618 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
621 g_connman->SetNetworkActive(request.params[0].get_bool());
623 return g_connman->GetNetworkActive();
626 static const CRPCCommand commands[] =
627 { // category name actor (function) okSafeMode
628 // --------------------- ------------------------ ----------------------- ----------
629 { "network", "getconnectioncount", &getconnectioncount, true, {} },
630 { "network", "ping", &ping, true, {} },
631 { "network", "getpeerinfo", &getpeerinfo, true, {} },
632 { "network", "addnode", &addnode, true, {"node","command"} },
633 { "network", "disconnectnode", &disconnectnode, true, {"address", "nodeid"} },
634 { "network", "getaddednodeinfo", &getaddednodeinfo, true, {"node"} },
635 { "network", "getnettotals", &getnettotals, true, {} },
636 { "network", "getnetworkinfo", &getnetworkinfo, true, {} },
637 { "network", "setban", &setban, true, {"subnet", "command", "bantime", "absolute"} },
638 { "network", "listbanned", &listbanned, true, {} },
639 { "network", "clearbanned", &clearbanned, true, {} },
640 { "network", "setnetworkactive", &setnetworkactive, true, {"state"} },
643 void RegisterNetRPCCommands(CRPCTable &t)
645 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
646 t.appendCommand(commands[vcidx].name, &commands[vcidx]);