mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-10 05:11:10 +00:00
Merge branch 'new-cmdline' into openssl
Conflicts: ClientContext.cpp Daemon.cpp I2PControl.cpp I2PControl.h docs/configuration.md
This commit is contained in:
commit
900fc1cb46
@ -396,7 +396,7 @@ namespace client
|
|||||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Addresbook: subscriptions.txt not found");
|
LogPrint (eLogWarning, "Addresbook: subscriptions.txt not found in datadir");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
|
#include "Config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
@ -37,46 +38,58 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> localDestination;
|
std::shared_ptr<ClientDestination> localDestination;
|
||||||
// proxies
|
bool httproxy; i2p::config::GetOption("httpproxy.enabled", httproxy);
|
||||||
std::string proxyKeys = i2p::util::config::GetArg("-proxykeys", "");
|
if (httproxy) {
|
||||||
if (proxyKeys.length () > 0)
|
std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys);
|
||||||
{
|
std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr);
|
||||||
i2p::data::PrivateKeys keys;
|
uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort);
|
||||||
LoadPrivateKeys (keys, proxyKeys);
|
LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
||||||
localDestination = CreateNewLocalDestination (keys, false);
|
if (httpProxyKeys.length () > 0)
|
||||||
|
{
|
||||||
|
i2p::data::PrivateKeys keys;
|
||||||
|
LoadPrivateKeys (keys, httpProxyKeys);
|
||||||
|
localDestination = CreateNewLocalDestination (keys, false);
|
||||||
|
}
|
||||||
|
m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, localDestination);
|
||||||
|
m_HttpProxy->Start();
|
||||||
}
|
}
|
||||||
std::string httpProxyAddr = i2p::util::config::GetArg("-httpproxyaddress", "127.0.0.1");
|
|
||||||
uint16_t httpProxyPort = i2p::util::config::GetArg("-httpproxyport", 4444);
|
|
||||||
LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
|
||||||
m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, localDestination);
|
|
||||||
m_HttpProxy->Start();
|
|
||||||
|
|
||||||
std::string socksProxyAddr = i2p::util::config::GetArg("-socksproxyaddress", "127.0.0.1");
|
bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy);
|
||||||
uint16_t socksProxyPort = i2p::util::config::GetArg("-socksproxyport", 4447);
|
if (socksproxy) {
|
||||||
std::string socksOutProxyAddr = i2p::util::config::GetArg("-socksoutproxyaddress", "");
|
std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys);
|
||||||
uint16_t socksOutProxyPort = i2p::util::config::GetArg("-socksoutproxyport", 0);
|
std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr);
|
||||||
LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort);
|
uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort);
|
||||||
m_SocksProxy = new i2p::proxy::SOCKSProxy(socksProxyAddr, socksProxyPort, socksOutProxyAddr, socksOutProxyPort, localDestination);
|
std::string socksOutProxyAddr; i2p::config::GetOption("socksproxy.outproxy", socksOutProxyAddr);
|
||||||
m_SocksProxy->Start();
|
uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort);
|
||||||
|
LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort);
|
||||||
|
if (socksProxyKeys.length () > 0)
|
||||||
|
{
|
||||||
|
i2p::data::PrivateKeys keys;
|
||||||
|
LoadPrivateKeys (keys, socksProxyKeys);
|
||||||
|
localDestination = CreateNewLocalDestination (keys, false);
|
||||||
|
}
|
||||||
|
m_SocksProxy = new i2p::proxy::SOCKSProxy(socksProxyAddr, socksProxyPort, socksOutProxyAddr, socksOutProxyPort, localDestination);
|
||||||
|
m_SocksProxy->Start();
|
||||||
|
}
|
||||||
|
|
||||||
// I2P tunnels
|
// I2P tunnels
|
||||||
ReadTunnels ();
|
ReadTunnels ();
|
||||||
|
|
||||||
// SAM
|
// SAM
|
||||||
std::string samAddr = i2p::util::config::GetArg("-samaddress", "127.0.0.1");
|
bool sam; i2p::config::GetOption("sam.enabled", sam);
|
||||||
uint16_t samPort = i2p::util::config::GetArg("-samport", 0);
|
if (sam) {
|
||||||
if (samPort)
|
std::string samAddr; i2p::config::GetOption("sam.address", samAddr);
|
||||||
{
|
uint16_t samPort; i2p::config::GetOption("sam.port", samPort);
|
||||||
LogPrint(eLogInfo, "Clients: starting SAM bridge at", samAddr, ":", samPort);
|
LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort);
|
||||||
m_SamBridge = new SAMBridge (samAddr, samPort);
|
m_SamBridge = new SAMBridge (samAddr, samPort);
|
||||||
m_SamBridge->Start ();
|
m_SamBridge->Start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOB
|
// BOB
|
||||||
std::string bobAddr = i2p::util::config::GetArg("-bobaddress", "127.0.0.1");
|
bool bob; i2p::config::GetOption("bob.enabled", bob);
|
||||||
uint16_t bobPort = i2p::util::config::GetArg("-bobport", 0);
|
if (bob) {
|
||||||
if (bobPort)
|
std::string bobAddr; i2p::config::GetOption("bob.address", bobAddr);
|
||||||
{
|
uint16_t bobPort; i2p::config::GetOption("bob.port", bobPort);
|
||||||
LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort);
|
LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort);
|
||||||
m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort);
|
m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort);
|
||||||
m_BOBCommandChannel->Start ();
|
m_BOBCommandChannel->Start ();
|
||||||
|
225
Config.cpp
Normal file
225
Config.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2016, 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 <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <boost/program_options/cmdline.hpp>
|
||||||
|
#include <boost/program_options/options_description.hpp>
|
||||||
|
#include <boost/program_options/parsers.hpp>
|
||||||
|
#include <boost/program_options/variables_map.hpp>
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
using namespace boost::program_options;
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace config {
|
||||||
|
options_description m_OptionsDesc;
|
||||||
|
variables_map m_Options;
|
||||||
|
|
||||||
|
/* list of renamed options */
|
||||||
|
std::map<std::string, std::string> remapped_options = {
|
||||||
|
{ "tunnelscfg", "tunconf" },
|
||||||
|
{ "v6", "ipv6" },
|
||||||
|
{ "httpaddress", "http.address" },
|
||||||
|
{ "httpport", "http.port" },
|
||||||
|
{ "httpproxyaddress", "httpproxy.address" },
|
||||||
|
{ "httpproxyport", "httpproxy.port" },
|
||||||
|
{ "socksproxyaddress", "socksproxy.address" },
|
||||||
|
{ "socksproxyport", "socksproxy.port" },
|
||||||
|
{ "samaddress", "sam.address" },
|
||||||
|
{ "samport", "sam.port" },
|
||||||
|
{ "bobaddress", "bob.address" },
|
||||||
|
{ "bobport", "bob.port" },
|
||||||
|
{ "i2pcontroladdress", "i2pcontrol.address" },
|
||||||
|
{ "i2pcontroladdress", "i2pcontrol.port" },
|
||||||
|
{ "proxykeys", "httpproxy.keys" },
|
||||||
|
};
|
||||||
|
/* list of options, that loose their argument and become simple switch */
|
||||||
|
std::set<std::string> boolean_options = {
|
||||||
|
"daemon", "floodfill", "notransit", "service", "ipv6"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* this function is a solid piece of shit, remove it after 2.6.0 */
|
||||||
|
std::pair<std::string, std::string> old_syntax_parser(const std::string& s) {
|
||||||
|
std::string name = "";
|
||||||
|
std::string value = "";
|
||||||
|
std::size_t pos = 0;
|
||||||
|
/* shortcuts -- -h */
|
||||||
|
if (s.length() == 2 && s.at(0) == '-' && s.at(1) != '-')
|
||||||
|
return make_pair(s.substr(1), "");
|
||||||
|
/* old-style -- -log, /log, etc */
|
||||||
|
if (s.at(0) == '/' || (s.at(0) == '-' && s.at(1) != '-')) {
|
||||||
|
if ((pos = s.find_first_of("= ")) != std::string::npos) {
|
||||||
|
name = s.substr(1, pos - 1);
|
||||||
|
value = s.substr(pos + 1);
|
||||||
|
} else {
|
||||||
|
name = s.substr(1, pos);
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
if (boolean_options.count(name) > 0 && value != "")
|
||||||
|
std::cerr << "args: don't give an argument to switch option: " << s << std::endl;
|
||||||
|
if (m_OptionsDesc.find_nothrow(name, false)) {
|
||||||
|
std::cerr << "args: option " << s << " style is DEPRECATED, use --" << name << " instead" << std::endl;
|
||||||
|
return std::make_pair(name, value);
|
||||||
|
}
|
||||||
|
if (remapped_options.count(name) > 0) {
|
||||||
|
name = remapped_options[name];
|
||||||
|
std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl;
|
||||||
|
return std::make_pair(name, value);
|
||||||
|
} /* else */
|
||||||
|
}
|
||||||
|
/* long options -- --help */
|
||||||
|
if (s.substr(0, 2) == "--") {
|
||||||
|
if ((pos = s.find_first_of("= ")) != std::string::npos) {
|
||||||
|
name = s.substr(2, pos - 2);
|
||||||
|
value = s.substr(pos + 1);
|
||||||
|
} else {
|
||||||
|
name = s.substr(2, pos);
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
if (boolean_options.count(name) > 0 && value != "") {
|
||||||
|
std::cerr << "args: don't give an argument to switch option: " << s << std::endl;
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
if (m_OptionsDesc.find_nothrow(name, false))
|
||||||
|
return std::make_pair(name, value);
|
||||||
|
if (remapped_options.count(name) > 0) {
|
||||||
|
name = remapped_options[name];
|
||||||
|
std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl;
|
||||||
|
return std::make_pair(name, value);
|
||||||
|
} /* else */
|
||||||
|
}
|
||||||
|
std::cerr << "args: unknown option -- " << s << std::endl;
|
||||||
|
return std::make_pair("", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init() {
|
||||||
|
options_description general("General options");
|
||||||
|
general.add_options()
|
||||||
|
("help", "Show this message")
|
||||||
|
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf)")
|
||||||
|
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg)")
|
||||||
|
("pidfile", value<std::string>()->default_value(""), "Write pidfile to given path")
|
||||||
|
("log", value<std::string>()->default_value(""), "Write logs to file instead stdout")
|
||||||
|
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
|
||||||
|
("loglevel", value<std::string>()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error)")
|
||||||
|
("host", value<std::string>()->default_value(""), "External IP (deprecated)")
|
||||||
|
("port", value<uint16_t>()->default_value(4567), "Port to listen for incoming connections")
|
||||||
|
("ipv6", value<bool>()->zero_tokens()->default_value(false), "Enable communication through ipv6")
|
||||||
|
("daemon", value<bool>()->zero_tokens()->default_value(false), "Router will go to background after start")
|
||||||
|
("service", value<bool>()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'")
|
||||||
|
("notransit", value<bool>()->zero_tokens()->default_value(false), "Router will not forward transit traffic")
|
||||||
|
("floodfill", value<bool>()->zero_tokens()->default_value(false), "Router will try to become floodfill")
|
||||||
|
("bandwidth", value<char>()->default_value('O'), "Bandwidth limiting: L - 32kbps, O - 256Kbps, P - unlimited (ignored if floodfill)")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description httpserver("HTTP Server options");
|
||||||
|
httpserver.add_options()
|
||||||
|
("http.enabled", value<bool>()->default_value(true), "Enable or disable webconsole")
|
||||||
|
("http.address", value<std::string>()->default_value("127.0.0.1"), "Webconsole listen address")
|
||||||
|
("http.port", value<uint16_t>()->default_value(7070), "Webconsole listen port")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description httpproxy("HTTP Proxy options");
|
||||||
|
httpproxy.add_options()
|
||||||
|
("httpproxy.enabled", value<bool>()->default_value(true), "Enable or disable HTTP Proxy")
|
||||||
|
("httpproxy.address", value<std::string>()->default_value("127.0.0.1"), "HTTP Proxy listen address")
|
||||||
|
("httpproxy.port", value<uint16_t>()->default_value(4444), "HTTP Proxy listen port")
|
||||||
|
("httpproxy.keys", value<std::string>()->default_value("httpproxy-keys.dat"), "HTTP Proxy encryption keys")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description socksproxy("SOCKS Proxy options");
|
||||||
|
socksproxy.add_options()
|
||||||
|
("socksproxy.enabled", value<bool>()->default_value(true), "Enable or disable SOCKS Proxy")
|
||||||
|
("socksproxy.address", value<std::string>()->default_value("127.0.0.1"), "SOCKS Proxy listen address")
|
||||||
|
("socksproxy.port", value<uint16_t>()->default_value(4447), "SOCKS Proxy listen port")
|
||||||
|
("socksproxy.keys", value<std::string>()->default_value("socksproxy-keys.dat"), "SOCKS Proxy encryption keys")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description sam("SAM bridge options");
|
||||||
|
sam.add_options()
|
||||||
|
("sam.enabled", value<bool>()->default_value(false), "Enable or disable SAM Application bridge")
|
||||||
|
("sam.address", value<std::string>()->default_value("127.0.0.1"), "SAM listen address")
|
||||||
|
("sam.port", value<uint16_t>()->default_value(7656), "SAM listen port")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description bob("BOB options");
|
||||||
|
bob.add_options()
|
||||||
|
("bob.enabled", value<bool>()->default_value(false), "Enable or disable BOB command channel")
|
||||||
|
("bob.address", value<std::string>()->default_value("127.0.0.1"), "BOB listen address")
|
||||||
|
("bob.port", value<uint16_t>()->default_value(2827), "BOB listen port")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description i2pcontrol("I2PControl options");
|
||||||
|
i2pcontrol.add_options()
|
||||||
|
("i2pcontrol.enabled", value<bool>()->default_value(false), "Enable or disable I2P Control Protocol")
|
||||||
|
("i2pcontrol.address", value<std::string>()->default_value("127.0.0.1"), "I2PCP listen address")
|
||||||
|
("i2pcontrol.port", value<uint16_t>()->default_value(7650), "I2PCP listen port")
|
||||||
|
("i2pcontrol.password", value<std::string>()->default_value("itoopie"), "I2PCP access password")
|
||||||
|
("i2pcontrol.cert", value<std::string>()->default_value("i2pcontrol.crt.pem"), "I2PCP connection cerificate")
|
||||||
|
("i2pcontrol.key", value<std::string>()->default_value("i2pcontrol.key.pem"), "I2PCP connection cerificate key")
|
||||||
|
;
|
||||||
|
|
||||||
|
m_OptionsDesc
|
||||||
|
.add(general)
|
||||||
|
.add(httpserver)
|
||||||
|
.add(httpproxy)
|
||||||
|
.add(socksproxy)
|
||||||
|
.add(sam)
|
||||||
|
.add(bob)
|
||||||
|
.add(i2pcontrol)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseCmdline(int argc, char* argv[]) {
|
||||||
|
try {
|
||||||
|
auto style = boost::program_options::command_line_style::unix_style
|
||||||
|
| boost::program_options::command_line_style::allow_long_disguise;
|
||||||
|
style &= ~ boost::program_options::command_line_style::allow_guessing;
|
||||||
|
store(parse_command_line(argc, argv, m_OptionsDesc, style, old_syntax_parser), m_Options);
|
||||||
|
} catch (boost::program_options::error e) {
|
||||||
|
std::cerr << "args: " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Options.count("help") || m_Options.count("h")) {
|
||||||
|
std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
|
||||||
|
std::cout << m_OptionsDesc;
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseConfig(const std::string& path) {
|
||||||
|
if (path == "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ifstream config(path, std::ios::in);
|
||||||
|
|
||||||
|
if (!config.is_open()) {
|
||||||
|
std::cerr << "missing/unreadable config file: " << path << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
store(boost::program_options::parse_config_file(config, m_OptionsDesc), m_Options);
|
||||||
|
} catch (boost::program_options::error e) {
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finalize() {
|
||||||
|
notify(m_Options);
|
||||||
|
};
|
||||||
|
} // namespace config
|
||||||
|
} // namespace i2p
|
100
Config.h
Normal file
100
Config.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/program_options/options_description.hpp>
|
||||||
|
#include <boost/program_options/variables_map.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functions to parse and store i2pd parameters
|
||||||
|
*
|
||||||
|
* General usage flow:
|
||||||
|
* Init() -- early as possible
|
||||||
|
* ParseCmdline() -- somewhere close to main()
|
||||||
|
* ParseConfig() -- after detecting path to config
|
||||||
|
* Finalize() -- right after all Parse*() functions called
|
||||||
|
* GetOption() -- may be called after Finalize()
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace config {
|
||||||
|
extern boost::program_options::variables_map m_Options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize list of acceptable parameters
|
||||||
|
*
|
||||||
|
* Should be called before any Parse* functions.
|
||||||
|
*/
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse cmdline parameters, and show help if requested
|
||||||
|
* @param argc Cmdline arguments count, should be passed from main().
|
||||||
|
* @param argv Cmdline parameters array, should be passed from main()
|
||||||
|
*
|
||||||
|
* If --help is given in parameters, shows it's list with description
|
||||||
|
* terminates the program with exitcode 0.
|
||||||
|
*
|
||||||
|
* In case of parameter misuse boost throws an exception.
|
||||||
|
* We internally handle type boost::program_options::unknown_option,
|
||||||
|
* and then terminate program with exitcode 1.
|
||||||
|
*
|
||||||
|
* Other exceptions will be passed to higher level.
|
||||||
|
*/
|
||||||
|
void ParseCmdline(int argc, char* argv[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load and parse given config file
|
||||||
|
* @param path Path to config file
|
||||||
|
*
|
||||||
|
* If error occured when opening file path is points to,
|
||||||
|
* we show the error message and terminate program.
|
||||||
|
*
|
||||||
|
* In case of parameter misuse boost throws an exception.
|
||||||
|
* We internally handle type boost::program_options::unknown_option,
|
||||||
|
* and then terminate program with exitcode 1.
|
||||||
|
*
|
||||||
|
* Other exceptions will be passed to higher level.
|
||||||
|
*/
|
||||||
|
void ParseConfig(const std::string& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Used to combine options from cmdline, config and default values
|
||||||
|
*/
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
|
/* @brief Accessor to parameters by name
|
||||||
|
* @param name Name of the requested parameter
|
||||||
|
* @param value Variable where to store option
|
||||||
|
* @return this function returns false if parameter not found
|
||||||
|
*
|
||||||
|
* @example uint16_t port; GetOption("sam.port", port);
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
bool GetOption(const char *name, T& value) {
|
||||||
|
if (!m_Options.count(name))
|
||||||
|
return false;
|
||||||
|
value = m_Options[name].as<T>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set value of given parameter
|
||||||
|
* @param name Name of settable parameter
|
||||||
|
* @param value New parameter value
|
||||||
|
* @return true if value set up successful, false otherwise
|
||||||
|
*
|
||||||
|
* @example uint16_t port = 2827; SetOption("bob.port", port);
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
bool SetOption(const char *name, const T& value) {
|
||||||
|
if (!m_Options.count(name))
|
||||||
|
return false;
|
||||||
|
m_Options[name] = value;
|
||||||
|
notify(m_Options);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONFIG_H
|
131
Daemon.cpp
131
Daemon.cpp
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@ -50,78 +51,106 @@ namespace i2p
|
|||||||
|
|
||||||
bool Daemon_Singleton::IsService () const
|
bool Daemon_Singleton::IsService () const
|
||||||
{
|
{
|
||||||
|
bool service = false;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return i2p::util::config::GetArg("-service", 0);
|
i2p::config::GetOption("service", service);
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::init(int argc, char* argv[])
|
bool Daemon_Singleton::init(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
std::string config = i2p::util::filesystem::GetConfigFile().string();
|
||||||
|
std::string tunconf = i2p::util::filesystem::GetTunnelsConfigFile().string();
|
||||||
|
std::string datadir = i2p::util::filesystem::GetDataDir().string();
|
||||||
|
|
||||||
|
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
|
||||||
|
LogPrint(eLogDebug, "FS: main config file: ", config);
|
||||||
|
LogPrint(eLogDebug, "FS: tunnels config: ", tunconf);
|
||||||
|
LogPrint(eLogDebug, "FS: data directory: ", datadir);
|
||||||
|
|
||||||
|
i2p::config::Init();
|
||||||
|
i2p::config::ParseCmdline(argc, argv);
|
||||||
|
i2p::config::ParseConfig(config);
|
||||||
|
i2p::config::Finalize();
|
||||||
|
|
||||||
i2p::crypto::InitCrypto ();
|
i2p::crypto::InitCrypto ();
|
||||||
i2p::util::config::OptionParser(argc, argv);
|
|
||||||
i2p::context.Init ();
|
i2p::context.Init ();
|
||||||
|
|
||||||
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
|
i2p::config::GetOption("daemon", isDaemon);
|
||||||
LogPrint(eLogDebug, "FS: data directory: ", i2p::util::filesystem::GetDataDir().string());
|
|
||||||
i2p::util::config::ReadConfigFile(i2p::util::filesystem::GetConfigFile());
|
|
||||||
|
|
||||||
isDaemon = i2p::util::config::GetArg("-daemon", 0);
|
// temporary hack
|
||||||
isLogging = i2p::util::config::GetArg("-log", (int)isDaemon);
|
std::string logs = "";
|
||||||
|
i2p::config::GetOption("log", logs);
|
||||||
|
if (logs != "")
|
||||||
|
isLogging = true;
|
||||||
|
|
||||||
int port = i2p::util::config::GetArg("-port", 0);
|
uint16_t port; i2p::config::GetOption("port", port);
|
||||||
if (port)
|
LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port);
|
||||||
i2p::context.UpdatePort (port);
|
i2p::context.UpdatePort (port);
|
||||||
std::string host = i2p::util::config::GetArg("-host", "");
|
|
||||||
if (host != "")
|
std::string host; i2p::config::GetOption("host", host);
|
||||||
|
if (host != "") {
|
||||||
|
LogPrint(eLogInfo, "Daemon: address for incoming connections is ", host);
|
||||||
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (host));
|
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (host));
|
||||||
|
}
|
||||||
|
|
||||||
i2p::context.SetSupportsV6 (i2p::util::config::GetArg("-v6", 0));
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
i2p::context.SetAcceptsTunnels (!i2p::util::config::GetArg("-notransit", 0));
|
bool transit; i2p::config::GetOption("notransit", transit);
|
||||||
bool isFloodfill = i2p::util::config::GetArg("-floodfill", 0);
|
i2p::context.SetSupportsV6 (ipv6);
|
||||||
i2p::context.SetFloodfill (isFloodfill);
|
i2p::context.SetAcceptsTunnels (!transit);
|
||||||
auto bandwidth = i2p::util::config::GetArg("-bandwidth", "");
|
|
||||||
if (bandwidth.length () > 0)
|
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
||||||
{
|
char bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
|
||||||
if (bandwidth[0] > 'O')
|
|
||||||
i2p::context.SetExtraBandwidth ();
|
if (isFloodfill) {
|
||||||
else if (bandwidth[0] > 'L')
|
LogPrint(eLogInfo, "Daemon: router will be floodfill, bandwidth set to 'extra'");
|
||||||
i2p::context.SetHighBandwidth ();
|
i2p::context.SetFloodfill (true);
|
||||||
else
|
|
||||||
i2p::context.SetLowBandwidth ();
|
|
||||||
}
|
|
||||||
else if (isFloodfill)
|
|
||||||
i2p::context.SetExtraBandwidth ();
|
i2p::context.SetExtraBandwidth ();
|
||||||
LogPrint(eLogDebug, "Daemon: CMD parameters:");
|
} else if (bandwidth != '-') {
|
||||||
for (int i = 0; i < argc; ++i)
|
LogPrint(eLogInfo, "Daemon: bandwidth set to ", bandwidth);
|
||||||
LogPrint(eLogDebug, i, ": ", argv[i]);
|
switch (bandwidth) {
|
||||||
|
case 'P' : i2p::context.SetExtraBandwidth (); break;
|
||||||
|
case 'L' : i2p::context.SetHighBandwidth (); break;
|
||||||
|
default : i2p::context.SetLowBandwidth (); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::start()
|
bool Daemon_Singleton::start()
|
||||||
{
|
{
|
||||||
// initialize log
|
|
||||||
if (isLogging)
|
if (isLogging)
|
||||||
{
|
{
|
||||||
std::string logfile_path = IsService () ? "/var/log/i2pd" : i2p::util::filesystem::GetDataDir().string();
|
// set default to stdout
|
||||||
|
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
|
||||||
|
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
|
||||||
|
if (isDaemon && logfile == "") {
|
||||||
|
// can't log to stdout, use autodetect of logfile
|
||||||
|
if (IsService ()) {
|
||||||
|
logfile = "/var/log";
|
||||||
|
} else {
|
||||||
|
logfile = i2p::util::filesystem::GetDataDir().string();
|
||||||
|
}
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
logfile_path.append("/i2pd.log");
|
logfile.append("/i2pd.log");
|
||||||
#else
|
#else
|
||||||
logfile_path.append("\\i2pd.log");
|
logfile.append("\\i2pd.log");
|
||||||
#endif
|
#endif
|
||||||
StartLog (logfile_path);
|
}
|
||||||
|
StartLog (logfile);
|
||||||
|
g_Log->SetLogLevel(loglevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool http; i2p::config::GetOption("http.enabled", http);
|
||||||
|
if (http) {
|
||||||
|
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
||||||
|
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
||||||
|
LogPrint(eLogInfo, "Daemon: starting HTTP Server at ", httpAddr, ":", httpPort);
|
||||||
|
d.httpServer = std::unique_ptr<i2p::util::HTTPServer>(new i2p::util::HTTPServer(httpAddr, httpPort));
|
||||||
|
d.httpServer->Start();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
StartLog (""); // write to stdout
|
|
||||||
g_Log->SetLogLevel(i2p::util::config::GetArg("-loglevel", "info"));
|
|
||||||
|
|
||||||
std::string httpAddr = i2p::util::config::GetArg("-httpaddress", "127.0.0.1");
|
|
||||||
uint16_t httpPort = i2p::util::config::GetArg("-httpport", 7070);
|
|
||||||
LogPrint(eLogInfo, "Daemon: staring HTTP Server at ", httpAddr, ":", httpPort);
|
|
||||||
d.httpServer = std::unique_ptr<i2p::util::HTTPServer>(new i2p::util::HTTPServer(httpAddr, httpPort));
|
|
||||||
d.httpServer->Start();
|
|
||||||
|
|
||||||
LogPrint(eLogInfo, "Daemon: starting NetDB");
|
LogPrint(eLogInfo, "Daemon: starting NetDB");
|
||||||
i2p::data::netdb.Start();
|
i2p::data::netdb.Start();
|
||||||
@ -140,10 +169,10 @@ namespace i2p
|
|||||||
i2p::client::context.Start ();
|
i2p::client::context.Start ();
|
||||||
|
|
||||||
// I2P Control Protocol
|
// I2P Control Protocol
|
||||||
std::string i2pcpAddr = i2p::util::config::GetArg("-i2pcontroladdress", "127.0.0.1");
|
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||||
uint16_t i2pcpPort = i2p::util::config::GetArg("-i2pcontrolport", 0);
|
if (i2pcontrol) {
|
||||||
if (i2pcpPort)
|
std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr);
|
||||||
{
|
uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort);
|
||||||
LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
|
LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
|
||||||
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
|
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
|
||||||
d.m_I2PControlService->Start ();
|
d.m_I2PControlService->Start ();
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
void handle_signal(int sig)
|
void handle_signal(int sig)
|
||||||
{
|
{
|
||||||
switch (sig)
|
switch (sig)
|
||||||
@ -28,7 +28,6 @@ void handle_signal(int sig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
@ -74,7 +73,7 @@ namespace i2p
|
|||||||
|
|
||||||
// Pidfile
|
// Pidfile
|
||||||
// this code is c-styled and a bit ugly, but we need fd for locking pidfile
|
// this code is c-styled and a bit ugly, but we need fd for locking pidfile
|
||||||
pidfile = i2p::util::config::GetArg("-pidfile", "");
|
std::string pidfile; i2p::config::GetOption("pidfile", pidfile);
|
||||||
if (pidfile == "") {
|
if (pidfile == "") {
|
||||||
pidfile = IsService () ? "/var/run" : i2p::util::filesystem::GetDataDir().string();
|
pidfile = IsService () ? "/var/run" : i2p::util::filesystem::GetDataDir().string();
|
||||||
pidfile.append("/i2pd.pid");
|
pidfile.append("/i2pd.pid");
|
||||||
@ -120,7 +119,6 @@ namespace i2p
|
|||||||
|
|
||||||
return Daemon_Singleton::stop();
|
return Daemon_Singleton::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "Config.h"
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
@ -23,7 +24,7 @@ namespace i2p
|
|||||||
else
|
else
|
||||||
isDaemon = 0;
|
isDaemon = 0;
|
||||||
|
|
||||||
std::string serviceControl = i2p::util::config::GetArg("-svcctl", "");
|
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
|
||||||
if (serviceControl == "install")
|
if (serviceControl == "install")
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
|
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
|
||||||
|
323
I2PControl.cpp
323
I2PControl.cpp
@ -1,5 +1,3 @@
|
|||||||
// There is bug in boost 1.49 with gcc 4.7 coming with Debian Wheezy
|
|
||||||
#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
@ -8,10 +6,15 @@
|
|||||||
#include <boost/date_time/local_time/local_time.hpp>
|
#include <boost/date_time/local_time/local_time.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
|
|
||||||
|
// There is bug in boost 1.49 with gcc 4.7 coming with Debian Wheezy
|
||||||
|
#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))
|
||||||
#if !GCC47_BOOST149
|
#if !GCC47_BOOST149
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Config.h"
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
@ -26,58 +29,56 @@ namespace i2p
|
|||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
I2PControlService::I2PControlService (const std::string& address, int port):
|
I2PControlService::I2PControlService (const std::string& address, int port):
|
||||||
m_Password (I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning (false), m_Thread (nullptr),
|
m_IsRunning (false), m_Thread (nullptr),
|
||||||
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
|
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
|
||||||
m_SSLContext (m_Service, boost::asio::ssl::context::sslv23),
|
m_SSLContext (m_Service, boost::asio::ssl::context::sslv23),
|
||||||
m_ShutdownTimer (m_Service)
|
m_ShutdownTimer (m_Service)
|
||||||
{
|
{
|
||||||
LoadConfig ();
|
i2p::config::GetOption("i2pcontrol.password", m_Password);
|
||||||
// certificate
|
|
||||||
|
// certificate / keys
|
||||||
|
std::string i2pcp_crt; i2p::config::GetOption("i2pcontrol.cert", i2pcp_crt);
|
||||||
|
std::string i2pcp_key; i2p::config::GetOption("i2pcontrol.key", i2pcp_key);
|
||||||
|
// TODO: properly handle absolute paths
|
||||||
auto path = GetPath ();
|
auto path = GetPath ();
|
||||||
if (!boost::filesystem::exists (path))
|
if (!boost::filesystem::exists (path / i2pcp_crt) ||
|
||||||
|
!boost::filesystem::exists (path / i2pcp_key))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::create_directory (path))
|
LogPrint (eLogInfo, "I2PControl: creating new certificate for control connection");
|
||||||
LogPrint (eLogError, "Failed to create i2pcontrol directory");
|
CreateCertificate (i2pcp_crt.c_str(), i2pcp_key.c_str());
|
||||||
}
|
|
||||||
if (!boost::filesystem::exists (path / I2P_CONTROL_KEY_FILE) ||
|
|
||||||
!boost::filesystem::exists (path / I2P_CONTROL_CERT_FILE))
|
|
||||||
{
|
|
||||||
// create new certificate
|
|
||||||
CreateCertificate ();
|
|
||||||
LogPrint (eLogInfo, "I2PControl certificates created");
|
|
||||||
}
|
}
|
||||||
m_SSLContext.set_options (boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use);
|
m_SSLContext.set_options (boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use);
|
||||||
m_SSLContext.use_certificate_file ((path / I2P_CONTROL_CERT_FILE).string (), boost::asio::ssl::context::pem);
|
m_SSLContext.use_certificate_file ((path / i2pcp_crt).string (), boost::asio::ssl::context::pem);
|
||||||
m_SSLContext.use_private_key_file ((path / I2P_CONTROL_KEY_FILE).string (), boost::asio::ssl::context::pem);
|
m_SSLContext.use_private_key_file ((path / i2pcp_crt).string (), boost::asio::ssl::context::pem);
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_AUTHENTICATE] = &I2PControlService::AuthenticateHandler;
|
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_ECHO] = &I2PControlService::EchoHandler;
|
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_I2PCONTROL] = &I2PControlService::I2PControlHandler;
|
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_ROUTER_INFO] = &I2PControlService::RouterInfoHandler;
|
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_ROUTER_MANAGER] = &I2PControlService::RouterManagerHandler;
|
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_NETWORK_SETTING] = &I2PControlService::NetworkSettingHandler;
|
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||||
|
|
||||||
// I2PControl
|
// I2PControl
|
||||||
m_I2PControlHandlers[I2P_CONTROL_I2PCONTROL_PASSWORD] = &I2PControlService::PasswordHandler;
|
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
||||||
|
|
||||||
// RouterInfo
|
// RouterInfo
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_UPTIME] = &I2PControlService::UptimeHandler;
|
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_VERSION] = &I2PControlService::VersionHandler;
|
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_STATUS] = &I2PControlService::StatusHandler;
|
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NETDB_KNOWNPEERS] = &I2PControlService::NetDbKnownPeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NETDB_ACTIVEPEERS] = &I2PControlService::NetDbActivePeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NET_STATUS] = &I2PControlService::NetStatusHandler;
|
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_TUNNELS_PARTICIPATING] = &I2PControlService::TunnelsParticipatingHandler;
|
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_BW_IB_1S] = &I2PControlService::InboundBandwidth1S ;
|
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_BW_OB_1S] = &I2PControlService::OutboundBandwidth1S ;
|
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NET_TOTAL_RB] = &I2PControlService::NetTotalReceivedBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
||||||
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NET_TOTAL_SB] = &I2PControlService::NetTotalSentBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
||||||
|
|
||||||
// RouterManager
|
// RouterManager
|
||||||
m_RouterManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN] = &I2PControlService::ShutdownHandler;
|
m_RouterManagerHandlers["Reseed"] = &I2PControlService::ReseedHandler;
|
||||||
m_RouterManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN_GRACEFUL] = &I2PControlService::ShutdownGracefulHandler;
|
m_RouterManagerHandlers["Shutdown"] = &I2PControlService::ShutdownHandler;
|
||||||
m_RouterManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_RESEED] = &I2PControlService::ReseedHandler;
|
m_RouterManagerHandlers["ShutdownGraceful"] = &I2PControlService::ShutdownGracefulHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
I2PControlService::~I2PControlService ()
|
I2PControlService::~I2PControlService ()
|
||||||
@ -85,49 +86,6 @@ namespace client
|
|||||||
Stop ();
|
Stop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::LoadConfig ()
|
|
||||||
{
|
|
||||||
auto path = GetPath ();
|
|
||||||
if (!boost::filesystem::exists (path))
|
|
||||||
{
|
|
||||||
if (!boost::filesystem::create_directory (path))
|
|
||||||
LogPrint (eLogError, "Failed to create i2pcontrol directory");
|
|
||||||
}
|
|
||||||
boost::property_tree::ptree pt;
|
|
||||||
auto filename = path / I2P_CONTROL_CONFIG_FILE;
|
|
||||||
bool isNew = true;
|
|
||||||
if (boost::filesystem::exists (filename))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
boost::property_tree::read_ini (filename.string (), pt);
|
|
||||||
isNew = false;
|
|
||||||
}
|
|
||||||
catch (std::exception& ex)
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "Can't read ", filename, ": ", ex.what ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_Password = pt.get (I2P_CONTROL_I2PCONTROL_PASSWORD, I2P_CONTROL_DEFAULT_PASSWORD);
|
|
||||||
if (isNew) SaveConfig ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2PControlService::SaveConfig ()
|
|
||||||
{
|
|
||||||
boost::property_tree::ptree pt;
|
|
||||||
pt.put (I2P_CONTROL_I2PCONTROL_PASSWORD, m_Password);
|
|
||||||
auto filename = GetPath () / I2P_CONTROL_CONFIG_FILE;
|
|
||||||
// we take care about directory in LoadConfig
|
|
||||||
try
|
|
||||||
{
|
|
||||||
boost::property_tree::write_ini (filename.string (), pt);
|
|
||||||
}
|
|
||||||
catch (std::exception& ex)
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "Can't write ", filename, ": ", ex.what ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2PControlService::Start ()
|
void I2PControlService::Start ()
|
||||||
{
|
{
|
||||||
if (!m_IsRunning)
|
if (!m_IsRunning)
|
||||||
@ -158,15 +116,12 @@ namespace client
|
|||||||
{
|
{
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
m_Service.run ();
|
m_Service.run ();
|
||||||
}
|
} catch (std::exception& ex) {
|
||||||
catch (std::exception& ex)
|
LogPrint (eLogError, "I2PControl: runtime exception: ", ex.what ());
|
||||||
{
|
}
|
||||||
LogPrint (eLogError, "I2PControl: ", ex.what ());
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::Accept ()
|
void I2PControlService::Accept ()
|
||||||
@ -181,13 +136,12 @@ namespace client
|
|||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
Accept ();
|
Accept ();
|
||||||
|
|
||||||
if (!ecode)
|
if (ecode) {
|
||||||
{
|
LogPrint (eLogError, "I2PControl: accept error: ", ecode.message ());
|
||||||
LogPrint (eLogInfo, "New I2PControl request from ", socket->lowest_layer ().remote_endpoint ());
|
return;
|
||||||
Handshake (socket);
|
|
||||||
}
|
}
|
||||||
else
|
LogPrint (eLogDebug, "I2PControl: new request from ", socket->lowest_layer ().remote_endpoint ());
|
||||||
LogPrint (eLogError, "I2PControl accept error: ", ecode.message ());
|
Handshake (socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::Handshake (std::shared_ptr<ssl_socket> socket)
|
void I2PControlService::Handshake (std::shared_ptr<ssl_socket> socket)
|
||||||
@ -198,13 +152,12 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)
|
void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)
|
||||||
{
|
{
|
||||||
if (!ecode)
|
if (ecode) {
|
||||||
{
|
LogPrint (eLogError, "I2PControl: handshake error: ", ecode.message ());
|
||||||
//std::this_thread::sleep_for (std::chrono::milliseconds(5));
|
return;
|
||||||
ReadRequest (socket);
|
}
|
||||||
}
|
//std::this_thread::sleep_for (std::chrono::milliseconds(5));
|
||||||
else
|
ReadRequest (socket);
|
||||||
LogPrint (eLogError, "I2PControl handshake error: ", ecode.message ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::ReadRequest (std::shared_ptr<ssl_socket> socket)
|
void I2PControlService::ReadRequest (std::shared_ptr<ssl_socket> socket)
|
||||||
@ -224,12 +177,10 @@ namespace client
|
|||||||
size_t bytes_transferred, std::shared_ptr<ssl_socket> socket,
|
size_t bytes_transferred, std::shared_ptr<ssl_socket> socket,
|
||||||
std::shared_ptr<I2PControlBuffer> buf)
|
std::shared_ptr<I2PControlBuffer> buf)
|
||||||
{
|
{
|
||||||
if (ecode)
|
if (ecode) {
|
||||||
{
|
LogPrint (eLogError, "I2PControl: read error: ", ecode.message ());
|
||||||
LogPrint (eLogError, "I2PControl read error: ", ecode.message ());
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool isHtml = !memcmp (buf->data (), "POST", 4);
|
bool isHtml = !memcmp (buf->data (), "POST", 4);
|
||||||
@ -264,14 +215,14 @@ namespace client
|
|||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
boost::property_tree::read_json (ss, pt);
|
boost::property_tree::read_json (ss, pt);
|
||||||
|
|
||||||
std::string method = pt.get<std::string>(I2P_CONTROL_PROPERTY_METHOD);
|
std::string id = pt.get<std::string>("id");
|
||||||
|
std::string method = pt.get<std::string>("method");
|
||||||
auto it = m_MethodHandlers.find (method);
|
auto it = m_MethodHandlers.find (method);
|
||||||
if (it != m_MethodHandlers.end ())
|
if (it != m_MethodHandlers.end ())
|
||||||
{
|
{
|
||||||
std::ostringstream response;
|
std::ostringstream response;
|
||||||
response << "{\"id\":" << pt.get<std::string>(I2P_CONTROL_PROPERTY_ID) << ",\"result\":{";
|
response << "{\"id\":" << id << ",\"result\":{";
|
||||||
|
(this->*(it->second))(pt.get_child ("params"), response);
|
||||||
(this->*(it->second))(pt.get_child (I2P_CONTROL_PROPERTY_PARAMS), response);
|
|
||||||
response << "},\"jsonrpc\":\"2.0\"}";
|
response << "},\"jsonrpc\":\"2.0\"}";
|
||||||
SendResponse (socket, buf, response, isHtml);
|
SendResponse (socket, buf, response, isHtml);
|
||||||
}
|
}
|
||||||
@ -338,33 +289,34 @@ namespace client
|
|||||||
void I2PControlService::HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
void I2PControlService::HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
||||||
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf)
|
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf)
|
||||||
{
|
{
|
||||||
if (ecode)
|
if (ecode) {
|
||||||
LogPrint (eLogError, "I2PControl write error: ", ecode.message ());
|
LogPrint (eLogError, "I2PControl: write error: ", ecode.message ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
|
|
||||||
void I2PControlService::AuthenticateHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::AuthenticateHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
int api = params.get<int> (I2P_CONTROL_PARAM_API);
|
int api = params.get<int> ("API");
|
||||||
auto password = params.get<std::string> (I2P_CONTROL_PARAM_PASSWORD);
|
auto password = params.get<std::string> ("Password");
|
||||||
LogPrint (eLogDebug, "I2PControl Authenticate API=", api, " Password=", password);
|
LogPrint (eLogDebug, "I2PControl: Authenticate API=", api, " Password=", password);
|
||||||
if (password != m_Password) {
|
if (password != m_Password) {
|
||||||
LogPrint (eLogError, "I2PControl: Authenticate - Invalid password: ", password);
|
LogPrint (eLogError, "I2PControl: Authenticate - Invalid password: ", password);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
InsertParam (results, I2P_CONTROL_PARAM_API, api);
|
InsertParam (results, "API", api);
|
||||||
results << ",";
|
results << ",";
|
||||||
std::string token = boost::lexical_cast<std::string>(i2p::util::GetSecondsSinceEpoch ());
|
std::string token = boost::lexical_cast<std::string>(i2p::util::GetSecondsSinceEpoch ());
|
||||||
m_Tokens.insert (token);
|
m_Tokens.insert (token);
|
||||||
InsertParam (results, I2P_CONTROL_PARAM_TOKEN, token);
|
InsertParam (results, "Token", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::EchoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::EchoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
auto echo = params.get<std::string> (I2P_CONTROL_PARAM_ECHO);
|
auto echo = params.get<std::string> ("Echo");
|
||||||
LogPrint (eLogDebug, "I2PControl Echo Echo=", echo);
|
LogPrint (eLogDebug, "I2PControl Echo Echo=", echo);
|
||||||
InsertParam (results, I2P_CONTROL_PARAM_RESULT, echo);
|
InsertParam (results, "Result", echo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -372,10 +324,9 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::I2PControlHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::I2PControlHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2PControl I2PControl");
|
|
||||||
for (auto& it: params)
|
for (auto& it: params)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, it.first);
|
LogPrint (eLogDebug, "I2PControl: I2PControl request: ", it.first);
|
||||||
auto it1 = m_I2PControlHandlers.find (it.first);
|
auto it1 = m_I2PControlHandlers.find (it.first);
|
||||||
if (it1 != m_I2PControlHandlers.end ())
|
if (it1 != m_I2PControlHandlers.end ())
|
||||||
{
|
{
|
||||||
@ -383,26 +334,24 @@ namespace client
|
|||||||
InsertParam (results, it.first, "");
|
InsertParam (results, it.first, "");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "I2PControl I2PControl unknown request ", it.first);
|
LogPrint (eLogError, "I2PControl: I2PControl unknown request: ", it.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::PasswordHandler (const std::string& value)
|
void I2PControlService::PasswordHandler (const std::string& value)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2PControl new password=", value);
|
LogPrint (eLogWarning, "I2PControl: new password=", value, ", to make it persistent you should update your config!");
|
||||||
m_Password = value;
|
m_Password = value;
|
||||||
m_Tokens.clear ();
|
m_Tokens.clear ();
|
||||||
SaveConfig ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouterInfo
|
// RouterInfo
|
||||||
|
|
||||||
void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2PControl RouterInfo");
|
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); it++)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, it->first);
|
LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first);
|
||||||
auto it1 = m_RouterInfoHandlers.find (it->first);
|
auto it1 = m_RouterInfoHandlers.find (it->first);
|
||||||
if (it1 != m_RouterInfoHandlers.end ())
|
if (it1 != m_RouterInfoHandlers.end ())
|
||||||
{
|
{
|
||||||
@ -410,87 +359,89 @@ namespace client
|
|||||||
(this->*(it1->second))(results);
|
(this->*(it1->second))(results);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "I2PControl RouterInfo unknown request ", it->first);
|
LogPrint (eLogError, "I2PControl: RouterInfo unknown request ", it->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::UptimeHandler (std::ostringstream& results)
|
void I2PControlService::UptimeHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_UPTIME, (int)i2p::context.GetUptime ()*1000);
|
InsertParam (results, "i2p.router.uptime", (int)i2p::context.GetUptime ()*1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::VersionHandler (std::ostringstream& results)
|
void I2PControlService::VersionHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_VERSION, VERSION);
|
InsertParam (results, "i2p.router.version", VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::StatusHandler (std::ostringstream& results)
|
void I2PControlService::StatusHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_STATUS, "???"); // TODO:
|
InsertParam (results, "i2p.router.status", "???"); // TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results)
|
void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NETDB_KNOWNPEERS, i2p::data::netdb.GetNumRouters ());
|
InsertParam (results, "i2p.router.netdb.knownpeers", i2p::data::netdb.GetNumRouters ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetDbActivePeersHandler (std::ostringstream& results)
|
void I2PControlService::NetDbActivePeersHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NETDB_ACTIVEPEERS, (int)i2p::transport::transports.GetPeers ().size ());
|
InsertParam (results, "i2p.router.netdb.activepeers", (int)i2p::transport::transports.GetPeers ().size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetStatusHandler (std::ostringstream& results)
|
void I2PControlService::NetStatusHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NET_STATUS, (int)i2p::context.GetStatus ());
|
InsertParam (results, "i2p.router.net.status", (int)i2p::context.GetStatus ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::TunnelsParticipatingHandler (std::ostringstream& results)
|
void I2PControlService::TunnelsParticipatingHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_TUNNELS_PARTICIPATING, (int)i2p::tunnel::tunnels.GetTransitTunnels ().size ());
|
int transit = i2p::tunnel::tunnels.GetTransitTunnels ().size ();
|
||||||
|
InsertParam (results, "i2p.router.net.tunnels.participating", transit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::InboundBandwidth1S (std::ostringstream& results)
|
void I2PControlService::InboundBandwidth1S (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_BW_IB_1S, (double)i2p::transport::transports.GetInBandwidth ());
|
double bw = i2p::transport::transports.GetInBandwidth ();
|
||||||
|
InsertParam (results, "i2p.router.net.bw.inbound.1s", bw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::OutboundBandwidth1S (std::ostringstream& results)
|
void I2PControlService::OutboundBandwidth1S (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_BW_OB_1S, (double)i2p::transport::transports.GetOutBandwidth ());
|
double bw = i2p::transport::transports.GetOutBandwidth ();
|
||||||
|
InsertParam (results, "i2p.router.net.bw.outbound.1s", bw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetTotalReceivedBytes (std::ostringstream& results)
|
void I2PControlService::NetTotalReceivedBytes (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NET_TOTAL_RB, (double)i2p::transport::transports.GetTotalReceivedBytes ());
|
InsertParam (results, "i2p.router.net.total.received.bytes", (double)i2p::transport::transports.GetTotalReceivedBytes ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
|
void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NET_TOTAL_SB, (double)i2p::transport::transports.GetTotalSentBytes ());
|
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouterManager
|
// RouterManager
|
||||||
|
|
||||||
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2PControl RouterManager");
|
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); it++)
|
||||||
{
|
{
|
||||||
if (it != params.begin ()) results << ",";
|
if (it != params.begin ()) results << ",";
|
||||||
LogPrint (eLogDebug, it->first);
|
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
|
||||||
auto it1 = m_RouterManagerHandlers.find (it->first);
|
auto it1 = m_RouterManagerHandlers.find (it->first);
|
||||||
if (it1 != m_RouterManagerHandlers.end ())
|
if (it1 != m_RouterManagerHandlers.end ()) {
|
||||||
(this->*(it1->second))(results);
|
(this->*(it1->second))(results);
|
||||||
else
|
} else
|
||||||
LogPrint (eLogError, "I2PControl RouterManager unknown request ", it->first);
|
LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void I2PControlService::ShutdownHandler (std::ostringstream& results)
|
void I2PControlService::ShutdownHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Shutdown requested");
|
LogPrint (eLogInfo, "I2PControl: Shutdown requested");
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN, "");
|
InsertParam (results, "Shutdown", "");
|
||||||
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
|
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
|
||||||
m_ShutdownTimer.async_wait (
|
m_ShutdownTimer.async_wait (
|
||||||
[](const boost::system::error_code& ecode)
|
[](const boost::system::error_code& ecode)
|
||||||
@ -503,8 +454,8 @@ namespace client
|
|||||||
{
|
{
|
||||||
i2p::context.SetAcceptsTunnels (false);
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
int timeout = i2p::tunnel::tunnels.GetTransitTunnelsExpirationTimeout ();
|
int timeout = i2p::tunnel::tunnels.GetTransitTunnelsExpirationTimeout ();
|
||||||
LogPrint (eLogInfo, "Graceful shutdown requested. Will shutdown after ", timeout, " seconds");
|
LogPrint (eLogInfo, "I2PControl: Graceful shutdown requested, ", timeout, " seconds remains");
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN_GRACEFUL, "");
|
InsertParam (results, "ShutdownGraceful", "");
|
||||||
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
|
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
|
||||||
m_ShutdownTimer.async_wait (
|
m_ShutdownTimer.async_wait (
|
||||||
[](const boost::system::error_code& ecode)
|
[](const boost::system::error_code& ecode)
|
||||||
@ -515,30 +466,30 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::ReseedHandler (std::ostringstream& results)
|
void I2PControlService::ReseedHandler (std::ostringstream& results)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Reseed requested");
|
LogPrint (eLogInfo, "I2PControl: Reseed requested");
|
||||||
InsertParam (results, I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN, "");
|
InsertParam (results, "Reseed", "");
|
||||||
i2p::data::netdb.Reseed ();
|
i2p::data::netdb.Reseed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// network setting
|
// network setting
|
||||||
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2PControl NetworkSetting");
|
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); it++)
|
||||||
{
|
{
|
||||||
if (it != params.begin ()) results << ",";
|
if (it != params.begin ()) results << ",";
|
||||||
LogPrint (eLogDebug, it->first);
|
LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first);
|
||||||
auto it1 = m_NetworkSettingHandlers.find (it->first);
|
auto it1 = m_NetworkSettingHandlers.find (it->first);
|
||||||
if (it1 != m_NetworkSettingHandlers.end ())
|
if (it1 != m_NetworkSettingHandlers.end ()) {
|
||||||
(this->*(it1->second))(it->second.data (), results);
|
(this->*(it1->second))(it->second.data (), results);
|
||||||
else
|
} else
|
||||||
LogPrint (eLogError, "I2PControl NetworkSetting unknown request ", it->first);
|
LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// certificate
|
// certificate
|
||||||
void I2PControlService::CreateCertificate ()
|
void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path)
|
||||||
{
|
{
|
||||||
|
FILE *f = NULL;
|
||||||
EVP_PKEY * pkey = EVP_PKEY_new ();
|
EVP_PKEY * pkey = EVP_PKEY_new ();
|
||||||
RSA * rsa = RSA_new ();
|
RSA * rsa = RSA_new ();
|
||||||
BIGNUM * e = BN_dup (i2p::crypto::GetRSAE ());
|
BIGNUM * e = BN_dup (i2p::crypto::GetRSAE ());
|
||||||
@ -558,34 +509,30 @@ namespace client
|
|||||||
X509_NAME_add_entry_by_txt (name, "CN", MBSTRING_ASC, (unsigned char *)I2P_CONTROL_CERTIFICATE_COMMON_NAME, -1, -1, 0); // common name
|
X509_NAME_add_entry_by_txt (name, "CN", MBSTRING_ASC, (unsigned char *)I2P_CONTROL_CERTIFICATE_COMMON_NAME, -1, -1, 0); // common name
|
||||||
X509_set_issuer_name (x509, name); // set issuer to ourselves
|
X509_set_issuer_name (x509, name); // set issuer to ourselves
|
||||||
X509_sign (x509, pkey, EVP_sha1 ()); // sign
|
X509_sign (x509, pkey, EVP_sha1 ()); // sign
|
||||||
// save key and certificate
|
|
||||||
// keys
|
// save cert
|
||||||
auto filename = GetPath () / I2P_CONTROL_KEY_FILE;
|
if ((f = fopen (crt_path, "wb")) != NULL) {
|
||||||
FILE * f= fopen (filename.string ().c_str (), "wb");
|
LogPrint (eLogInfo, "I2PControl: saving new cert to ", crt_path);
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
PEM_write_PrivateKey (f, pkey, NULL, NULL, 0, NULL, NULL);
|
|
||||||
fclose (f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogPrint (eLogError, "Can't open file ", filename);
|
|
||||||
// certificate
|
|
||||||
filename = GetPath () / I2P_CONTROL_CERT_FILE;
|
|
||||||
f= fopen (filename.string ().c_str (), "wb");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
PEM_write_X509 (f, x509);
|
PEM_write_X509 (f, x509);
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
} else {
|
||||||
|
LogPrint (eLogError, "I2PControl: can't write cert: ", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
// save key
|
||||||
|
if ((f = fopen (key_path, "wb")) != NULL) {
|
||||||
|
LogPrint (eLogInfo, "I2PControl: saving cert key to : ", key_path);
|
||||||
|
PEM_write_PrivateKey (f, pkey, NULL, NULL, 0, NULL, NULL);
|
||||||
|
fclose (f);
|
||||||
|
} else {
|
||||||
|
LogPrint (eLogError, "I2PControl: can't write key: ", strerror(errno));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogError, "Can't open file ", filename);
|
|
||||||
|
|
||||||
X509_free (x509);
|
X509_free (x509);
|
||||||
|
} else {
|
||||||
|
LogPrint (eLogError, "I2PControl: can't create RSA key for certificate");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogError, "Couldn't create RSA key for certificate");
|
|
||||||
EVP_PKEY_free (pkey);
|
EVP_PKEY_free (pkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
58
I2PControl.h
58
I2PControl.h
@ -22,56 +22,6 @@ namespace client
|
|||||||
const size_t I2P_CONTROL_MAX_REQUEST_SIZE = 1024;
|
const size_t I2P_CONTROL_MAX_REQUEST_SIZE = 1024;
|
||||||
typedef std::array<char, I2P_CONTROL_MAX_REQUEST_SIZE> I2PControlBuffer;
|
typedef std::array<char, I2P_CONTROL_MAX_REQUEST_SIZE> I2PControlBuffer;
|
||||||
|
|
||||||
const char I2P_CONTROL_PATH[] = "ipcontrol";
|
|
||||||
const char I2P_CONTROL_KEY_FILE[] = "key.pem";
|
|
||||||
const char I2P_CONTROL_CERT_FILE[] = "cert.pem";
|
|
||||||
const char I2P_CONTROL_CONFIG_FILE[] = "i2pcontrol.conf";
|
|
||||||
const char I2P_CONTROL_DEFAULT_PASSWORD[] = "itoopie";
|
|
||||||
|
|
||||||
const char I2P_CONTROL_PROPERTY_ID[] = "id";
|
|
||||||
const char I2P_CONTROL_PROPERTY_METHOD[] = "method";
|
|
||||||
const char I2P_CONTROL_PROPERTY_PARAMS[] = "params";
|
|
||||||
const char I2P_CONTROL_PROPERTY_RESULT[] = "result";
|
|
||||||
|
|
||||||
// methods
|
|
||||||
const char I2P_CONTROL_METHOD_AUTHENTICATE[] = "Authenticate";
|
|
||||||
const char I2P_CONTROL_METHOD_ECHO[] = "Echo";
|
|
||||||
const char I2P_CONTROL_METHOD_I2PCONTROL[] = "I2PControl";
|
|
||||||
const char I2P_CONTROL_METHOD_ROUTER_INFO[] = "RouterInfo";
|
|
||||||
const char I2P_CONTROL_METHOD_ROUTER_MANAGER[] = "RouterManager";
|
|
||||||
const char I2P_CONTROL_METHOD_NETWORK_SETTING[] = "NetworkSetting";
|
|
||||||
|
|
||||||
// params
|
|
||||||
const char I2P_CONTROL_PARAM_API[] = "API";
|
|
||||||
const char I2P_CONTROL_PARAM_PASSWORD[] = "Password";
|
|
||||||
const char I2P_CONTROL_PARAM_TOKEN[] = "Token";
|
|
||||||
const char I2P_CONTROL_PARAM_ECHO[] = "Echo";
|
|
||||||
const char I2P_CONTROL_PARAM_RESULT[] = "Result";
|
|
||||||
|
|
||||||
// I2PControl
|
|
||||||
const char I2P_CONTROL_I2PCONTROL_ADDRESS[] = "i2pcontrol.address";
|
|
||||||
const char I2P_CONTROL_I2PCONTROL_PASSWORD[] = "i2pcontrol.password";
|
|
||||||
const char I2P_CONTROL_I2PCONTROL_PORT[] = "i2pcontrol.port";
|
|
||||||
|
|
||||||
// RouterInfo requests
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_UPTIME[] = "i2p.router.uptime";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_VERSION[] = "i2p.router.version";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_STATUS[] = "i2p.router.status";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_NETDB_KNOWNPEERS[] = "i2p.router.netdb.knownpeers";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_NETDB_ACTIVEPEERS[] = "i2p.router.netdb.activepeers";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_NET_STATUS[] = "i2p.router.net.status";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_TUNNELS_PARTICIPATING[] = "i2p.router.net.tunnels.participating";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_BW_IB_1S[] = "i2p.router.net.bw.inbound.1s";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_BW_OB_1S[] = "i2p.router.net.bw.outbound.1s";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_NET_TOTAL_RB[] = "i2p.router.net.total.received.bytes";
|
|
||||||
const char I2P_CONTROL_ROUTER_INFO_NET_TOTAL_SB[] = "i2p.router.net.total.sent.bytes";
|
|
||||||
|
|
||||||
// RouterManager requests
|
|
||||||
const char I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN[] = "Shutdown";
|
|
||||||
const char I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN_GRACEFUL[] = "ShutdownGraceful";
|
|
||||||
const char I2P_CONTROL_ROUTER_MANAGER_RESEED[] = "Reseed";
|
|
||||||
|
|
||||||
// Certificate
|
|
||||||
const long I2P_CONTROL_CERTIFICATE_VALIDITY = 365*10; // 10 years
|
const long I2P_CONTROL_CERTIFICATE_VALIDITY = 365*10; // 10 years
|
||||||
const char I2P_CONTROL_CERTIFICATE_COMMON_NAME[] = "i2pd.i2pcontrol";
|
const char I2P_CONTROL_CERTIFICATE_COMMON_NAME[] = "i2pd.i2pcontrol";
|
||||||
const char I2P_CONTROL_CERTIFICATE_ORGANIZATION[] = "Purple I2P";
|
const char I2P_CONTROL_CERTIFICATE_ORGANIZATION[] = "Purple I2P";
|
||||||
@ -89,9 +39,6 @@ namespace client
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void LoadConfig ();
|
|
||||||
void SaveConfig ();
|
|
||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
void Accept ();
|
void Accept ();
|
||||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket);
|
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket);
|
||||||
@ -105,9 +52,8 @@ namespace client
|
|||||||
void HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
void HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
||||||
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf);
|
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf);
|
||||||
|
|
||||||
boost::filesystem::path GetPath () const { return i2p::util::filesystem::GetDefaultDataDir() / I2P_CONTROL_PATH; };
|
boost::filesystem::path GetPath () const { return i2p::util::filesystem::GetDefaultDataDir(); };
|
||||||
void CreateCertificate ();
|
void CreateCertificate (const char *crt_path, const char *key_path);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include "Config.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
@ -43,11 +44,12 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
i2p::data::RouterInfo routerInfo;
|
i2p::data::RouterInfo routerInfo;
|
||||||
routerInfo.SetRouterIdentity (GetIdentity ());
|
routerInfo.SetRouterIdentity (GetIdentity ());
|
||||||
int port = i2p::util::config::GetArg("-port", 0);
|
uint16_t port; i2p::config::GetOption("port", port);
|
||||||
if (!port)
|
if (!port)
|
||||||
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
|
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
|
||||||
routerInfo.AddSSUAddress (i2p::util::config::GetArg("-host", "127.0.0.1").c_str (), port, routerInfo.GetIdentHash ());
|
std::string host; i2p::config::GetOption("host", host);
|
||||||
routerInfo.AddNTCPAddress (i2p::util::config::GetArg("-host", "127.0.0.1").c_str (), port);
|
routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ());
|
||||||
|
routerInfo.AddNTCPAddress (host.c_str(), port);
|
||||||
routerInfo.SetCaps (i2p::data::RouterInfo::eReachable |
|
routerInfo.SetCaps (i2p::data::RouterInfo::eReachable |
|
||||||
i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC
|
i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC
|
||||||
routerInfo.SetProperty ("netId", std::to_string (I2PD_NET_ID));
|
routerInfo.SetProperty ("netId", std::to_string (I2PD_NET_ID));
|
||||||
|
5
api.cpp
5
api.cpp
@ -1,5 +1,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
@ -18,7 +19,9 @@ namespace api
|
|||||||
void InitI2P (int argc, char* argv[], const char * appName)
|
void InitI2P (int argc, char* argv[], const char * appName)
|
||||||
{
|
{
|
||||||
i2p::util::filesystem::SetAppName (appName);
|
i2p::util::filesystem::SetAppName (appName);
|
||||||
i2p::util::config::OptionParser(argc, argv);
|
i2p::config::Init ();
|
||||||
|
i2p::config::ParseCmdline (argc, argv);
|
||||||
|
i2p::config::Finalize ();
|
||||||
i2p::crypto::InitCrypto ();
|
i2p::crypto::InitCrypto ();
|
||||||
i2p::context.Init ();
|
i2p::context.Init ();
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
|||||||
set ( CMAKE_SOURCE_DIR ".." )
|
set ( CMAKE_SOURCE_DIR ".." )
|
||||||
|
|
||||||
set (LIBI2PD_SRC
|
set (LIBI2PD_SRC
|
||||||
|
"${CMAKE_SOURCE_DIR}/Config.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Crypto.cpp"
|
"${CMAKE_SOURCE_DIR}/Crypto.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Garlic.cpp"
|
"${CMAKE_SOURCE_DIR}/Garlic.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp"
|
"${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp"
|
||||||
|
23
debian/i2pd.conf
vendored
23
debian/i2pd.conf
vendored
@ -1,16 +1,19 @@
|
|||||||
floodfill=0
|
ipv6
|
||||||
v6=0
|
|
||||||
|
|
||||||
httpproxyaddress=127.0.0.1
|
[httpproxy]
|
||||||
httpproxyport=4444
|
address = 127.0.0.1
|
||||||
|
port = 4444
|
||||||
|
|
||||||
# other services (disabled by default)
|
# other services (disabled by default)
|
||||||
#
|
#
|
||||||
# samaddress=127.0.0.1
|
#[sam]
|
||||||
# samport=7656
|
#address = 127.0.0.1
|
||||||
|
#port = 7656
|
||||||
#
|
#
|
||||||
# bobaddress=127.0.0.1
|
#[bob]
|
||||||
# bobport=2827
|
#address = 127.0.0.1
|
||||||
|
#port = 2827
|
||||||
#
|
#
|
||||||
# i2pcontroladdress=127.0.0.1
|
#[i2pcontrol]
|
||||||
# i2pcontrolport=7650
|
#address = 127.0.0.1
|
||||||
|
#port = 7650
|
||||||
|
2
debian/i2pd.init
vendored
2
debian/i2pd.init
vendored
@ -46,7 +46,7 @@ do_start()
|
|||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" --test > /dev/null \
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" --test > /dev/null \
|
||||||
|| return 1
|
|| return 1
|
||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" -- \
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" -- \
|
||||||
--service=1 --daemon=1 --log=1 --conf=$I2PCONF --tunnelscfg=$TUNCONF \
|
--service --daemon --log --conf=$I2PCONF --tunconf=$TUNCONF \
|
||||||
--port=$I2PD_PORT $DAEMON_OPTS > /dev/null 2>&1 \
|
--port=$I2PD_PORT $DAEMON_OPTS > /dev/null 2>&1 \
|
||||||
|| return 2
|
|| return 2
|
||||||
return $?
|
return $?
|
||||||
|
6
debian/i2pd.upstart
vendored
6
debian/i2pd.upstart
vendored
@ -4,7 +4,7 @@ start on runlevel [2345]
|
|||||||
stop on runlevel [016] or unmounting-filesystem
|
stop on runlevel [016] or unmounting-filesystem
|
||||||
|
|
||||||
# these can be overridden in /etc/init/i2pd.override
|
# these can be overridden in /etc/init/i2pd.override
|
||||||
env I2P_HOST="1.2.3.4"
|
env I2PD_HOST="1.2.3.4"
|
||||||
env I2P_PORT="4567"
|
env I2PD_PORT="4567"
|
||||||
|
|
||||||
exec /usr/sbin/i2pd --daemon=0 --log=1 --host=$I2P_HOST --port=$I2P_PORT
|
exec /usr/sbin/i2pd --daemon --log --host=$I2PD_HOST --port=$I2PD_PORT
|
||||||
|
6
debian/postinst
vendored
6
debian/postinst
vendored
@ -1,6 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
LOGFILE='/var/log/i2pd.log'
|
||||||
I2PDHOME='/var/lib/i2pd'
|
I2PDHOME='/var/lib/i2pd'
|
||||||
I2PDUSER='i2pd'
|
I2PDUSER='i2pd'
|
||||||
|
|
||||||
@ -16,8 +17,9 @@ case "$1" in
|
|||||||
adduser --system --quiet --group --home $I2PDHOME $I2PDUSER
|
adduser --system --quiet --group --home $I2PDHOME $I2PDUSER
|
||||||
fi
|
fi
|
||||||
|
|
||||||
touch /var/log/i2pd.log
|
touch $LOGFILE
|
||||||
chown -f ${I2PDUSER}:adm /var/log/i2pd.log
|
chmod 640 $LOGFILE
|
||||||
|
chown -f ${I2PDUSER}:adm $LOGFILE
|
||||||
mkdir -p -m0750 $I2PDHOME
|
mkdir -p -m0750 $I2PDHOME
|
||||||
chown -f -R -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME}
|
chown -f -R -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME}
|
||||||
;;
|
;;
|
||||||
|
43
docs/config_opts_after_2.3.0.md
Normal file
43
docs/config_opts_after_2.3.0.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
Изменения обработки параметров в релизах > 2.3.0
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
Система параметров отличается от того, что было ранее и достаточно сильно:
|
||||||
|
|
||||||
|
* изменения имён и стиля параметров
|
||||||
|
|
||||||
|
Все параметры теперь в виде --help (gnu-style), у некоторых есть шорткаты в виде -h (unix-style).
|
||||||
|
Это касается всех систем, в том числе винды.
|
||||||
|
|
||||||
|
--daemon=1 и подобное -> просто --daemon, без параметра. Нет опции - false, есть - true
|
||||||
|
--notransit=1 -> --notransit, то же что и выше: есть опция - false, нет - true
|
||||||
|
--v6 -> --ipv6 (первое было похоже на версию какого-то своего протокола, типа socksproxy --v5)
|
||||||
|
--tunnelscfg -> --tunconf (имя параметра было слишком длинным, cfg переделан на conf - единообразно с --conf)
|
||||||
|
--sockskeys -> разделён на два, для socks и httpproxy по-отдельности
|
||||||
|
|
||||||
|
* поддержка секций в основном конфиге
|
||||||
|
|
||||||
|
Выглядит это так:
|
||||||
|
|
||||||
|
# основные опции
|
||||||
|
pidfile = /var/run/i2pd.pid
|
||||||
|
#
|
||||||
|
# настройки конкретного модуля
|
||||||
|
[httproxy]
|
||||||
|
address = 1.2.3.4
|
||||||
|
port = 4446
|
||||||
|
keys = httproxy-keys.dat
|
||||||
|
# и так далее
|
||||||
|
[sam]
|
||||||
|
enabled = no
|
||||||
|
addresss = 127.0.0.2
|
||||||
|
# ^^ переопределяется только адрес, остальное берётся из дефолта
|
||||||
|
|
||||||
|
Точно так же сейчас работает конфиг туннелей: секция до точки - имя, после - параметр
|
||||||
|
|
||||||
|
* поддержка выключения отдельных сервисов "на корню" см sam.enabled и подобное
|
||||||
|
|
||||||
|
Это позволило задать дефолт для номера порта и не писать его руками для включения.
|
||||||
|
|
||||||
|
* добавлен --help (см #110)
|
||||||
|
|
||||||
|
* присутствует некая валидация параметров, --port=abcd - не прокатит, --port=100500 - тоже
|
@ -4,46 +4,68 @@ i2pd configuration
|
|||||||
Command line options
|
Command line options
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
* --port= - The port to listen on
|
|
||||||
* --httpaddress= - The address to listen on (HTTP server)
|
|
||||||
* --httpport= - The port to listen on (HTTP server)
|
|
||||||
* --loglevel= - Log messages above this level (debug, *info, warn, error)
|
|
||||||
* --pidfile= - Where to write pidfile (dont write by default)
|
|
||||||
* --daemon= - Enable or disable daemon mode. 1 for yes, 0 for no. 0 by default
|
|
||||||
* --log= - Enable or disable logging to the file. 1 for daemon, 0 for non-daemon by default
|
|
||||||
* --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove")
|
|
||||||
* --service= - 1 if uses system folders (/var/run/i2pd.pid, /var/log/i2pd/i2pd.log, /var/lib/i2pd).
|
|
||||||
* --v6= - 1 if supports communication through ipv6, off by default
|
|
||||||
* --floodfill= - 1 if router is floodfill, off by default
|
|
||||||
* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited
|
|
||||||
* --notransit= - 1 if router doesn't accept transit tunnels at startup. 0 by default
|
|
||||||
* --httpproxyaddress= - The address to listen on (HTTP Proxy)
|
|
||||||
* --httpproxyport= - The port to listen on (HTTP Proxy) 4446 by default
|
|
||||||
* --socksproxyaddress= - The address to listen on (SOCKS Proxy)
|
|
||||||
* --socksproxyport= - The port to listen on (SOCKS Proxy). 4447 by default
|
|
||||||
* --proxykeys= - optional keys file for proxy local destination (both HTTP and SOCKS)
|
|
||||||
* --samaddress= - The address to listen on (SAM bridge)
|
|
||||||
* --samport= - Port of SAM bridge. Usually 7656. SAM is off if not specified
|
|
||||||
* --bobaddress= - The address to listen on (BOB command channel)
|
|
||||||
* --bobport= - Port of BOB command channel. Usually 2827. BOB is off if not specified
|
|
||||||
* --i2pcontroladdress= - The address to listen on (I2P control service)
|
|
||||||
* --i2pcontrolport= - Port of I2P control service. Usually 7650. I2PControl is off if not specified
|
|
||||||
* --tunnelscfg= - Tunnels Config file (default: ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg)
|
|
||||||
* --conf= - Config file (default: ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf)
|
* --conf= - Config file (default: ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf)
|
||||||
This parameter will be silently ignored if the specified config file does not exist.
|
This parameter will be silently ignored if the specified config file does not exist.
|
||||||
Options specified on the command line take precedence over those in the config file.
|
Options specified on the command line take precedence over those in the config file.
|
||||||
|
* --tunconf= - Tunnels Config file (default: ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg)
|
||||||
|
* --pidfile= - Where to write pidfile (dont write by default)
|
||||||
|
* --log - Enable or disable logging to file. 1 for yes, 0 for no.
|
||||||
|
* --logfile= - Path to logfile (stdout if not set, autodetect if daemon)
|
||||||
|
* --loglevel= - Log messages above this level (debug, *info, warn, error)
|
||||||
|
* --host= - The external IP (deprecated)
|
||||||
|
* --port= - The port to listen on
|
||||||
|
* --daemon - Enable or disable daemon mode. 1 for yes, 0 for no.
|
||||||
|
* --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove")
|
||||||
|
* --service - Use system folders (/var/run/i2pd.pid, /var/log/i2pd.log, /var/lib/i2pd).
|
||||||
|
* --ipv6 - Enable communication through ipv6, off by default
|
||||||
|
* --notransit - Router will not accept transit tunnels at startup. 0 by default
|
||||||
|
* --floodfill - Router will be floodfill, off by default
|
||||||
|
* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited
|
||||||
|
This option will be ignored if --floodfill given
|
||||||
|
|
||||||
|
* --http.address= - The address to listen on (HTTP server)
|
||||||
|
* --http.port= - The port to listen on (HTTP server)
|
||||||
|
|
||||||
|
* --httpproxy.address= - The address to listen on (HTTP Proxy)
|
||||||
|
* --httpproxy.port= - The port to listen on (HTTP Proxy) 4446 by default
|
||||||
|
* --httpproxy.keys= - optional keys file for proxy local destination (both HTTP and SOCKS)
|
||||||
|
|
||||||
|
* --socksproxy.address= - The address to listen on (SOCKS Proxy)
|
||||||
|
* --socksproxy.port= - The port to listen on (SOCKS Proxy). 4447 by default
|
||||||
|
* --socksproxy.keys= - optional keys file for proxy local destination (both HTTP and SOCKS)
|
||||||
|
* --socksproxy.outproxy= - Address of outproxy. requests outside i2p will go there
|
||||||
|
* --socksproxy.outproxyport= - Outproxy remote port
|
||||||
|
|
||||||
|
* --sam.address= - The address to listen on (SAM bridge)
|
||||||
|
* --sam.port= - Port of SAM bridge. Usually 7656. SAM is off if not specified
|
||||||
|
|
||||||
|
* --bob.address= - The address to listen on (BOB command channel)
|
||||||
|
* --bob.port= - Port of BOB command channel. Usually 2827. BOB is off if not specified
|
||||||
|
|
||||||
|
* --i2pcontrol.address= - The address to listen on (I2P control service)
|
||||||
|
* --i2pcontrol.port= - Port of I2P control service. Usually 7650. I2PControl is off if not specified
|
||||||
|
|
||||||
Config files
|
Config files
|
||||||
------------
|
------------
|
||||||
|
|
||||||
INI-like, syntax is the following : <key> = <value>.
|
INI-like, syntax is the following : <key> = <value>.
|
||||||
Comments are "#", not ";" as you may expect. See [boost ticket](https://svn.boost.org/trac/boost/ticket/808)
|
Comments are "#", not ";" as you may expect. See [boost ticket](https://svn.boost.org/trac/boost/ticket/808)
|
||||||
All command-line parameters are allowed as keys, for example:
|
All command-line parameters are allowed as keys, but note for those which contains dot (.).
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
i2p.conf:
|
i2p.conf:
|
||||||
|
|
||||||
log = 1
|
# comment
|
||||||
v6 = 0
|
log = yes
|
||||||
|
ipv6 = yes
|
||||||
|
# settings for specific module
|
||||||
|
[httpproxy]
|
||||||
|
port = 4444
|
||||||
|
# ^^ this will be --httproxy.port= in cmdline
|
||||||
|
# another one
|
||||||
|
[sam]
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
tunnels.cfg (filename of this config is subject of change):
|
tunnels.cfg (filename of this config is subject of change):
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@ LIB_SRC = \
|
|||||||
|
|
||||||
LIB_CLIENT_SRC = \
|
LIB_CLIENT_SRC = \
|
||||||
AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \
|
AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \
|
||||||
SAM.cpp SOCKS.cpp HTTPProxy.cpp
|
SAM.cpp SOCKS.cpp HTTPProxy.cpp Config.cpp
|
||||||
|
|
||||||
# also: Daemon{Linux,Win32}.cpp will be added later
|
# also: Daemon{Linux,Win32}.cpp will be added later
|
||||||
DAEMON_SRC = \
|
DAEMON_SRC = \
|
||||||
HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
|
HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp Config.cpp i2pd.cpp
|
||||||
|
|
||||||
|
121
util.cpp
121
util.cpp
@ -13,6 +13,7 @@
|
|||||||
#include <boost/program_options/detail/config_file.hpp>
|
#include <boost/program_options/detail/config_file.hpp>
|
||||||
#include <boost/program_options/parsers.hpp>
|
#include <boost/program_options/parsers.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include "Config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
@ -66,86 +67,6 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace config
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string> mapArgs;
|
|
||||||
|
|
||||||
void OptionParser(int argc, const char* const argv[])
|
|
||||||
{
|
|
||||||
mapArgs.clear();
|
|
||||||
for (int i = 1; i < argc; i++)
|
|
||||||
{
|
|
||||||
std::string strKey (argv[i]);
|
|
||||||
std::string strValue;
|
|
||||||
size_t has_data = strKey.find('=');
|
|
||||||
if (has_data != std::string::npos)
|
|
||||||
{
|
|
||||||
strValue = strKey.substr(has_data+1);
|
|
||||||
strKey = strKey.substr(0, has_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
boost::to_lower(strKey);
|
|
||||||
if (boost::algorithm::starts_with(strKey, "/"))
|
|
||||||
strKey = "-" + strKey.substr(1);
|
|
||||||
#endif
|
|
||||||
if (strKey[0] != '-')
|
|
||||||
break;
|
|
||||||
|
|
||||||
mapArgs[strKey] = strValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(PAIRTYPE(const std::string,std::string)& entry, mapArgs)
|
|
||||||
{
|
|
||||||
std::string name = entry.first;
|
|
||||||
|
|
||||||
// interpret --foo as -foo (as long as both are not set)
|
|
||||||
if (name.find("--") == 0)
|
|
||||||
{
|
|
||||||
std::string singleDash(name.begin()+1, name.end());
|
|
||||||
if (mapArgs.count(singleDash) == 0)
|
|
||||||
mapArgs[singleDash] = entry.second;
|
|
||||||
name = singleDash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetArg(const std::string& strArg, const std::string& strDefault)
|
|
||||||
{
|
|
||||||
if (mapArgs.count(strArg))
|
|
||||||
return mapArgs[strArg];
|
|
||||||
return strDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetArg(const std::string& strArg, int nDefault)
|
|
||||||
{
|
|
||||||
if (mapArgs.count(strArg))
|
|
||||||
return atoi(mapArgs[strArg].c_str());
|
|
||||||
return nDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadConfigFile(boost::filesystem::path path)
|
|
||||||
{
|
|
||||||
boost::filesystem::ifstream streamConfig(path);
|
|
||||||
if (!streamConfig.good())
|
|
||||||
return; // No i2pd.conf file is OK
|
|
||||||
|
|
||||||
std::set<std::string> setOptions;
|
|
||||||
setOptions.insert("*");
|
|
||||||
|
|
||||||
for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
|
|
||||||
{
|
|
||||||
// Don't overwrite existing settings so command line settings override i2pd.conf
|
|
||||||
std::string strKey = std::string("-") + it->string_key;
|
|
||||||
if (mapArgs.count(strKey) == 0)
|
|
||||||
{
|
|
||||||
mapArgs[strKey] = it->value[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace filesystem
|
namespace filesystem
|
||||||
{
|
{
|
||||||
std::string appName ("i2pd");
|
std::string appName ("i2pd");
|
||||||
@ -166,8 +87,10 @@ namespace filesystem
|
|||||||
|
|
||||||
// TODO: datadir parameter is useless because GetDataDir is called before OptionParser
|
// TODO: datadir parameter is useless because GetDataDir is called before OptionParser
|
||||||
// and mapArgs is not initialized yet
|
// and mapArgs is not initialized yet
|
||||||
/*if (i2p::util::config::mapArgs.count("-datadir"))
|
/*
|
||||||
path = boost::filesystem::system_complete(i2p::util::config::mapArgs["-datadir"]);
|
std::string datadir; i2p::config::GetOption("datadir", datadir);
|
||||||
|
if (datadir != "")
|
||||||
|
path = boost::filesystem::system_complete(datadir);
|
||||||
else */
|
else */
|
||||||
path = GetDefaultDataDir();
|
path = GetDefaultDataDir();
|
||||||
|
|
||||||
@ -200,17 +123,34 @@ namespace filesystem
|
|||||||
|
|
||||||
boost::filesystem::path GetConfigFile()
|
boost::filesystem::path GetConfigFile()
|
||||||
{
|
{
|
||||||
boost::filesystem::path pathConfigFile(i2p::util::config::GetArg("-conf", "i2p.conf"));
|
std::string config; i2p::config::GetOption("conf", config);
|
||||||
if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir() / pathConfigFile;
|
if (config != "") {
|
||||||
return pathConfigFile;
|
/* config file set with cmdline */
|
||||||
|
boost::filesystem::path path(config);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
/* else - try autodetect */
|
||||||
|
boost::filesystem::path path("i2p.conf");
|
||||||
|
path = GetDataDir() / path;
|
||||||
|
if (!boost::filesystem::exists(path))
|
||||||
|
path = ""; /* reset */
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path GetTunnelsConfigFile()
|
boost::filesystem::path GetTunnelsConfigFile()
|
||||||
{
|
{
|
||||||
boost::filesystem::path pathTunnelsConfigFile(i2p::util::config::GetArg("-tunnelscfg", "tunnels.cfg"));
|
std::string tunconf; i2p::config::GetOption("tunconf", tunconf);
|
||||||
if (!pathTunnelsConfigFile.is_complete())
|
if (tunconf != "") {
|
||||||
pathTunnelsConfigFile = GetDataDir() / pathTunnelsConfigFile;
|
/* config file set with cmdline */
|
||||||
return pathTunnelsConfigFile;
|
boost::filesystem::path path(tunconf);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
/* else - try autodetect */
|
||||||
|
boost::filesystem::path path("tunnels.cfg");
|
||||||
|
path = GetDataDir() / path;
|
||||||
|
if (!boost::filesystem::exists(path))
|
||||||
|
path = ""; /* reset */
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path GetDefaultDataDir()
|
boost::filesystem::path GetDefaultDataDir()
|
||||||
@ -225,7 +165,8 @@ namespace filesystem
|
|||||||
SHGetFolderPath(NULL, CSIDL_APPDATA, 0, NULL, localAppData);
|
SHGetFolderPath(NULL, CSIDL_APPDATA, 0, NULL, localAppData);
|
||||||
return boost::filesystem::path(std::string(localAppData) + "\\" + appName);
|
return boost::filesystem::path(std::string(localAppData) + "\\" + appName);
|
||||||
#else /* UNIX */
|
#else /* UNIX */
|
||||||
if (i2p::util::config::GetArg("-service", 0)) // use system folder
|
bool service; i2p::config::GetOption("service", service);
|
||||||
|
if (service) // use system folder
|
||||||
return boost::filesystem::path(std::string ("/var/lib/") + appName);
|
return boost::filesystem::path(std::string ("/var/lib/") + appName);
|
||||||
boost::filesystem::path pathRet;
|
boost::filesystem::path pathRet;
|
||||||
char* pszHome = getenv("HOME");
|
char* pszHome = getenv("HOME");
|
||||||
|
8
util.h
8
util.h
@ -14,14 +14,6 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
namespace config
|
|
||||||
{
|
|
||||||
void OptionParser(int argc, const char* const argv[]);
|
|
||||||
int GetArg(const std::string& strArg, int nDefault);
|
|
||||||
std::string GetArg(const std::string& strArg, const std::string& strDefault);
|
|
||||||
void ReadConfigFile(boost::filesystem::path path);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace filesystem
|
namespace filesystem
|
||||||
{
|
{
|
||||||
void SetAppName (const std::string& name);
|
void SetAppName (const std::string& name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user