]> Git Repo - VerusCoin.git/blob - src/rpc/net.cpp
Incorporate all Zcash updates through 2.0.7-3 in addition to PBaaS, reserves, etc.
[VerusCoin.git] / src / rpc / net.cpp
1 // Copyright (c) 2009-2014 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php .
4
5 #include "rpc/server.h"
6
7 #include "clientversion.h"
8 #include "main.h"
9 #include "net.h"
10 #include "netbase.h"
11 #include "protocol.h"
12 #include "sync.h"
13 #include "timedata.h"
14 #include "util.h"
15 #include "version.h"
16 #include "deprecation.h"
17
18 #include <boost/foreach.hpp>
19
20 #include <univalue.h>
21
22 using namespace std;
23
24 UniValue getconnectioncount(const UniValue& params, bool fHelp)
25 {
26     if (fHelp || params.size() != 0)
27         throw runtime_error(
28             "getconnectioncount\n"
29             "\nReturns the number of connections to other nodes.\n"
30             "\nbResult:\n"
31             "n          (numeric) The connection count\n"
32             "\nExamples:\n"
33             + HelpExampleCli("getconnectioncount", "")
34             + HelpExampleRpc("getconnectioncount", "")
35         );
36
37     LOCK2(cs_main, cs_vNodes);
38
39     return (int)vNodes.size();
40 }
41
42 UniValue ping(const UniValue& params, bool fHelp)
43 {
44     if (fHelp || params.size() != 0)
45         throw runtime_error(
46             "ping\n"
47             "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
48             "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
49             "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
50             "\nExamples:\n"
51             + HelpExampleCli("ping", "")
52             + HelpExampleRpc("ping", "")
53         );
54
55     // Request that each node send a ping during next message processing pass
56     LOCK2(cs_main, cs_vNodes);
57
58     BOOST_FOREACH(CNode* pNode, vNodes) {
59         pNode->fPingQueued = true;
60     }
61
62     return NullUniValue;
63 }
64
65 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
66 {
67     vstats.clear();
68
69     LOCK(cs_vNodes);
70     vstats.reserve(vNodes.size());
71     BOOST_FOREACH(CNode* pnode, vNodes) {
72         CNodeStats stats;
73         pnode->copyStats(stats);
74         vstats.push_back(stats);
75     }
76 }
77
78 UniValue getpeerinfo(const UniValue& params, bool fHelp)
79 {
80     if (fHelp || params.size() != 0)
81         throw runtime_error(
82             "getpeerinfo\n"
83             "\nReturns data about each connected network node as a json array of objects.\n"
84             "\nbResult:\n"
85             "[\n"
86             "  {\n"
87             "    \"id\": n,                   (numeric) Peer index\n"
88             "    \"addr\":\"host:port\",      (string) The ip address and port of the peer\n"
89             "    \"addrlocal\":\"ip:port\",   (string) local address\n"
90             "    \"services\":\"xxxxxxxxxxxxxxxx\",   (string) The services offered\n"
91             "    \"lastsend\": ttt,           (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
92             "    \"lastrecv\": ttt,           (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
93             "    \"bytessent\": n,            (numeric) The total bytes sent\n"
94             "    \"bytesrecv\": n,            (numeric) The total bytes received\n"
95             "    \"conntime\": ttt,           (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
96             "    \"timeoffset\": ttt,         (numeric) The time offset in seconds\n"
97             "    \"pingtime\": n,             (numeric) ping time\n"
98             "    \"pingwait\": n,             (numeric) ping wait\n"
99             "    \"version\": v,              (numeric) The peer version, such as 170002\n"
100             "    \"subver\": \"/MagicBean:x.y.z[-v]/\",  (string) The string version\n"
101             "    \"inbound\": true|false,     (boolean) Inbound (true) or Outbound (false)\n"
102             "    \"startingheight\": n,       (numeric) The starting height (block) of the peer\n"
103             "    \"banscore\": n,             (numeric) The ban score\n"
104             "    \"synced_headers\": n,       (numeric) The last header we have in common with this peer\n"
105             "    \"synced_blocks\": n,        (numeric) The last block we have in common with this peer\n"
106             "    \"inflight\": [\n"
107             "       n,                        (numeric) The heights of blocks we're currently asking from this peer\n"
108             "       ...\n"
109             "    ]\n"
110             "  }\n"
111             "  ,...\n"
112             "]\n"
113             "\nExamples:\n"
114             + HelpExampleCli("getpeerinfo", "")
115             + HelpExampleRpc("getpeerinfo", "")
116         );
117
118     LOCK(cs_main);
119
120     vector<CNodeStats> vstats;
121     CopyNodeStats(vstats);
122
123     UniValue ret(UniValue::VARR);
124
125     BOOST_FOREACH(const CNodeStats& stats, vstats) {
126         UniValue obj(UniValue::VOBJ);
127         CNodeStateStats statestats;
128         bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
129         obj.push_back(Pair("id", stats.nodeid));
130         obj.push_back(Pair("addr", stats.addrName));
131         if (!(stats.addrLocal.empty()))
132             obj.push_back(Pair("addrlocal", stats.addrLocal));
133         obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
134         obj.push_back(Pair("lastsend", stats.nLastSend));
135         obj.push_back(Pair("lastrecv", stats.nLastRecv));
136         obj.push_back(Pair("bytessent", stats.nSendBytes));
137         obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
138         obj.push_back(Pair("conntime", stats.nTimeConnected));
139         obj.push_back(Pair("timeoffset", stats.nTimeOffset));
140         obj.push_back(Pair("pingtime", stats.dPingTime));
141         if (stats.dPingWait > 0.0)
142             obj.push_back(Pair("pingwait", stats.dPingWait));
143         obj.push_back(Pair("version", stats.nVersion));
144         // Use the sanitized form of subver here, to avoid tricksy remote peers from
145         // corrupting or modifying the JSON output by putting special characters in
146         // their ver message.
147         obj.push_back(Pair("subver", stats.cleanSubVer));
148         obj.push_back(Pair("inbound", stats.fInbound));
149         obj.push_back(Pair("startingheight", stats.nStartingHeight));
150         if (fStateStats) {
151             obj.push_back(Pair("banscore", statestats.nMisbehavior));
152             obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
153             obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
154             UniValue heights(UniValue::VARR);
155             BOOST_FOREACH(int height, statestats.vHeightInFlight) {
156                 heights.push_back(height);
157             }
158             obj.push_back(Pair("inflight", heights));
159         }
160         obj.push_back(Pair("whitelisted", stats.fWhitelisted));
161
162         ret.push_back(obj);
163     }
164
165     return ret;
166 }
167
168 int32_t KOMODO_LONGESTCHAIN;
169 int32_t komodo_longestchain()
170 {
171     int32_t ht,n=0,num=0,maxheight=0,height = 0;
172     vector<CNodeStats> vstats;
173     {
174         LOCK(cs_main);
175         CopyNodeStats(vstats);
176     }
177     BOOST_FOREACH(const CNodeStats& stats, vstats)
178     {
179         //fprintf(stderr,"komodo_longestchain iter.%d\n",n);
180         CNodeStateStats statestats;
181         bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
182         ht = 0;
183         if ( stats.nStartingHeight > ht )
184             ht = stats.nStartingHeight;
185         if ( statestats.nSyncHeight > ht )
186             ht = statestats.nSyncHeight;
187         if ( statestats.nCommonHeight > ht )
188             ht = statestats.nCommonHeight;
189         if ( maxheight == 0 || ht > maxheight*1.01 )
190             maxheight = ht, num = 1;
191         else if ( ht > maxheight*0.99 )
192             num++;
193         n++;
194         if ( ht > height )
195             height = ht;
196     }
197     if ( num > (n >> 1) )
198     {
199         extern char ASSETCHAINS_SYMBOL[];
200         if ( 0 && height != KOMODO_LONGESTCHAIN )
201             fprintf(stderr,"set %s KOMODO_LONGESTCHAIN <- %d\n",ASSETCHAINS_SYMBOL,height);
202         KOMODO_LONGESTCHAIN = height;
203         return(height);
204     }
205     KOMODO_LONGESTCHAIN = 0;
206     return(0);
207 }
208
209 UniValue addnode(const UniValue& params, bool fHelp)
210 {
211     string strCommand;
212     if (params.size() == 2)
213         strCommand = params[1].get_str();
214     if (fHelp || params.size() != 2 ||
215         (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
216         throw runtime_error(
217             "addnode \"node\" \"add|remove|onetry\"\n"
218             "\nAttempts add or remove a node from the addnode list.\n"
219             "Or try a connection to a node once.\n"
220             "\nArguments:\n"
221             "1. \"node\"     (string, required) The node (see getpeerinfo for nodes)\n"
222             "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"
223             "\nExamples:\n"
224             + HelpExampleCli("addnode", "\"192.168.0.6:8233\" \"onetry\"")
225             + HelpExampleRpc("addnode", "\"192.168.0.6:8233\", \"onetry\"")
226         );
227
228     string strNode = params[0].get_str();
229
230     if (strCommand == "onetry")
231     {
232         CAddress addr;
233         OpenNetworkConnection(addr, NULL, strNode.c_str());
234         return NullUniValue;
235     }
236
237     LOCK(cs_vAddedNodes);
238     vector<string>::iterator it = vAddedNodes.begin();
239     for(; it != vAddedNodes.end(); it++)
240         if (strNode == *it)
241             break;
242
243     if (strCommand == "add")
244     {
245         if (it != vAddedNodes.end())
246             throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
247         vAddedNodes.push_back(strNode);
248     }
249     else if(strCommand == "remove")
250     {
251         if (it == vAddedNodes.end())
252             throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
253         vAddedNodes.erase(it);
254     }
255
256     return NullUniValue;
257 }
258
259 UniValue disconnectnode(const UniValue& params, bool fHelp)
260 {
261     if (fHelp || params.size() != 1)
262         throw runtime_error(
263             "disconnectnode \"node\" \n"
264             "\nImmediately disconnects from the specified node.\n"
265             "\nArguments:\n"
266             "1. \"node\"     (string, required) The node (see getpeerinfo for nodes)\n"
267             "\nExamples:\n"
268             + HelpExampleCli("disconnectnode", "\"192.168.0.6:8233\"")
269             + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8233\"")
270         );
271
272     CNode* pNode = FindNode(params[0].get_str());
273     if (pNode == NULL)
274         throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
275
276     pNode->fDisconnect = true;
277
278     return NullUniValue;
279 }
280
281 UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
282 {
283     if (fHelp || params.size() < 1 || params.size() > 2)
284         throw runtime_error(
285             "getaddednodeinfo dns ( \"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             "If dns is false, only a list of added nodes will be provided,\n"
289             "otherwise connected information will also be available.\n"
290             "\nArguments:\n"
291             "1. dns        (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
292             "2. \"node\"   (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
293             "\nResult:\n"
294             "[\n"
295             "  {\n"
296             "    \"addednode\" : \"192.168.0.201\",   (string) The node ip address\n"
297             "    \"connected\" : true|false,          (boolean) If connected\n"
298             "    \"addresses\" : [\n"
299             "       {\n"
300             "         \"address\" : \"192.168.0.201:8233\",  (string) The Komodo server host and port\n"
301             "         \"connected\" : \"outbound\"           (string) connection, inbound or outbound\n"
302             "       }\n"
303             "       ,...\n"
304             "     ]\n"
305             "  }\n"
306             "  ,...\n"
307             "]\n"
308             "\nExamples:\n"
309             + HelpExampleCli("getaddednodeinfo", "true")
310             + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
311             + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
312         );
313
314     bool fDns = params[0].get_bool();
315
316     list<string> laddedNodes(0);
317     if (params.size() == 1)
318     {
319         LOCK(cs_vAddedNodes);
320         BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
321             laddedNodes.push_back(strAddNode);
322     }
323     else
324     {
325         string strNode = params[1].get_str();
326         LOCK(cs_vAddedNodes);
327         BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) {
328             if (strAddNode == strNode)
329             {
330                 laddedNodes.push_back(strAddNode);
331                 break;
332             }
333         }
334         if (laddedNodes.size() == 0)
335             throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
336     }
337
338     UniValue ret(UniValue::VARR);
339     if (!fDns)
340     {
341         BOOST_FOREACH (const std::string& strAddNode, laddedNodes) {
342             UniValue obj(UniValue::VOBJ);
343             obj.push_back(Pair("addednode", strAddNode));
344             ret.push_back(obj);
345         }
346         return ret;
347     }
348
349     list<pair<string, vector<CService> > > laddedAddreses(0);
350     BOOST_FOREACH(const std::string& strAddNode, laddedNodes) {
351         vector<CService> vservNode(0);
352         if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
353             laddedAddreses.push_back(make_pair(strAddNode, vservNode));
354         else
355         {
356             UniValue obj(UniValue::VOBJ);
357             obj.push_back(Pair("addednode", strAddNode));
358             obj.push_back(Pair("connected", false));
359             UniValue addresses(UniValue::VARR);
360             obj.push_back(Pair("addresses", addresses));
361         }
362     }
363
364     LOCK(cs_vNodes);
365     for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
366     {
367         UniValue obj(UniValue::VOBJ);
368         obj.push_back(Pair("addednode", it->first));
369
370         UniValue addresses(UniValue::VARR);
371         bool fConnected = false;
372         BOOST_FOREACH(const CService& addrNode, it->second) {
373             bool fFound = false;
374             UniValue node(UniValue::VOBJ);
375             node.push_back(Pair("address", addrNode.ToString()));
376             BOOST_FOREACH(CNode* pnode, vNodes) {
377                 if (pnode->addr == addrNode)
378                 {
379                     fFound = true;
380                     fConnected = true;
381                     node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
382                     break;
383                 }
384             }
385             if (!fFound)
386                 node.push_back(Pair("connected", "false"));
387             addresses.push_back(node);
388         }
389         obj.push_back(Pair("connected", fConnected));
390         obj.push_back(Pair("addresses", addresses));
391         ret.push_back(obj);
392     }
393
394     return ret;
395 }
396
397 UniValue getnettotals(const UniValue& params, bool fHelp)
398 {
399     if (fHelp || params.size() > 0)
400         throw runtime_error(
401             "getnettotals\n"
402             "\nReturns information about network traffic, including bytes in, bytes out,\n"
403             "and current time.\n"
404             "\nResult:\n"
405             "{\n"
406             "  \"totalbytesrecv\": n,   (numeric) Total bytes received\n"
407             "  \"totalbytessent\": n,   (numeric) Total bytes sent\n"
408             "  \"timemillis\": t        (numeric) Total cpu time\n"
409             "}\n"
410             "\nExamples:\n"
411             + HelpExampleCli("getnettotals", "")
412             + HelpExampleRpc("getnettotals", "")
413        );
414
415     UniValue obj(UniValue::VOBJ);
416     obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
417     obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
418     obj.push_back(Pair("timemillis", GetTimeMillis()));
419     return obj;
420 }
421
422 static UniValue GetNetworksInfo()
423 {
424     UniValue networks(UniValue::VARR);
425     for(int n=0; n<NET_MAX; ++n)
426     {
427         enum Network network = static_cast<enum Network>(n);
428         if(network == NET_UNROUTABLE)
429             continue;
430         proxyType proxy;
431         UniValue obj(UniValue::VOBJ);
432         GetProxy(network, proxy);
433         obj.push_back(Pair("name", GetNetworkName(network)));
434         obj.push_back(Pair("limited", IsLimited(network)));
435         obj.push_back(Pair("reachable", IsReachable(network)));
436         obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()));
437         obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
438         networks.push_back(obj);
439     }
440     return networks;
441 }
442
443 UniValue getdeprecationinfo(const UniValue& params, bool fHelp)
444 {
445     const CChainParams& chainparams = Params();
446     if (fHelp || params.size() != 0 || chainparams.NetworkIDString() != "main")
447         throw runtime_error(
448             "getdeprecationinfo\n"
449             "Returns an object containing current version and deprecation block height. Applicable only on mainnet.\n"
450             "\nResult:\n"
451             "{\n"
452             "  \"version\": xxxxx,                      (numeric) the server version\n"
453             "  \"subversion\": \"/MagicBean:x.y.z[-v]/\",     (string) the server subversion string\n"
454             "  \"deprecationheight\": xxxxx,            (numeric) the block height at which this version will deprecate and shut down\n"
455             "}\n"
456             "\nExamples:\n"
457             + HelpExampleCli("getdeprecationinfo", "")
458             + HelpExampleRpc("getdeprecationinfo", "")
459         );
460
461     UniValue obj(UniValue::VOBJ);
462     obj.push_back(Pair("version", CLIENT_VERSION));
463     obj.push_back(Pair("subversion",
464         FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
465     obj.push_back(Pair("deprecationheight", DEPRECATION_HEIGHT));
466
467     return obj;
468 }
469
470 UniValue getnetworkinfo(const UniValue& params, bool fHelp)
471 {
472     if (fHelp || params.size() != 0)
473         throw runtime_error(
474             "getnetworkinfo\n"
475             "Returns an object containing various state info regarding P2P networking.\n"
476             "\nResult:\n"
477             "{\n"
478             "  \"version\": xxxxx,                      (numeric) the server version\n"
479             "  \"subversion\": \"/MagicBean:x.y.z[-v]/\",     (string) the server subversion string\n"
480             "  \"protocolversion\": xxxxx,              (numeric) the protocol version\n"
481             "  \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
482             "  \"timeoffset\": xxxxx,                   (numeric) the time offset\n"
483             "  \"connections\": xxxxx,                  (numeric) the number of connections\n"
484             "  \"networks\": [                          (array) information per network\n"
485             "  {\n"
486             "    \"name\": \"xxx\",                     (string) network (ipv4, ipv6 or onion)\n"
487             "    \"limited\": true|false,               (boolean) is the network limited using -onlynet?\n"
488             "    \"reachable\": true|false,             (boolean) is the network reachable?\n"
489             "    \"proxy\": \"host:port\"               (string) the proxy that is used for this network, or empty if none\n"
490             "  }\n"
491             "  ,...\n"
492             "  ],\n"
493             "  \"relayfee\": x.xxxxxxxx,                (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
494             "  \"localaddresses\": [                    (array) list of local addresses\n"
495             "  {\n"
496             "    \"address\": \"xxxx\",                 (string) network address\n"
497             "    \"port\": xxx,                         (numeric) network port\n"
498             "    \"score\": xxx                         (numeric) relative score\n"
499             "  }\n"
500             "  ,...\n"
501             "  ]\n"
502             "  \"warnings\": \"...\"                    (string) any network warnings (such as alert messages) \n"
503             "}\n"
504             "\nExamples:\n"
505             + HelpExampleCli("getnetworkinfo", "")
506             + HelpExampleRpc("getnetworkinfo", "")
507         );
508
509     LOCK(cs_main);
510
511     UniValue obj(UniValue::VOBJ);
512     obj.push_back(Pair("version",       CLIENT_VERSION));
513     obj.push_back(Pair("subversion",    strSubVersion));
514     obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
515     obj.push_back(Pair("localservices",       strprintf("%016x", nLocalServices)));
516     obj.push_back(Pair("timeoffset",    GetTimeOffset()));
517     obj.push_back(Pair("connections",   (int)vNodes.size()));
518     obj.push_back(Pair("networks",      GetNetworksInfo()));
519     obj.push_back(Pair("relayfee",      ValueFromAmount(::minRelayTxFee.GetFeePerK())));
520     UniValue localAddresses(UniValue::VARR);
521     {
522         LOCK(cs_mapLocalHost);
523         BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
524         {
525             UniValue rec(UniValue::VOBJ);
526             rec.push_back(Pair("address", item.first.ToString()));
527             rec.push_back(Pair("port", item.second.nPort));
528             rec.push_back(Pair("score", item.second.nScore));
529             localAddresses.push_back(rec);
530         }
531     }
532     obj.push_back(Pair("localaddresses", localAddresses));
533     obj.push_back(Pair("warnings",       GetWarnings("statusbar")));
534     return obj;
535 }
536
537 UniValue setban(const UniValue& params, bool fHelp)
538 {
539     string strCommand;
540     if (params.size() >= 2)
541         strCommand = params[1].get_str();
542     if (fHelp || params.size() < 2 ||
543         (strCommand != "add" && strCommand != "remove"))
544         throw runtime_error(
545                             "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n"
546                             "\nAttempts add or remove a IP/Subnet from the banned list.\n"
547                             "\nArguments:\n"
548                             "1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
549                             "2. \"command\"      (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
550                             "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"
551                             "4. \"absolute\"     (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
552                             "\nExamples:\n"
553                             + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
554                             + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
555                             + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400")
556                             );
557
558     CSubNet subNet;
559     CNetAddr netAddr;
560     bool isSubnet = false;
561
562     if (params[0].get_str().find("/") != string::npos)
563         isSubnet = true;
564
565     if (!isSubnet)
566         netAddr = CNetAddr(params[0].get_str());
567     else
568         subNet = CSubNet(params[0].get_str());
569
570     if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
571         throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
572
573     if (strCommand == "add")
574     {
575         if (isSubnet ? CNode::IsBanned(subNet) : CNode::IsBanned(netAddr))
576             throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
577
578         int64_t banTime = 0; //use standard bantime if not specified
579         if (params.size() >= 3 && !params[2].isNull())
580             banTime = params[2].get_int64();
581
582         bool absolute = false;
583         if (params.size() == 4 && params[3].isTrue())
584             absolute = true;
585
586         isSubnet ? CNode::Ban(subNet, banTime, absolute) : CNode::Ban(netAddr, banTime, absolute);
587
588         //disconnect possible nodes
589         while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr)))
590             bannedNode->fDisconnect = true;
591     }
592     else if(strCommand == "remove")
593     {
594         if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) ))
595             throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed");
596     }
597
598     return NullUniValue;
599 }
600
601 UniValue listbanned(const UniValue& params, bool fHelp)
602 {
603     if (fHelp || params.size() != 0)
604         throw runtime_error(
605                             "listbanned\n"
606                             "\nList all banned IPs/Subnets.\n"
607                             "\nExamples:\n"
608                             + HelpExampleCli("listbanned", "")
609                             + HelpExampleRpc("listbanned", "")
610                             );
611
612     std::map<CSubNet, int64_t> banMap;
613     CNode::GetBanned(banMap);
614
615     UniValue bannedAddresses(UniValue::VARR);
616     for (std::map<CSubNet, int64_t>::iterator it = banMap.begin(); it != banMap.end(); it++)
617     {
618         UniValue rec(UniValue::VOBJ);
619         rec.push_back(Pair("address", (*it).first.ToString()));
620         rec.push_back(Pair("banned_until", (*it).second));
621         bannedAddresses.push_back(rec);
622     }
623
624     return bannedAddresses;
625 }
626
627 UniValue clearbanned(const UniValue& params, bool fHelp)
628 {
629     if (fHelp || params.size() != 0)
630         throw runtime_error(
631                             "clearbanned\n"
632                             "\nClear all banned IPs.\n"
633                             "\nExamples:\n"
634                             + HelpExampleCli("clearbanned", "")
635                             + HelpExampleRpc("clearbanned", "")
636                             );
637
638     CNode::ClearBanned();
639
640     return NullUniValue;
641 }
642
643 static const CRPCCommand commands[] =
644 { //  category              name                      actor (function)         okSafeMode
645   //  --------------------- ------------------------  -----------------------  ----------
646     { "network",            "getconnectioncount",     &getconnectioncount,     true  },
647     { "network",            "getdeprecationinfo",     &getdeprecationinfo,     true  },
648     { "network",            "ping",                   &ping,                   true  },
649     { "network",            "getpeerinfo",            &getpeerinfo,            true  },
650     { "network",            "addnode",                &addnode,                true  },
651     { "network",            "disconnectnode",         &disconnectnode,         true  },
652     { "network",            "getaddednodeinfo",       &getaddednodeinfo,       true  },
653     { "network",            "getnettotals",           &getnettotals,           true  },
654     { "network",            "getnetworkinfo",         &getnetworkinfo,         true  },
655     { "network",            "setban",                 &setban,                 true  },
656     { "network",            "listbanned",             &listbanned,             true  },
657     { "network",            "clearbanned",            &clearbanned,            true  },
658 };
659
660 void RegisterNetRPCCommands(CRPCTable &tableRPC)
661 {
662     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
663         tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
664 }
This page took 0.063361 seconds and 4 git commands to generate.