Config.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * Copyright (c) 2013-2017, The PurpleI2P Project
  3. *
  4. * This file is part of Purple i2pd project and licensed under BSD3
  5. *
  6. * See full license text in LICENSE file at top of project tree
  7. */
  8. #include <cstdlib>
  9. #include <iostream>
  10. #include <fstream>
  11. #include <map>
  12. #include <string>
  13. #include <boost/program_options/cmdline.hpp>
  14. #include <boost/program_options/options_description.hpp>
  15. #include <boost/program_options/parsers.hpp>
  16. #include <boost/program_options/variables_map.hpp>
  17. #include "Identity.h"
  18. #include "Config.h"
  19. #include "version.h"
  20. using namespace boost::program_options;
  21. namespace i2p {
  22. namespace config {
  23. options_description m_OptionsDesc;
  24. variables_map m_Options;
  25. void Init()
  26. {
  27. options_description general("General options");
  28. general.add_options()
  29. ("help", "Show this message")
  30. ("version", "Show i2pd version")
  31. ("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
  32. ("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
  33. ("tunnelsdir", value<std::string>()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d")
  34. ("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
  35. ("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
  36. ("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
  37. ("loglevel", value<std::string>()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error, none)")
  38. ("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)")
  39. ("family", value<std::string>()->default_value(""), "Specify a family, router belongs to")
  40. ("datadir", value<std::string>()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
  41. ("host", value<std::string>()->default_value("0.0.0.0"), "External IP")
  42. ("ifname", value<std::string>()->default_value(""), "Network interface to bind to")
  43. ("ifname4", value<std::string>()->default_value(""), "Network interface to bind to for ipv4")
  44. ("ifname6", value<std::string>()->default_value(""), "Network interface to bind to for ipv6")
  45. ("nat", value<bool>()->default_value(true), "Should we assume we are behind NAT? (default: enabled)")
  46. ("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
  47. ("ipv4", value<bool>()->default_value(true), "Enable communication through ipv4 (default: enabled)")
  48. ("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)")
  49. ("netid", value<int>()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2")
  50. ("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)")
  51. ("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)")
  52. ("notransit", bool_switch()->default_value(false), "Router will not accept transit tunnels at startup (default: disabled)")
  53. ("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)")
  54. ("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)")
  55. ("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)")
  56. ("ntcp", value<bool>()->default_value(false), "Enable NTCP transport (default: disabled)")
  57. ("ssu", value<bool>()->default_value(true), "Enable SSU transport (default: enabled)")
  58. ("ntcpproxy", value<std::string>()->default_value(""), "Proxy URL for NTCP transport")
  59. #ifdef _WIN32
  60. ("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
  61. ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)")
  62. ("close", value<std::string>()->default_value("ask"), "Action on close: minimize, exit, ask")
  63. #endif
  64. ;
  65. options_description limits("Limits options");
  66. limits.add_options()
  67. ("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
  68. ("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
  69. ("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
  70. ("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Threshold to start probabilistic backoff with ntcp sessions (default: use system limit)")
  71. ("limits.ntcphard", value<uint16_t>()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)")
  72. ("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Maximum number of threads used by NTCP DH worker (default: 1)")
  73. ;
  74. options_description httpserver("HTTP Server options");
  75. httpserver.add_options()
  76. ("http.enabled", value<bool>()->default_value(true), "Enable or disable webconsole")
  77. ("http.address", value<std::string>()->default_value("127.0.0.1"), "Webconsole listen address")
  78. ("http.port", value<uint16_t>()->default_value(7070), "Webconsole listen port")
  79. ("http.auth", value<bool>()->default_value(false), "Enable Basic HTTP auth for webconsole")
  80. ("http.user", value<std::string>()->default_value("i2pd"), "Username for basic auth")
  81. ("http.pass", value<std::string>()->default_value(""), "Password for basic auth (default: random, see logs)")
  82. ("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
  83. ("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
  84. ("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
  85. ;
  86. options_description httpproxy("HTTP Proxy options");
  87. httpproxy.add_options()
  88. ("httpproxy.enabled", value<bool>()->default_value(true), "Enable or disable HTTP Proxy")
  89. ("httpproxy.address", value<std::string>()->default_value("127.0.0.1"), "HTTP Proxy listen address")
  90. ("httpproxy.port", value<uint16_t>()->default_value(4444), "HTTP Proxy listen port")
  91. ("httpproxy.keys", value<std::string>()->default_value(""), "File to persist HTTP Proxy keys")
  92. ("httpproxy.signaturetype", value<i2p::data::SigningKeyType>()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
  93. ("httpproxy.inbound.length", value<std::string>()->default_value("3"), "HTTP proxy inbound tunnel length")
  94. ("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length")
  95. ("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity")
  96. ("httpproxy.outbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy outbound tunnels quantity")
  97. ("httpproxy.latency.min", value<std::string>()->default_value("0"), "HTTP proxy min latency for tunnels")
  98. ("httpproxy.latency.max", value<std::string>()->default_value("0"), "HTTP proxy max latency for tunnels")
  99. ("httpproxy.outproxy", value<std::string>()->default_value(""), "HTTP proxy upstream out proxy url")
  100. ("httpproxy.addresshelper", value<bool>()->default_value(true), "Enable or disable addresshelper")
  101. ;
  102. options_description socksproxy("SOCKS Proxy options");
  103. socksproxy.add_options()
  104. ("socksproxy.enabled", value<bool>()->default_value(true), "Enable or disable SOCKS Proxy")
  105. ("socksproxy.address", value<std::string>()->default_value("127.0.0.1"), "SOCKS Proxy listen address")
  106. ("socksproxy.port", value<uint16_t>()->default_value(4447), "SOCKS Proxy listen port")
  107. ("socksproxy.keys", value<std::string>()->default_value(""), "File to persist SOCKS Proxy keys")
  108. ("socksproxy.signaturetype", value<i2p::data::SigningKeyType>()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
  109. ("socksproxy.inbound.length", value<std::string>()->default_value("3"), "SOCKS proxy inbound tunnel length")
  110. ("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length")
  111. ("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity")
  112. ("socksproxy.outbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy outbound tunnels quantity")
  113. ("socksproxy.latency.min", value<std::string>()->default_value("0"), "SOCKS proxy min latency for tunnels")
  114. ("socksproxy.latency.max", value<std::string>()->default_value("0"), "SOCKS proxy max latency for tunnels")
  115. ("socksproxy.outproxy.enabled", value<bool>()->default_value(false), "Enable or disable SOCKS outproxy")
  116. ("socksproxy.outproxy", value<std::string>()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy")
  117. ("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
  118. ;
  119. options_description sam("SAM bridge options");
  120. sam.add_options()
  121. ("sam.enabled", value<bool>()->default_value(true), "Enable or disable SAM Application bridge")
  122. ("sam.address", value<std::string>()->default_value("127.0.0.1"), "SAM listen address")
  123. ("sam.port", value<uint16_t>()->default_value(7656), "SAM listen port")
  124. ;
  125. options_description bob("BOB options");
  126. bob.add_options()
  127. ("bob.enabled", value<bool>()->default_value(false), "Enable or disable BOB command channel")
  128. ("bob.address", value<std::string>()->default_value("127.0.0.1"), "BOB listen address")
  129. ("bob.port", value<uint16_t>()->default_value(2827), "BOB listen port")
  130. ;
  131. options_description i2cp("I2CP options");
  132. i2cp.add_options()
  133. ("i2cp.enabled", value<bool>()->default_value(false), "Enable or disable I2CP")
  134. ("i2cp.address", value<std::string>()->default_value("127.0.0.1"), "I2CP listen address")
  135. ("i2cp.port", value<uint16_t>()->default_value(7654), "I2CP listen port")
  136. ;
  137. options_description i2pcontrol("I2PControl options");
  138. i2pcontrol.add_options()
  139. ("i2pcontrol.enabled", value<bool>()->default_value(false), "Enable or disable I2P Control Protocol")
  140. ("i2pcontrol.address", value<std::string>()->default_value("127.0.0.1"), "I2PCP listen address")
  141. ("i2pcontrol.port", value<uint16_t>()->default_value(7650), "I2PCP listen port")
  142. ("i2pcontrol.password", value<std::string>()->default_value("itoopie"), "I2PCP access password")
  143. ("i2pcontrol.cert", value<std::string>()->default_value("i2pcontrol.crt.pem"), "I2PCP connection certificate")
  144. ("i2pcontrol.key", value<std::string>()->default_value("i2pcontrol.key.pem"), "I2PCP connection certificate key")
  145. ;
  146. bool upnp_default = false;
  147. #if (defined(USE_UPNP) && (defined(WIN32_APP) || defined(ANDROID)))
  148. upnp_default = true; // enable UPNP for windows GUI and android by default
  149. #endif
  150. options_description upnp("UPnP options");
  151. upnp.add_options()
  152. ("upnp.enabled", value<bool>()->default_value(upnp_default), "Enable or disable UPnP: automatic port forwarding")
  153. ("upnp.name", value<std::string>()->default_value("I2Pd"), "Name i2pd appears in UPnP forwarding list")
  154. ;
  155. options_description precomputation("Precomputation options");
  156. precomputation.add_options()
  157. ("precomputation.elgamal",
  158. #if defined(__x86_64__)
  159. value<bool>()->default_value(false),
  160. #else
  161. value<bool>()->default_value(true),
  162. #endif
  163. "Enable or disable elgamal precomputation table")
  164. ;
  165. options_description reseed("Reseed options");
  166. reseed.add_options()
  167. ("reseed.verify", value<bool>()->default_value(false), "Verify .su3 signature")
  168. ("reseed.threshold", value<uint16_t>()->default_value(25), "Minimum number of known routers before requesting reseed")
  169. ("reseed.floodfill", value<std::string>()->default_value(""), "Path to router info of floodfill to reseed from")
  170. ("reseed.file", value<std::string>()->default_value(""), "Path to local .su3 file or HTTPS URL to reseed from")
  171. ("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
  172. ("reseed.proxy", value<std::string>()->default_value(""), "url for reseed proxy, supports http/socks")
  173. ("reseed.urls", value<std::string>()->default_value(
  174. "https://reseed.i2p-projekt.de/,"
  175. "https://i2p.mooo.com/netDb/,"
  176. "https://netdb.i2p2.no/,"
  177. // "https://us.reseed.i2p2.no:444/," // mamoth's shit
  178. // "https://uk.reseed.i2p2.no:444/," // mamoth's shit
  179. "https://reseed.i2p.net.in/,"
  180. "https://download.xxlspeed.com/,"
  181. "https://reseed-fr.i2pd.xyz/,"
  182. "https://reseed.memcpy.io/,"
  183. "https://reseed.onion.im/,"
  184. "https://i2pseed.creativecowpat.net:8443/,"
  185. "https://i2p.novg.net/"
  186. ), "Reseed URLs, separated by comma")
  187. ;
  188. options_description addressbook("AddressBook options");
  189. addressbook.add_options()
  190. ("addressbook.defaulturl", value<std::string>()->default_value(
  191. "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt"
  192. ), "AddressBook subscription URL for initial setup")
  193. ("addressbook.subscriptions", value<std::string>()->default_value(""), "AddressBook subscriptions URLs, separated by comma");
  194. options_description trust("Trust options");
  195. trust.add_options()
  196. ("trust.enabled", value<bool>()->default_value(false), "Enable explicit trust options")
  197. ("trust.family", value<std::string>()->default_value(""), "Router Familiy to trust for first hops")
  198. ("trust.routers", value<std::string>()->default_value(""), "Only Connect to these routers")
  199. ("trust.hidden", value<bool>()->default_value(false), "Should we hide our router from other routers?")
  200. ;
  201. options_description websocket("Websocket Options");
  202. websocket.add_options()
  203. ("websockets.enabled", value<bool>()->default_value(false), "Enable websocket server")
  204. ("websockets.address", value<std::string>()->default_value("127.0.0.1"), "Address to bind websocket server on")
  205. ("websockets.port", value<uint16_t>()->default_value(7666), "Port to bind websocket server on")
  206. ;
  207. options_description exploratory("Exploratory Options");
  208. exploratory.add_options()
  209. ("exploratory.inbound.length", value<int>()->default_value(2), "Exploratory inbound tunnel length")
  210. ("exploratory.outbound.length", value<int>()->default_value(2), "Exploratory outbound tunnel length")
  211. ("exploratory.inbound.quantity", value<int>()->default_value(3), "Exploratory inbound tunnels quantity")
  212. ("exploratory.outbound.quantity", value<int>()->default_value(3), "Exploratory outbound tunnels quantity")
  213. ;
  214. options_description ntcp2("NTCP2 Options");
  215. ntcp2.add_options()
  216. ("ntcp2.enabled", value<bool>()->default_value(true), "Enable NTCP2 (default: enabled)")
  217. ("ntcp2.published", value<bool>()->default_value(true), "Publish NTCP2 (default: enabled)")
  218. ("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)")
  219. ("ntcp2.addressv6", value<std::string>()->default_value("::"), "Address to bind NTCP2 on")
  220. ;
  221. options_description nettime("Time sync options");
  222. nettime.add_options()
  223. ("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
  224. ("nettime.ntpservers", value<std::string>()->default_value(
  225. "0.pool.ntp.org,"
  226. "1.pool.ntp.org,"
  227. "2.pool.ntp.org,"
  228. "3.pool.ntp.org"
  229. ), "Comma separated list of NTCP servers")
  230. ("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
  231. ;
  232. options_description persist("Network information persisting options");
  233. persist.add_options()
  234. ("persist.profiles", value<bool>()->default_value(true), "Persist peer profiles (default: true)")
  235. ("persist.addressbook", value<bool>()->default_value(true), "Persist full addresses (default: true)")
  236. ;
  237. m_OptionsDesc
  238. .add(general)
  239. .add(limits)
  240. .add(httpserver)
  241. .add(httpproxy)
  242. .add(socksproxy)
  243. .add(sam)
  244. .add(bob)
  245. .add(i2cp)
  246. .add(i2pcontrol)
  247. .add(upnp)
  248. .add(precomputation)
  249. .add(reseed)
  250. .add(addressbook)
  251. .add(trust)
  252. .add(websocket)
  253. .add(exploratory)
  254. .add(ntcp2)
  255. .add(nettime)
  256. .add(persist)
  257. ;
  258. }
  259. void ParseCmdline(int argc, char* argv[], bool ignoreUnknown)
  260. {
  261. try
  262. {
  263. auto style = boost::program_options::command_line_style::unix_style
  264. | boost::program_options::command_line_style::allow_long_disguise;
  265. style &= ~ boost::program_options::command_line_style::allow_guessing;
  266. if (ignoreUnknown)
  267. store(command_line_parser(argc, argv).options(m_OptionsDesc).style (style).allow_unregistered().run(), m_Options);
  268. else
  269. store(parse_command_line(argc, argv, m_OptionsDesc, style), m_Options);
  270. }
  271. catch (boost::program_options::error& e)
  272. {
  273. std::cerr << "args: " << e.what() << std::endl;
  274. exit(EXIT_FAILURE);
  275. }
  276. if (!ignoreUnknown && (m_Options.count("help") || m_Options.count("h")))
  277. {
  278. std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
  279. std::cout << m_OptionsDesc;
  280. exit(EXIT_SUCCESS);
  281. }
  282. else if (m_Options.count("version"))
  283. {
  284. std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
  285. std::cout << "Boost version "
  286. << BOOST_VERSION / 100000 << "." // maj. version
  287. << BOOST_VERSION / 100 % 1000 << "." // min. version
  288. << BOOST_VERSION % 100 // patch version
  289. << std::endl;
  290. #if defined(OPENSSL_VERSION_TEXT)
  291. std::cout << OPENSSL_VERSION_TEXT << std::endl;
  292. #endif
  293. #if defined(LIBRESSL_VERSION_TEXT)
  294. std::cout << LIBRESSL_VERSION_TEXT << std::endl;
  295. #endif
  296. exit(EXIT_SUCCESS);
  297. }
  298. }
  299. void ParseConfig(const std::string& path)
  300. {
  301. if (path == "") return;
  302. std::ifstream config(path, std::ios::in);
  303. if (!config.is_open())
  304. {
  305. std::cerr << "missing/unreadable config file: " << path << std::endl;
  306. exit(EXIT_FAILURE);
  307. }
  308. try
  309. {
  310. store(boost::program_options::parse_config_file(config, m_OptionsDesc), m_Options);
  311. }
  312. catch (boost::program_options::error& e)
  313. {
  314. std::cerr << e.what() << std::endl;
  315. exit(EXIT_FAILURE);
  316. };
  317. }
  318. void Finalize()
  319. {
  320. notify(m_Options);
  321. }
  322. bool IsDefault(const char *name)
  323. {
  324. if (!m_Options.count(name))
  325. throw "try to check non-existent option";
  326. if (m_Options[name].defaulted())
  327. return true;
  328. return false;
  329. }
  330. bool GetOptionAsAny(const char *name, boost::any& value)
  331. {
  332. if (!m_Options.count(name))
  333. return false;
  334. value = m_Options[name];
  335. return true;
  336. }
  337. bool GetOptionAsAny(const std::string& name, boost::any& value)
  338. {
  339. return GetOptionAsAny (name.c_str (), value);
  340. }
  341. } // namespace config
  342. } // namespace i2p