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.
268 lines
8.5 KiB
268 lines
8.5 KiB
#ifndef I2PCONTROL_H__ |
|
#define I2PCONTROL_H__ |
|
|
|
#include <boost/property_tree/ptree.hpp> |
|
#include <string> |
|
#include <map> |
|
#include <functional> |
|
#include <mutex> |
|
#include <boost/asio.hpp> |
|
|
|
namespace i2p { |
|
|
|
// Forward declaration |
|
namespace tunnel { class Tunnel; } |
|
|
|
namespace client { |
|
namespace i2pcontrol { |
|
|
|
namespace constants { |
|
|
|
const char DEFAULT_PASSWORD[] = "itoopie"; |
|
const uint64_t TOKEN_LIFETIME = 600; // Token lifetime in seconds |
|
const std::size_t TOKEN_SIZE = 8; // Token size in bytes |
|
|
|
const char PROPERTY_ID[] = "id"; |
|
const char PROPERTY_METHOD[] = "method"; |
|
const char PROPERTY_PARAMS[] = "params"; |
|
const char PROPERTY_RESULT[] = "result"; |
|
|
|
// methods |
|
const char METHOD_AUTHENTICATE[] = "Authenticate"; |
|
const char METHOD_ECHO[] = "Echo"; |
|
const char METHOD_I2PCONTROL[] = "I2PControl"; |
|
const char METHOD_ROUTER_INFO[] = "RouterInfo"; |
|
const char METHOD_ROUTER_MANAGER[] = "RouterManager"; |
|
const char METHOD_NETWORK_SETTING[] = "NetworkSetting"; |
|
|
|
// params |
|
const char PARAM_API[] = "API"; |
|
const char PARAM_PASSWORD[] = "Password"; |
|
const char PARAM_TOKEN[] = "Token"; |
|
const char PARAM_ECHO[] = "Echo"; |
|
const char PARAM_RESULT[] = "Result"; |
|
|
|
// I2PControl |
|
const char I2PCONTROL_ADDRESS[] = "i2pcontrol.address"; |
|
const char I2PCONTROL_PASSWORD[] = "i2pcontrol.password"; |
|
const char I2PCONTROL_PORT[] = "i2pcontrol.port"; |
|
|
|
// RouterInfo requests |
|
const char ROUTER_INFO_UPTIME[] = "i2p.router.uptime"; |
|
const char ROUTER_INFO_VERSION[] = "i2p.router.version"; |
|
const char ROUTER_INFO_STATUS[] = "i2p.router.status"; |
|
const char ROUTER_INFO_DATAPATH[] = "i2p.router.datapath"; |
|
const char ROUTER_INFO_NETDB_KNOWNPEERS[] = "i2p.router.netdb.knownpeers"; |
|
const char ROUTER_INFO_NETDB_ACTIVEPEERS[] = "i2p.router.netdb.activepeers"; |
|
const char ROUTER_INFO_NETDB_FLOODFILLS[] = "i2p.router.netdb.floodfills"; |
|
const char ROUTER_INFO_NETDB_LEASESETS[] = "i2p.router.netdb.leasesets"; |
|
const char ROUTER_INFO_NET_STATUS[] = "i2p.router.net.status"; |
|
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_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_OB_1S[] = "i2p.router.net.bw.outbound.1s"; |
|
|
|
// RouterManager requests |
|
const char ROUTER_MANAGER_SHUTDOWN[] = "Shutdown"; |
|
const char ROUTER_MANAGER_SHUTDOWN_GRACEFUL[] = "ShutdownGraceful"; |
|
const char ROUTER_MANAGER_RESEED[] = "Reseed"; |
|
|
|
} // 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. |
|
* @note authentication tokens are per-session |
|
* @note I2PControlSession must always be used as a std::shared_ptr |
|
* @warning an I2PControlSession must be destroyed before its io_service |
|
*/ |
|
class I2PControlSession : public std::enable_shared_from_this<I2PControlSession> { |
|
|
|
public: |
|
enum class ErrorCode { |
|
None = 0, |
|
// JSON-RPC2 |
|
MethodNotFound = 32601, |
|
InvalidParameters = 32602, |
|
InvalidRequest = 32600, |
|
InternalError = 32603, |
|
ParseError = 32700, |
|
// I2PControl specific |
|
InvalidPassword = 32001, |
|
NoToken = 32002, |
|
NonexistentToken = 32003, |
|
ExpiredToken = 32004, |
|
UnspecifiedVersion = 32005, |
|
UnsupportedVersion = 32006 |
|
}; |
|
|
|
class Response { |
|
std::string id; |
|
std::string version; |
|
ErrorCode error; |
|
std::map<std::string, std::string> parameters; |
|
|
|
public: |
|
Response(const std::string& version = "2.0"); |
|
std::string toJsonString() const; |
|
|
|
/** |
|
* Set an output parameter to a specified string. |
|
* @todo escape quotes |
|
*/ |
|
void setParam(const std::string& param, const std::string& value); |
|
|
|
/** |
|
* Set an output parameter to a specified integer. |
|
*/ |
|
void setParam(const std::string& param, int value); |
|
|
|
/** |
|
* Set an output parameter to a specified double. |
|
*/ |
|
void setParam(const std::string& param, double value); |
|
|
|
/** |
|
* Set an output parameter to a specified Json object. |
|
*/ |
|
void setParam(const std::string& param, const JsonObject& value); |
|
|
|
void setError(ErrorCode code); |
|
void setId(const std::string& identifier); |
|
|
|
std::string getErrorMsg() const; |
|
}; |
|
|
|
/** |
|
* Sets up the appropriate handlers. |
|
* @param pass the password required to authenticate (i.e. obtains a token) |
|
* @param ios the parent io_service object, must remain valid throughout |
|
* the lifetime of this I2PControlSession. |
|
*/ |
|
I2PControlSession(boost::asio::io_service& ios, |
|
const std::string& pass = constants::DEFAULT_PASSWORD); |
|
|
|
/** |
|
* Starts the I2PControlSession. |
|
* In essence, this starts the expireTokensTimer. |
|
* @note should always be called after construction |
|
*/ |
|
void start(); |
|
|
|
/** |
|
* Cancels all operations that are waiting. |
|
* @note it's a good idea to call this before destruction (shared_ptr reset) |
|
*/ |
|
void stop(); |
|
|
|
/** |
|
* Handle a json string with I2PControl instructions. |
|
*/ |
|
Response handleRequest(std::stringstream& request); |
|
private: |
|
// For convenience |
|
typedef boost::property_tree::ptree PropertyTree; |
|
// Handler types |
|
typedef void (I2PControlSession::*MethodHandler)( |
|
const PropertyTree& pt, Response& results |
|
); |
|
typedef void (I2PControlSession::*RequestHandler)(Response& results); |
|
|
|
/** |
|
* Tries to authenticate by checking whether the given token is valid. |
|
* Sets the appropriate error code in the given response. |
|
*/ |
|
bool authenticate(const PropertyTree& pt, Response& response); |
|
|
|
/** |
|
* Generate a random authentication token. |
|
* @return 8 random bytes as a hexadecimal string |
|
*/ |
|
std::string generateToken() const; |
|
|
|
void startExpireTokensJob(); |
|
|
|
/** |
|
* Expire tokens that are too old. |
|
*/ |
|
void expireTokens(const boost::system::error_code& error); |
|
|
|
// Method handlers |
|
void handleAuthenticate(const PropertyTree& pt, Response& response); |
|
void handleEcho(const PropertyTree& pt, Response& response); |
|
void handleI2PControl(const PropertyTree& pt, Response& response); |
|
void handleRouterInfo(const PropertyTree& pt, Response& response); |
|
void handleRouterManager(const PropertyTree& pt, Response& response); |
|
void handleNetworkSetting(const PropertyTree& pt, Response& response); |
|
|
|
// RouterInfo handlers |
|
void handleUptime(Response& response); |
|
void handleVersion(Response& response); |
|
void handleStatus(Response& response); |
|
void handleDatapath(Response& response); |
|
void handleNetDbKnownPeers(Response& response); |
|
void handleNetDbActivePeers(Response& response); |
|
void handleNetDbFloodfills(Response& response); |
|
void handleNetDbLeaseSets(Response& response); |
|
void handleNetStatus(Response& response); |
|
|
|
void handleTunnelsParticipating(Response& response); |
|
void handleTunnelsCreationSuccess(Response& response); |
|
void handleTunnelsInList(Response& response); |
|
void handleTunnelsOutList(Response& response); |
|
|
|
void handleInBandwidth1S(Response& response); |
|
void handleOutBandwidth1S(Response& response); |
|
|
|
// RouterManager handlers |
|
void handleShutdown(Response& response); |
|
void handleShutdownGraceful(Response& response); |
|
void handleReseed(Response& response); |
|
|
|
std::string password; |
|
std::map<std::string, uint64_t> tokens; |
|
std::mutex tokensMutex; |
|
|
|
std::map<std::string, MethodHandler> methodHandlers; |
|
std::map<std::string, RequestHandler> routerInfoHandlers; |
|
std::map<std::string, RequestHandler> routerManagerHandlers; |
|
std::map<std::string, RequestHandler> networkSettingHandlers; |
|
|
|
boost::asio::io_service& service; |
|
boost::asio::deadline_timer shutdownTimer; |
|
boost::asio::deadline_timer expireTokensTimer; |
|
}; |
|
|
|
} |
|
} |
|
} |
|
|
|
#endif // I2PCONTROL_H__
|
|
|