LCOV - code coverage report
Current view: top level - src - rpcnet.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 154 279 55.2 %
Date: 2015-10-12 22:39:14 Functions: 11 15 73.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11