]>
Commit | Line | Data |
---|---|---|
db0e8ccd | 1 | // Copyright (c) 2009-2013 The Bitcoin developers |
70ab73a0 JG |
2 | // Distributed under the MIT/X11 software license, see the accompanying |
3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | |
4 | ||
5 | #include "net.h" | |
6 | #include "bitcoinrpc.h" | |
7 | ||
8 | using namespace json_spirit; | |
9 | using namespace std; | |
10 | ||
11 | Value getconnectioncount(const Array& params, bool fHelp) | |
12 | { | |
13 | if (fHelp || params.size() != 0) | |
14 | throw runtime_error( | |
15 | "getconnectioncount\n" | |
16 | "Returns the number of connections to other nodes."); | |
17 | ||
1006f070 | 18 | LOCK(cs_vNodes); |
70ab73a0 JG |
19 | return (int)vNodes.size(); |
20 | } | |
21 | ||
971bb3e9 JL |
22 | Value ping(const Array& params, bool fHelp) |
23 | { | |
24 | if (fHelp || params.size() != 0) | |
25 | throw runtime_error( | |
26 | "ping\n" | |
27 | "Requests that a ping be sent to all other nodes, to measure ping time.\n" | |
28 | "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n" | |
29 | "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping."); | |
30 | ||
31 | // Request that each node send a ping during next message processing pass | |
32 | LOCK(cs_vNodes); | |
33 | BOOST_FOREACH(CNode* pNode, vNodes) { | |
34 | pNode->fPingQueued = true; | |
35 | } | |
36 | ||
37 | return Value::null; | |
38 | } | |
39 | ||
1006f070 JG |
40 | static void CopyNodeStats(std::vector<CNodeStats>& vstats) |
41 | { | |
42 | vstats.clear(); | |
43 | ||
44 | LOCK(cs_vNodes); | |
45 | vstats.reserve(vNodes.size()); | |
46 | BOOST_FOREACH(CNode* pnode, vNodes) { | |
47 | CNodeStats stats; | |
48 | pnode->copyStats(stats); | |
49 | vstats.push_back(stats); | |
50 | } | |
51 | } | |
52 | ||
53 | Value getpeerinfo(const Array& params, bool fHelp) | |
54 | { | |
55 | if (fHelp || params.size() != 0) | |
56 | throw runtime_error( | |
57 | "getpeerinfo\n" | |
58 | "Returns data about each connected network node."); | |
59 | ||
60 | vector<CNodeStats> vstats; | |
61 | CopyNodeStats(vstats); | |
62 | ||
63 | Array ret; | |
64 | ||
65 | BOOST_FOREACH(const CNodeStats& stats, vstats) { | |
66 | Object obj; | |
67 | ||
68 | obj.push_back(Pair("addr", stats.addrName)); | |
69 | obj.push_back(Pair("services", strprintf("%08"PRI64x, stats.nServices))); | |
70 | obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend)); | |
71 | obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv)); | |
86648a8d PW |
72 | obj.push_back(Pair("bytessent", (boost::int64_t)stats.nSendBytes)); |
73 | obj.push_back(Pair("bytesrecv", (boost::int64_t)stats.nRecvBytes)); | |
1006f070 | 74 | obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected)); |
971bb3e9 JL |
75 | obj.push_back(Pair("pingtime", stats.dPingTime)); |
76 | if (stats.dPingWait > 0.0) | |
77 | obj.push_back(Pair("pingwait", stats.dPingWait)); | |
1006f070 JG |
78 | obj.push_back(Pair("version", stats.nVersion)); |
79 | obj.push_back(Pair("subver", stats.strSubVer)); | |
80 | obj.push_back(Pair("inbound", stats.fInbound)); | |
18e8e437 | 81 | obj.push_back(Pair("startingheight", stats.nStartingHeight)); |
1006f070 | 82 | obj.push_back(Pair("banscore", stats.nMisbehavior)); |
86648a8d PW |
83 | if (stats.fSyncNode) |
84 | obj.push_back(Pair("syncnode", true)); | |
1006f070 JG |
85 | |
86 | ret.push_back(obj); | |
87 | } | |
ea0796bd | 88 | |
1006f070 JG |
89 | return ret; |
90 | } | |
70ab73a0 | 91 | |
72a348fd MC |
92 | Value addnode(const Array& params, bool fHelp) |
93 | { | |
94 | string strCommand; | |
95 | if (params.size() == 2) | |
96 | strCommand = params[1].get_str(); | |
97 | if (fHelp || params.size() != 2 || | |
98 | (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) | |
99 | throw runtime_error( | |
100 | "addnode <node> <add|remove|onetry>\n" | |
101 | "Attempts add or remove <node> from the addnode list or try a connection to <node> once."); | |
102 | ||
103 | string strNode = params[0].get_str(); | |
104 | ||
105 | if (strCommand == "onetry") | |
106 | { | |
107 | CAddress addr; | |
108 | ConnectNode(addr, strNode.c_str()); | |
109 | return Value::null; | |
110 | } | |
111 | ||
112 | LOCK(cs_vAddedNodes); | |
113 | vector<string>::iterator it = vAddedNodes.begin(); | |
114 | for(; it != vAddedNodes.end(); it++) | |
115 | if (strNode == *it) | |
116 | break; | |
117 | ||
118 | if (strCommand == "add") | |
119 | { | |
120 | if (it != vAddedNodes.end()) | |
121 | throw JSONRPCError(-23, "Error: Node already added"); | |
122 | vAddedNodes.push_back(strNode); | |
123 | } | |
124 | else if(strCommand == "remove") | |
125 | { | |
126 | if (it == vAddedNodes.end()) | |
127 | throw JSONRPCError(-24, "Error: Node has not been added."); | |
128 | vAddedNodes.erase(it); | |
129 | } | |
130 | ||
131 | return Value::null; | |
132 | } | |
133 | ||
67a11bd6 MC |
134 | Value getaddednodeinfo(const Array& params, bool fHelp) |
135 | { | |
136 | if (fHelp || params.size() < 1 || params.size() > 2) | |
137 | throw runtime_error( | |
138 | "getaddednodeinfo <dns> [node]\n" | |
139 | "Returns information about the given added node, or all added nodes\n" | |
140 | "(note that onetry addnodes are not listed here)\n" | |
141 | "If dns is false, only a list of added nodes will be provided,\n" | |
142 | "otherwise connected information will also be available."); | |
143 | ||
144 | bool fDns = params[0].get_bool(); | |
145 | ||
146 | list<string> laddedNodes(0); | |
147 | if (params.size() == 1) | |
148 | { | |
149 | LOCK(cs_vAddedNodes); | |
150 | BOOST_FOREACH(string& strAddNode, vAddedNodes) | |
151 | laddedNodes.push_back(strAddNode); | |
152 | } | |
153 | else | |
154 | { | |
155 | string strNode = params[1].get_str(); | |
156 | LOCK(cs_vAddedNodes); | |
157 | BOOST_FOREACH(string& strAddNode, vAddedNodes) | |
158 | if (strAddNode == strNode) | |
159 | { | |
160 | laddedNodes.push_back(strAddNode); | |
161 | break; | |
162 | } | |
163 | if (laddedNodes.size() == 0) | |
164 | throw JSONRPCError(-24, "Error: Node has not been added."); | |
165 | } | |
166 | ||
167 | if (!fDns) | |
168 | { | |
169 | Object ret; | |
170 | BOOST_FOREACH(string& strAddNode, laddedNodes) | |
171 | ret.push_back(Pair("addednode", strAddNode)); | |
172 | return ret; | |
173 | } | |
174 | ||
175 | Array ret; | |
176 | ||
177 | list<pair<string, vector<CService> > > laddedAddreses(0); | |
178 | BOOST_FOREACH(string& strAddNode, laddedNodes) | |
179 | { | |
180 | vector<CService> vservNode(0); | |
0e4b3175 | 181 | if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) |
67a11bd6 MC |
182 | laddedAddreses.push_back(make_pair(strAddNode, vservNode)); |
183 | else | |
184 | { | |
185 | Object obj; | |
186 | obj.push_back(Pair("addednode", strAddNode)); | |
187 | obj.push_back(Pair("connected", false)); | |
188 | Array addresses; | |
189 | obj.push_back(Pair("addresses", addresses)); | |
190 | } | |
191 | } | |
192 | ||
193 | LOCK(cs_vNodes); | |
194 | for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++) | |
195 | { | |
196 | Object obj; | |
197 | obj.push_back(Pair("addednode", it->first)); | |
198 | ||
199 | Array addresses; | |
200 | bool fConnected = false; | |
201 | BOOST_FOREACH(CService& addrNode, it->second) | |
202 | { | |
203 | bool fFound = false; | |
204 | Object node; | |
205 | node.push_back(Pair("address", addrNode.ToString())); | |
206 | BOOST_FOREACH(CNode* pnode, vNodes) | |
207 | if (pnode->addr == addrNode) | |
208 | { | |
209 | fFound = true; | |
210 | fConnected = true; | |
211 | node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound")); | |
212 | break; | |
213 | } | |
214 | if (!fFound) | |
215 | node.push_back(Pair("connected", "false")); | |
216 | addresses.push_back(node); | |
217 | } | |
218 | obj.push_back(Pair("connected", fConnected)); | |
219 | obj.push_back(Pair("addresses", addresses)); | |
220 | ret.push_back(obj); | |
221 | } | |
222 | ||
223 | return ret; | |
224 | } | |
225 | ||
ce14345a SE |
226 | Value getnettotals(const Array& params, bool fHelp) |
227 | { | |
228 | if (fHelp || params.size() > 0) | |
229 | throw runtime_error( | |
230 | "getnettotals\n" | |
231 | "Returns information about network traffic, including bytes in, bytes out,\n" | |
232 | "and current time."); | |
233 | ||
234 | Object obj; | |
235 | obj.push_back(Pair("totalbytesrecv", static_cast< boost::uint64_t>(CNode::GetTotalBytesRecv()))); | |
236 | obj.push_back(Pair("totalbytessent", static_cast<boost::uint64_t>(CNode::GetTotalBytesSent()))); | |
237 | obj.push_back(Pair("timemillis", static_cast<boost::int64_t>(GetTimeMillis()))); | |
238 | return obj; | |
239 | } |