@@ -42,6 +42,7 @@ static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
42
42
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900 ;
43
43
static const bool DEFAULT_NAMED=false ;
44
44
static const int CONTINUE_EXECUTION=-1 ;
45
+ static constexpr int8_t UNKNOWN_NETWORK{-1 };
45
46
46
47
/* * Default number of blocks to generate for RPC generatetoaddress. */
47
48
static const std::string DEFAULT_NBLOCKS = " 1" ;
@@ -228,6 +229,56 @@ class BaseRequestHandler
228
229
virtual UniValue ProcessReply (const UniValue &batch_in) = 0;
229
230
};
230
231
232
+ /* * Process addrinfo requests */
233
+ class AddrinfoRequestHandler : public BaseRequestHandler
234
+ {
235
+ private:
236
+ static constexpr uint8_t m_networks_size{5 };
237
+ const std::array<std::string, m_networks_size> m_networks{{" ipv4" , " ipv6" , " torv2" , " torv3" , " i2p" }};
238
+ int8_t NetworkStringToId (const std::string& str) const
239
+ {
240
+ for (uint8_t i = 0 ; i < m_networks_size; ++i) {
241
+ if (str == m_networks.at (i)) return i;
242
+ }
243
+ return UNKNOWN_NETWORK;
244
+ }
245
+
246
+ public:
247
+ UniValue PrepareRequest (const std::string& method, const std::vector<std::string>& args) override
248
+ {
249
+ if (!args.empty ()) {
250
+ throw std::runtime_error (" -addrinfo takes no arguments" );
251
+ }
252
+ UniValue params{RPCConvertValues (" getnodeaddresses" , std::vector<std::string>{{" 0" }})};
253
+ return JSONRPCRequestObj (" getnodeaddresses" , params, 1 );
254
+ }
255
+
256
+ UniValue ProcessReply (const UniValue& reply) override
257
+ {
258
+ // Count the number of peers we know by network, including torv2 versus torv3.
259
+ std::array<uint64_t , m_networks_size> counts{{}};
260
+ for (const UniValue& node : reply[" result" ].getValues ()) {
261
+ std::string network_name{node[" network" ].get_str ()};
262
+ if (network_name == " onion" ) {
263
+ network_name = node[" address" ].get_str ().size () > 22 ? " torv3" : " torv2" ;
264
+ }
265
+ const int8_t network_id{NetworkStringToId (network_name)};
266
+ if (network_id == UNKNOWN_NETWORK) continue ;
267
+ ++counts.at (network_id);
268
+ }
269
+ // Prepare result to return to user.
270
+ UniValue result{UniValue::VOBJ}, addresses{UniValue::VOBJ};
271
+ uint64_t total{0 }; // Total address count
272
+ for (uint8_t i = 0 ; i < m_networks_size; ++i) {
273
+ addresses.pushKV (m_networks.at (i), counts.at (i));
274
+ total += counts.at (i);
275
+ }
276
+ addresses.pushKV (" total" , total);
277
+ result.pushKV (" addresses_known" , addresses);
278
+ return JSONRPCReplyObj (result, NullUniValue, 1 );
279
+ }
280
+ };
281
+
231
282
/* * Process getinfo requests */
232
283
class GetinfoRequestHandler : public BaseRequestHandler
233
284
{
@@ -299,7 +350,6 @@ class GetinfoRequestHandler: public BaseRequestHandler
299
350
class NetinfoRequestHandler : public BaseRequestHandler
300
351
{
301
352
private:
302
- static constexpr int8_t UNKNOWN_NETWORK{-1 };
303
353
static constexpr uint8_t m_networks_size{4 };
304
354
static constexpr uint8_t MAX_DETAIL_LEVEL{4 };
305
355
const std::array<std::string, m_networks_size> m_networks{{" ipv4" , " ipv6" , " onion" , " i2p" }};
0 commit comments