mirror of https://github.com/PurpleI2P/i2pd.git
I2P: End-to-End encrypted and anonymous Internet
https://i2pd.website/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
376 lines
12 KiB
376 lines
12 KiB
/* |
|
* Copyright (c) 2013-2022, The PurpleI2P Project |
|
* |
|
* This file is part of Purple i2pd project and licensed under BSD3 |
|
* |
|
* See full license text in LICENSE file at top of project tree |
|
*/ |
|
|
|
#include <iomanip> |
|
#define BOOST_BIND_GLOBAL_PLACEHOLDERS |
|
#include <boost/lexical_cast.hpp> |
|
#include <boost/property_tree/json_parser.hpp> |
|
|
|
#include "Log.h" |
|
#include "RouterContext.h" |
|
#include "NetDb.hpp" |
|
#include "Tunnel.h" |
|
#include "Transports.h" |
|
#include "version.h" |
|
#include "ClientContext.h" |
|
#include "I2PControlHandlers.h" |
|
|
|
namespace i2p |
|
{ |
|
namespace client |
|
{ |
|
I2PControlHandlers::I2PControlHandlers () |
|
{ |
|
// RouterInfo |
|
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlHandlers::UptimeHandler; |
|
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlHandlers::VersionHandler; |
|
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlHandlers::StatusHandler; |
|
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlHandlers::NetDbKnownPeersHandler; |
|
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlHandlers::NetDbActivePeersHandler; |
|
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlHandlers::InboundBandwidth1S; |
|
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlHandlers::OutboundBandwidth1S; |
|
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlHandlers::NetStatusHandler; |
|
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlHandlers::TunnelsParticipatingHandler; |
|
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlHandlers::TunnelsSuccessRateHandler; |
|
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlHandlers::NetTotalReceivedBytes; |
|
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlHandlers::NetTotalSentBytes; |
|
|
|
// NetworkSetting |
|
m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlHandlers::InboundBandwidthLimit; |
|
m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlHandlers::OutboundBandwidthLimit; |
|
|
|
// ClientServicesInfo |
|
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlHandlers::I2PTunnelInfoHandler; |
|
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlHandlers::HTTPProxyInfoHandler; |
|
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlHandlers::SOCKSInfoHandler; |
|
m_ClientServicesInfoHandlers["SAM"] = &I2PControlHandlers::SAMInfoHandler; |
|
m_ClientServicesInfoHandlers["BOB"] = &I2PControlHandlers::BOBInfoHandler; |
|
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlHandlers::I2CPInfoHandler; |
|
} |
|
|
|
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, int value) const |
|
{ |
|
ss << "\"" << name << "\":" << value; |
|
} |
|
|
|
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value, bool quotes) const |
|
{ |
|
ss << "\"" << name << "\":"; |
|
if (value.length () > 0) |
|
{ |
|
if (quotes) |
|
ss << "\"" << value << "\""; |
|
else |
|
ss << value; |
|
} |
|
else |
|
ss << "null"; |
|
} |
|
|
|
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, double value) const |
|
{ |
|
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value; |
|
} |
|
|
|
void I2PControlHandlers::InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const |
|
{ |
|
std::ostringstream buf; |
|
boost::property_tree::write_json (buf, value, false); |
|
ss << "\"" << name << "\":" << buf.str(); |
|
} |
|
|
|
// RouterInfo |
|
|
|
void I2PControlHandlers::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results) |
|
{ |
|
bool first = true; |
|
for (auto it = params.begin (); it != params.end (); it++) |
|
{ |
|
LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first); |
|
auto it1 = m_RouterInfoHandlers.find (it->first); |
|
if (it1 != m_RouterInfoHandlers.end ()) |
|
{ |
|
if (!first) results << ","; |
|
else first = false; |
|
(this->*(it1->second))(results); |
|
} |
|
else |
|
LogPrint (eLogError, "I2PControl: RouterInfo unknown request ", it->first); |
|
} |
|
} |
|
|
|
void I2PControlHandlers::UptimeHandler (std::ostringstream& results) |
|
{ |
|
InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL), false); |
|
} |
|
|
|
void I2PControlHandlers::VersionHandler (std::ostringstream& results) |
|
{ |
|
InsertParam (results, "i2p.router.version", VERSION); |
|
} |
|
|
|
void I2PControlHandlers::StatusHandler (std::ostringstream& results) |
|
{ |
|
auto dest = i2p::client::context.GetSharedLocalDestination (); |
|
InsertParam (results, "i2p.router.status", (dest && dest->IsReady ()) ? "1" : "0"); |
|
} |
|
|
|
void I2PControlHandlers::NetDbKnownPeersHandler (std::ostringstream& results) |
|
{ |
|
InsertParam (results, "i2p.router.netdb.knownpeers", i2p::data::netdb.GetNumRouters ()); |
|
} |
|
|
|
void I2PControlHandlers::NetDbActivePeersHandler (std::ostringstream& results) |
|
{ |
|
InsertParam (results, "i2p.router.netdb.activepeers", (int)i2p::transport::transports.GetPeers ().size ()); |
|
} |
|
|
|
void I2PControlHandlers::NetStatusHandler (std::ostringstream& results) |
|
{ |
|
InsertParam (results, "i2p.router.net.status", (int)i2p::context.GetStatus ()); |
|
} |
|
|
|
void I2PControlHandlers::TunnelsParticipatingHandler (std::ostringstream& results) |
|
{ |
|
int transit = i2p::tunnel::tunnels.GetTransitTunnels ().size (); |
|
InsertParam (results, "i2p.router.net.tunnels.participating", transit); |
|
} |
|
|
|
void I2PControlHandlers::TunnelsSuccessRateHandler (std::ostringstream& results) |
|
{ |
|
int rate = i2p::tunnel::tunnels.GetTunnelCreationSuccessRate (); |
|
InsertParam (results, "i2p.router.net.tunnels.successrate", rate); |
|
} |
|
|
|
void I2PControlHandlers::InboundBandwidth1S (std::ostringstream& results) |
|
{ |
|
double bw = i2p::transport::transports.GetInBandwidth (); |
|
InsertParam (results, "i2p.router.net.bw.inbound.1s", bw); |
|
} |
|
|
|
void I2PControlHandlers::OutboundBandwidth1S (std::ostringstream& results) |
|
{ |
|
double bw = i2p::transport::transports.GetOutBandwidth (); |
|
InsertParam (results, "i2p.router.net.bw.outbound.1s", bw); |
|
} |
|
|
|
void I2PControlHandlers::NetTotalReceivedBytes (std::ostringstream& results) |
|
{ |
|
InsertParam (results, "i2p.router.net.total.received.bytes", (double)i2p::transport::transports.GetTotalReceivedBytes ()); |
|
} |
|
|
|
void I2PControlHandlers::NetTotalSentBytes (std::ostringstream& results) |
|
{ |
|
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ()); |
|
} |
|
|
|
// network setting |
|
void I2PControlHandlers::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results) |
|
{ |
|
for (auto it = params.begin (); it != params.end (); it++) |
|
{ |
|
LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first); |
|
auto it1 = m_NetworkSettingHandlers.find (it->first); |
|
if (it1 != m_NetworkSettingHandlers.end ()) { |
|
if (it != params.begin ()) results << ","; |
|
(this->*(it1->second))(it->second.data (), results); |
|
} else |
|
LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first); |
|
} |
|
} |
|
|
|
void I2PControlHandlers::InboundBandwidthLimit (const std::string& value, std::ostringstream& results) |
|
{ |
|
if (value != "null") |
|
i2p::context.SetBandwidth (std::atoi(value.c_str())); |
|
int bw = i2p::context.GetBandwidthLimit(); |
|
InsertParam (results, "i2p.router.net.bw.in", bw); |
|
} |
|
|
|
void I2PControlHandlers::OutboundBandwidthLimit (const std::string& value, std::ostringstream& results) |
|
{ |
|
if (value != "null") |
|
i2p::context.SetBandwidth (std::atoi(value.c_str())); |
|
int bw = i2p::context.GetBandwidthLimit(); |
|
InsertParam (results, "i2p.router.net.bw.out", bw); |
|
} |
|
|
|
// ClientServicesInfo |
|
|
|
void I2PControlHandlers::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results) |
|
{ |
|
for (auto it = params.begin (); it != params.end (); it++) |
|
{ |
|
LogPrint (eLogDebug, "I2PControl: ClientServicesInfo request: ", it->first); |
|
auto it1 = m_ClientServicesInfoHandlers.find (it->first); |
|
if (it1 != m_ClientServicesInfoHandlers.end ()) |
|
{ |
|
if (it != params.begin ()) results << ","; |
|
(this->*(it1->second))(results); |
|
} |
|
else |
|
LogPrint (eLogError, "I2PControl: ClientServicesInfo unknown request ", it->first); |
|
} |
|
} |
|
|
|
void I2PControlHandlers::I2PTunnelInfoHandler (std::ostringstream& results) |
|
{ |
|
boost::property_tree::ptree pt; |
|
boost::property_tree::ptree client_tunnels, server_tunnels; |
|
|
|
for (auto& it: i2p::client::context.GetClientTunnels ()) |
|
{ |
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); |
|
boost::property_tree::ptree ct; |
|
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); |
|
client_tunnels.add_child(it.second->GetName (), ct); |
|
} |
|
|
|
auto& serverTunnels = i2p::client::context.GetServerTunnels (); |
|
if (!serverTunnels.empty ()) { |
|
for (auto& it: serverTunnels) |
|
{ |
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); |
|
boost::property_tree::ptree st; |
|
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); |
|
st.put("port", it.second->GetLocalPort ()); |
|
server_tunnels.add_child(it.second->GetName (), st); |
|
} |
|
} |
|
|
|
auto& clientForwards = i2p::client::context.GetClientForwards (); |
|
if (!clientForwards.empty ()) |
|
{ |
|
for (auto& it: clientForwards) |
|
{ |
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); |
|
boost::property_tree::ptree ct; |
|
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); |
|
client_tunnels.add_child(it.second->GetName (), ct); |
|
} |
|
} |
|
|
|
auto& serverForwards = i2p::client::context.GetServerForwards (); |
|
if (!serverForwards.empty ()) |
|
{ |
|
for (auto& it: serverForwards) |
|
{ |
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); |
|
boost::property_tree::ptree st; |
|
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); |
|
server_tunnels.add_child(it.second->GetName (), st); |
|
} |
|
} |
|
|
|
pt.add_child("client", client_tunnels); |
|
pt.add_child("server", server_tunnels); |
|
|
|
InsertParam (results, "I2PTunnel", pt); |
|
} |
|
|
|
void I2PControlHandlers::HTTPProxyInfoHandler (std::ostringstream& results) |
|
{ |
|
boost::property_tree::ptree pt; |
|
|
|
auto httpProxy = i2p::client::context.GetHttpProxy (); |
|
if (httpProxy) |
|
{ |
|
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); |
|
pt.put("enabled", true); |
|
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); |
|
} |
|
else |
|
pt.put("enabled", false); |
|
|
|
InsertParam (results, "HTTPProxy", pt); |
|
} |
|
|
|
void I2PControlHandlers::SOCKSInfoHandler (std::ostringstream& results) |
|
{ |
|
boost::property_tree::ptree pt; |
|
|
|
auto socksProxy = i2p::client::context.GetSocksProxy (); |
|
if (socksProxy) |
|
{ |
|
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); |
|
pt.put("enabled", true); |
|
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); |
|
} |
|
else |
|
pt.put("enabled", false); |
|
|
|
InsertParam (results, "SOCKS", pt); |
|
} |
|
|
|
void I2PControlHandlers::SAMInfoHandler (std::ostringstream& results) |
|
{ |
|
boost::property_tree::ptree pt; |
|
auto sam = i2p::client::context.GetSAMBridge (); |
|
if (sam) |
|
{ |
|
pt.put("enabled", true); |
|
boost::property_tree::ptree sam_sessions; |
|
for (auto& it: sam->GetSessions ()) |
|
{ |
|
boost::property_tree::ptree sam_session, sam_session_sockets; |
|
auto& name = it.second->GetLocalDestination ()->GetNickname (); |
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); |
|
sam_session.put("name", name); |
|
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); |
|
|
|
for (const auto& socket: sam->ListSockets(it.first)) |
|
{ |
|
boost::property_tree::ptree stream; |
|
stream.put("type", socket->GetSocketType ()); |
|
stream.put("peer", socket->GetSocket ().remote_endpoint()); |
|
|
|
sam_session_sockets.push_back(std::make_pair("", stream)); |
|
} |
|
sam_session.add_child("sockets", sam_session_sockets); |
|
sam_sessions.add_child(it.first, sam_session); |
|
} |
|
|
|
pt.add_child("sessions", sam_sessions); |
|
} |
|
else |
|
pt.put("enabled", false); |
|
|
|
InsertParam (results, "SAM", pt); |
|
} |
|
|
|
void I2PControlHandlers::BOBInfoHandler (std::ostringstream& results) |
|
{ |
|
boost::property_tree::ptree pt; |
|
auto bob = i2p::client::context.GetBOBCommandChannel (); |
|
if (bob) |
|
{ |
|
/* TODO more info */ |
|
pt.put("enabled", true); |
|
} |
|
else |
|
pt.put("enabled", false); |
|
|
|
InsertParam (results, "BOB", pt); |
|
} |
|
|
|
void I2PControlHandlers::I2CPInfoHandler (std::ostringstream& results) |
|
{ |
|
boost::property_tree::ptree pt; |
|
auto i2cp = i2p::client::context.GetI2CPServer (); |
|
if (i2cp) |
|
{ |
|
/* TODO more info */ |
|
pt.put("enabled", true); |
|
} |
|
else |
|
pt.put("enabled", false); |
|
|
|
InsertParam (results, "I2CP", pt); |
|
} |
|
} |
|
}
|
|
|