mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
Add basic inbound tunnel information to webui.
This commit is contained in:
parent
19557a0908
commit
f04f556b75
@ -24,6 +24,64 @@ namespace i2p {
|
|||||||
namespace client {
|
namespace client {
|
||||||
namespace i2pcontrol {
|
namespace i2pcontrol {
|
||||||
|
|
||||||
|
JsonObject::JsonObject(const std::string& value)
|
||||||
|
: children(), value("\"" + value + "\"")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject::JsonObject(int value)
|
||||||
|
: children(), value(std::to_string(value))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject::JsonObject(double v)
|
||||||
|
: children(), value()
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::fixed << std::setprecision(2) << v;
|
||||||
|
value = oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject& JsonObject::operator[](const std::string& key)
|
||||||
|
{
|
||||||
|
return children[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string JsonObject::toString() const
|
||||||
|
{
|
||||||
|
if(children.empty())
|
||||||
|
return value;
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << '{';
|
||||||
|
for(auto it = children.begin(); it != children.end(); ++it) {
|
||||||
|
if(it != children.begin())
|
||||||
|
oss << ',';
|
||||||
|
oss << '"' << it->first << "\":" << it->second.toString();
|
||||||
|
}
|
||||||
|
oss << '}';
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject tunnelToJsonObject(i2p::tunnel::Tunnel* tunnel)
|
||||||
|
{
|
||||||
|
JsonObject obj;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
tunnel->GetTunnelConfig()->Print(ss); // TODO: use a JsonObject
|
||||||
|
obj["layout"] = JsonObject(ss.str());
|
||||||
|
|
||||||
|
const auto state = tunnel->GetState();
|
||||||
|
if(state == i2p::tunnel::eTunnelStateFailed)
|
||||||
|
obj["state"] = JsonObject("failed");
|
||||||
|
else if(state == i2p::tunnel::eTunnelStateExpiring)
|
||||||
|
obj["state"] = JsonObject("expiring");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
I2PControlSession::Response::Response(const std::string& version)
|
I2PControlSession::Response::Response(const std::string& version)
|
||||||
: id(), version(version), error(ErrorCode::None), parameters()
|
: id(), version(version), error(ErrorCode::None), parameters()
|
||||||
{
|
{
|
||||||
@ -92,6 +150,11 @@ void I2PControlSession::Response::setParam(const std::string& param, double valu
|
|||||||
parameters[param] = oss.str();
|
parameters[param] = oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I2PControlSession::Response::setParam(const std::string& param, const JsonObject& value)
|
||||||
|
{
|
||||||
|
parameters[param] = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
void I2PControlSession::Response::setError(ErrorCode code)
|
void I2PControlSession::Response::setError(ErrorCode code)
|
||||||
{
|
{
|
||||||
error = code;
|
error = code;
|
||||||
@ -126,6 +189,8 @@ I2PControlSession::I2PControlSession(boost::asio::io_service& ios, const std::st
|
|||||||
routerInfoHandlers[ROUTER_INFO_NET_STATUS] = &I2PControlSession::handleNetStatus;
|
routerInfoHandlers[ROUTER_INFO_NET_STATUS] = &I2PControlSession::handleNetStatus;
|
||||||
routerInfoHandlers[ROUTER_INFO_TUNNELS_PARTICIPATING] = &I2PControlSession::handleTunnelsParticipating;
|
routerInfoHandlers[ROUTER_INFO_TUNNELS_PARTICIPATING] = &I2PControlSession::handleTunnelsParticipating;
|
||||||
routerInfoHandlers[ROUTER_INFO_TUNNELS_CREATION_SUCCESS] = &I2PControlSession::handleTunnelsCreationSuccess;
|
routerInfoHandlers[ROUTER_INFO_TUNNELS_CREATION_SUCCESS] = &I2PControlSession::handleTunnelsCreationSuccess;
|
||||||
|
routerInfoHandlers[ROUTER_INFO_TUNNELS_IN_LIST] = &I2PControlSession::handleTunnelsInList;
|
||||||
|
routerInfoHandlers[ROUTER_INFO_TUNNELS_OUT_LIST] = &I2PControlSession::handleTunnelsOutList;
|
||||||
routerInfoHandlers[ROUTER_INFO_BW_IB_1S] = &I2PControlSession::handleInBandwidth1S;
|
routerInfoHandlers[ROUTER_INFO_BW_IB_1S] = &I2PControlSession::handleInBandwidth1S;
|
||||||
routerInfoHandlers[ROUTER_INFO_BW_OB_1S] = &I2PControlSession::handleOutBandwidth1S;
|
routerInfoHandlers[ROUTER_INFO_BW_OB_1S] = &I2PControlSession::handleOutBandwidth1S;
|
||||||
|
|
||||||
@ -368,6 +433,33 @@ void I2PControlSession::handleTunnelsCreationSuccess(Response& response)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I2PControlSession::handleTunnelsInList(Response& response)
|
||||||
|
{
|
||||||
|
JsonObject list;
|
||||||
|
|
||||||
|
for(auto pair : i2p::tunnel::tunnels.GetInboundTunnels()) {
|
||||||
|
const std::string id = std::to_string(pair.first);
|
||||||
|
list[id] = tunnelToJsonObject(pair.second.get());
|
||||||
|
list[id]["bytes"] = JsonObject(
|
||||||
|
static_cast<int>(pair.second->GetNumReceivedBytes())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
response.setParam(constants::ROUTER_INFO_TUNNELS_IN_LIST, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PControlSession::handleTunnelsOutList(Response& response)
|
||||||
|
{
|
||||||
|
JsonObject list;
|
||||||
|
for(auto tunnel : i2p::tunnel::tunnels.GetOutboundTunnels()) {
|
||||||
|
const std::string id = std::to_string(tunnel->GetTunnelID());
|
||||||
|
list[id] = tunnelToJsonObject(tunnel.get());
|
||||||
|
list[id]["bytes"] = JsonObject(
|
||||||
|
static_cast<int>(tunnel->GetNumSentBytes())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
response.setParam(constants::ROUTER_INFO_TUNNELS_OUT_LIST, list);
|
||||||
|
}
|
||||||
|
|
||||||
void I2PControlSession::handleInBandwidth1S(Response& response)
|
void I2PControlSession::handleInBandwidth1S(Response& response)
|
||||||
{
|
{
|
||||||
response.setParam(
|
response.setParam(
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
namespace tunnel { class Tunnel; }
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
namespace i2pcontrol {
|
namespace i2pcontrol {
|
||||||
|
|
||||||
@ -54,7 +58,10 @@ const char ROUTER_INFO_NETDB_FLOODFILLS[] = "i2p.router.netdb.floodfills";
|
|||||||
const char ROUTER_INFO_NETDB_LEASESETS[] = "i2p.router.netdb.leasesets";
|
const char ROUTER_INFO_NETDB_LEASESETS[] = "i2p.router.netdb.leasesets";
|
||||||
const char ROUTER_INFO_NET_STATUS[] = "i2p.router.net.status";
|
const char ROUTER_INFO_NET_STATUS[] = "i2p.router.net.status";
|
||||||
const char ROUTER_INFO_TUNNELS_PARTICIPATING[] = "i2p.router.net.tunnels.participating";
|
const char ROUTER_INFO_TUNNELS_PARTICIPATING[] = "i2p.router.net.tunnels.participating";
|
||||||
|
// TODO: Probably better to use the standard GetRate instead
|
||||||
const char ROUTER_INFO_TUNNELS_CREATION_SUCCESS[] = "i2p.router.net.tunnels.creationsuccessrate";
|
const char ROUTER_INFO_TUNNELS_CREATION_SUCCESS[] = "i2p.router.net.tunnels.creationsuccessrate";
|
||||||
|
const char ROUTER_INFO_TUNNELS_IN_LIST[] = "i2p.router.net.tunnels.inbound.list";
|
||||||
|
const char ROUTER_INFO_TUNNELS_OUT_LIST[] = "i2p.router.net.tunnels.outbound.list";
|
||||||
const char ROUTER_INFO_BW_IB_1S[] = "i2p.router.net.bw.inbound.1s";
|
const char ROUTER_INFO_BW_IB_1S[] = "i2p.router.net.bw.inbound.1s";
|
||||||
const char ROUTER_INFO_BW_OB_1S[] = "i2p.router.net.bw.outbound.1s";
|
const char ROUTER_INFO_BW_OB_1S[] = "i2p.router.net.bw.outbound.1s";
|
||||||
|
|
||||||
@ -65,6 +72,32 @@ const char ROUTER_MANAGER_RESEED[] = "Reseed";
|
|||||||
|
|
||||||
} // constants
|
} // constants
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Json object, provides functionality to convert to string.
|
||||||
|
*/
|
||||||
|
class JsonObject {
|
||||||
|
|
||||||
|
public:
|
||||||
|
JsonObject() = default;
|
||||||
|
|
||||||
|
JsonObject(const std::string& value);
|
||||||
|
|
||||||
|
JsonObject(int value);
|
||||||
|
|
||||||
|
JsonObject(double value);
|
||||||
|
|
||||||
|
JsonObject& operator[](const std::string& key);
|
||||||
|
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, JsonObject> children;
|
||||||
|
std::string value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
JsonObject tunnelToJsonObject(i2p::tunnel::Tunnel* tunnel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Null" I2P control implementation, does not do actual networking.
|
* "Null" I2P control implementation, does not do actual networking.
|
||||||
* @note authentication tokens are per-session
|
* @note authentication tokens are per-session
|
||||||
@ -106,9 +139,22 @@ public:
|
|||||||
* @todo escape quotes
|
* @todo escape quotes
|
||||||
*/
|
*/
|
||||||
void setParam(const std::string& param, const std::string& value);
|
void setParam(const std::string& param, const std::string& value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an ouptut parameter to a specified integer.
|
||||||
|
*/
|
||||||
void setParam(const std::string& param, int value);
|
void setParam(const std::string& param, int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an ouptut parameter to a specified double.
|
||||||
|
*/
|
||||||
void setParam(const std::string& param, double value);
|
void setParam(const std::string& param, double value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an ouptut parameter to a specified Json object.
|
||||||
|
*/
|
||||||
|
void setParam(const std::string& param, const JsonObject& value);
|
||||||
|
|
||||||
void setError(ErrorCode code);
|
void setError(ErrorCode code);
|
||||||
void setId(const std::string& identifier);
|
void setId(const std::string& identifier);
|
||||||
|
|
||||||
@ -187,8 +233,12 @@ private:
|
|||||||
void handleNetDbFloodfills(Response& response);
|
void handleNetDbFloodfills(Response& response);
|
||||||
void handleNetDbLeaseSets(Response& response);
|
void handleNetDbLeaseSets(Response& response);
|
||||||
void handleNetStatus(Response& response);
|
void handleNetStatus(Response& response);
|
||||||
|
|
||||||
void handleTunnelsParticipating(Response& response);
|
void handleTunnelsParticipating(Response& response);
|
||||||
void handleTunnelsCreationSuccess(Response& response);
|
void handleTunnelsCreationSuccess(Response& response);
|
||||||
|
void handleTunnelsInList(Response& response);
|
||||||
|
void handleTunnelsOutList(Response& response);
|
||||||
|
|
||||||
void handleInBandwidth1S(Response& response);
|
void handleInBandwidth1S(Response& response);
|
||||||
void handleOutBandwidth1S(Response& response);
|
void handleOutBandwidth1S(Response& response);
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ std::string getMimeType(const std::string& filename)
|
|||||||
const std::string ext = filename.substr(filename.find_last_of("."));
|
const std::string ext = filename.substr(filename.find_last_of("."));
|
||||||
if(ext == ".css")
|
if(ext == ".css")
|
||||||
return "text/css";
|
return "text/css";
|
||||||
else if(ext == ".css")
|
else if(ext == ".js")
|
||||||
return "text/javascript";
|
return "text/javascript";
|
||||||
else if(ext == ".html" || ext == ".htm")
|
else if(ext == ".html" || ext == ".htm")
|
||||||
return "text/html";
|
return "text/html";
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<a href="netdb.html" class="menu-link">Network Database</a>
|
<a href="netdb.html" class="menu-link">Network Database</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="menu-item">
|
||||||
|
<a href="tunnels.html" class="menu-link">Tunnels</a>
|
||||||
|
</li>
|
||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<a href="config.html" class="menu-link">Configure</a>
|
<a href="config.html" class="menu-link">Configure</a>
|
||||||
</li>
|
</li>
|
||||||
|
66
webui/tunnels.html
Normal file
66
webui/tunnels.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Purple I2P 0.10.0 Webconsole</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="css/main.css">
|
||||||
|
<script type="text/javascript" src="javascript/I2PControl.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function updateNetDbInfo(result, session) {
|
||||||
|
if(session.error) {
|
||||||
|
alert("Error: " + session.error["message"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var table = document.getElementById("tunnels").getElementsByTagName("tbody")[0];
|
||||||
|
|
||||||
|
for(id in result["i2p.router.net.tunnels.inbound.list"]) {
|
||||||
|
if(!result["i2p.router.net.tunnels.inbound.list"].hasOwnProperty(id))
|
||||||
|
continue;
|
||||||
|
var tunnel = result["i2p.router.net.tunnels.inbound.list"][id];
|
||||||
|
|
||||||
|
var row = table.insertRow(table.rows.length);
|
||||||
|
row.insertCell(0).appendChild(document.createTextNode(id));
|
||||||
|
row.insertCell(1).appendChild(document.createTextNode(tunnel["status"] ? tunnel["status"] : "running"));
|
||||||
|
row.insertCell(2).appendChild(document.createTextNode(tunnel["layout"]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestNetDbInfo(session) {
|
||||||
|
session.request("RouterInfo", {
|
||||||
|
"i2p.router.net.tunnels.inbound.list" : "",
|
||||||
|
}, updateNetDbInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
var session = new I2PControl.Session("itoopie");
|
||||||
|
session.start(function() { requestNetDbInfo(session); });
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<h1>i2pd router console</h1>
|
||||||
|
<h2>Tunnel List</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
<table id="tunnels">
|
||||||
|
<thead>
|
||||||
|
<th>Tunnel ID</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Overview</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--#include virtual="menu.html" -->
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user