diff --git a/doc/i2p.md b/doc/i2p.md index 92c69f4841..10f0605dad 100644 --- a/doc/i2p.md +++ b/doc/i2p.md @@ -16,8 +16,7 @@ enabled is required. Options include: Java - [i2pd (I2P Daemon)](https://github.com/PurpleI2P/i2pd) ([documentation](https://i2pd.readthedocs.io/en/latest)), a lighter - alternative in C++ (successfully tested with version 2.23 and up; version 2.36 - or later recommended) + alternative in C++ - [i2p-zero](https://github.com/i2p-zero/i2p-zero) - [other alternatives](https://en.wikipedia.org/wiki/I2P#Routers) @@ -33,12 +32,10 @@ Core configuration options: none) -i2pacceptincoming - If set and -i2psam is also set then incoming I2P connections are - accepted via the SAM proxy. If this is not set but -i2psam is set - then only outgoing connections will be made to the I2P network. - Ignored if -i2psam is not set. Listening for incoming I2P - connections is done through the SAM proxy, not by binding to a - local address and port (default: 1) + Whether to accept inbound I2P connections (default: 1). Ignored if + -i2psam is not set. Listening for inbound I2P connections is + done through the SAM proxy, not by binding to a local address and + port. ``` In a typical situation, this suffices: @@ -47,27 +44,6 @@ In a typical situation, this suffices: dashd -i2psam=127.0.0.1:7656 ``` -The first time Dash Core connects to the I2P router, if -`-i2pacceptincoming=1`, then it will automatically generate a persistent I2P -address and its corresponding private key. The private key will be saved in a -file named `i2p_private_key` in the Dash Core data directory. The persistent -I2P address is used for accepting incoming connections and for making outgoing -connections if `-i2pacceptincoming=1`. If `-i2pacceptincoming=0` then only -outbound I2P connections are made and a different transient I2P address is used -for each connection to improve privacy. - -## Persistent vs transient I2P addresses - -In I2P connections, the connection receiver sees the I2P address of the -connection initiator. This is unlike the Tor network where the recipient does -not know who is connecting to them and can't tell if two connections are from -the same peer or not. - -If an I2P node is not accepting incoming connections, then Dash Core uses -random, one-time, transient I2P addresses for itself for outbound connections -to make it harder to discriminate, fingerprint or analyze it based on its I2P -address. - ## Additional configuration options related to I2P ``` @@ -104,7 +80,29 @@ In general, a node can be run with both onion and I2P hidden services (or any/all of IPv4/IPv6/onion/I2P), which can provide a potential fallback if one of the networks has issues. -## I2P-related information in Dash Core +## Persistent vs transient I2P addresses + +The first time Dash Core connects to the I2P router, it automatically +generates a persistent I2P address and its corresponding private key by default +or if `-i2pacceptincoming=1` is set. The private key is saved in a file named +`i2p_private_key` in the Dash Core data directory. The persistent I2P +address is used for making outbound connections and accepting inbound +connections. + +In the I2P network, the receiver of an inbound connection sees the address of +the initiator. This is unlike the Tor network, where the recipient does not +know who is connecting to it. + +If your node is configured by setting `-i2pacceptincoming=0` to not accept +inbound I2P connections, then it will use a random transient I2P address for +itself on each outbound connection to make it harder to discriminate, +fingerprint or analyze it based on its I2P address. + +I2P addresses are designed to be long-lived. Waiting for tunnels to be built +for every peer connection adds delay to connection setup time. Therefore, I2P +listening should only be turned off if really needed. + +## Fetching I2P-related information from Dash Core There are several ways to see your I2P address in Dash Core if accepting incoming I2P connections (`-i2pacceptincoming`): @@ -140,14 +138,19 @@ port (`TO_PORT`) is always set to 0 and is not in the control of Dash Core. ## Bandwidth -I2P routers may route a large amount of general network traffic with their -default settings. Check your router's configuration to limit the amount of this -traffic relayed, if desired. +By default, your node shares bandwidth and transit tunnels with the I2P network +in order to increase your anonymity with cover traffic, help the I2P router used +by your node integrate optimally with the network, and give back to the network. +It's important that the nodes of a popular application like Dash contribute +as much to the I2P network as they consume. -With `i2pd`, the amount of bandwidth being shared with the wider network can be -adjusted with the `bandwidth`, `share` and `transittunnels` options in your -`i2pd.conf` file. For example, to limit total I2P traffic to 256KB/s and share -50% of this limit for a maximum of 20 transit tunnels: +It is possible, though strongly discouraged, to change your I2P router +configuration to limit the amount of I2P traffic relayed by your node. + +With `i2pd`, this can be done by adjusting the `bandwidth`, `share` and +`transittunnels` options in your `i2pd.conf` file. For example, to limit total +I2P traffic to 256KB/s and share 50% of this limit for a maximum of 20 transit +tunnels: ``` bandwidth = 256 @@ -157,9 +160,15 @@ share = 50 transittunnels = 20 ``` -If you prefer not to relay any public I2P traffic and only permit I2P traffic -from programs which are connecting via the SAM proxy, e.g. Dash Core, you -can set the `notransit` option to `true`. - Similar bandwidth configuration options for the Java I2P router can be found in `http://127.0.0.1:7657/config` under the "Bandwidth" tab. + +Before doing this, please see the "Participating Traffic Considerations" section +in [Embedding I2P in your Application](https://geti2p.net/en/docs/applications/embedding). + +In most cases, the default router settings should work fine. + +## Bundling I2P in a Dash application + +Please see the "General Guidance for Developers" section in https://geti2p.net/en/docs/api/samv3 +if you are developing a downstream application that may be bundling I2P with Dash. diff --git a/src/init.cpp b/src/init.cpp index 3a83d70086..d600e54a85 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -131,8 +131,9 @@ #include #endif -static const bool DEFAULT_PROXYRANDOMIZE = true; -static const bool DEFAULT_REST_ENABLE = false; +static constexpr bool DEFAULT_PROXYRANDOMIZE{true}; +static constexpr bool DEFAULT_REST_ENABLE{false}; +static constexpr bool DEFAULT_I2P_ACCEPT_INCOMING{true}; static CDSNotificationInterface* pdsNotificationInterface = nullptr; @@ -581,7 +582,7 @@ void SetupServerArgs(NodeContext& node) argsman.AddArg("-maxuploadtarget=", strprintf("Tries to keep outbound traffic under the given target (in MiB per 24h). Limit does not apply to peers with 'download' permission. 0 = no limit (default: %d)", DEFAULT_MAX_UPLOAD_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-onion=", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-i2psam=", "I2P SAM proxy to reach I2P peers and accept I2P connections (default: none)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-i2pacceptincoming", "If set and -i2psam is also set then incoming I2P connections are accepted via the SAM proxy. If this is not set but -i2psam is set then only outgoing connections will be made to the I2P network. Ignored if -i2psam is not set. Listening for incoming I2P connections is done through the SAM proxy, not by binding to a local address and port (default: 1)", ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION); + argsman.AddArg("-i2pacceptincoming", strprintf("Whether to accept inbound I2P connections (default: %i). Ignored if -i2psam is not set. Listening for inbound I2P connections is done through the SAM proxy, not by binding to a local address and port.", DEFAULT_I2P_ACCEPT_INCOMING), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-onlynet=", "Make outgoing connections only through network (" + Join(GetNetworkNames(), ", ") + "). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks. Warning: if it is used with non-onion networks and the -onion or -proxy option is set, then outbound onion connections will still be made; use -noonion or -onion=0 to disable outbound onion connections in this case.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); @@ -2534,7 +2535,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc SetReachable(NET_I2P, false); } - connOptions.m_i2p_accept_incoming = args.GetBoolArg("-i2pacceptincoming", true); + connOptions.m_i2p_accept_incoming = args.GetBoolArg("-i2pacceptincoming", DEFAULT_I2P_ACCEPT_INCOMING); if (!node.connman->Start(*node.dmnman, *node.mn_metaman, *node.mn_sync, *node.scheduler, connOptions)) { return false; diff --git a/test/functional/p2p_i2p_sessions.py b/test/functional/p2p_i2p_sessions.py index 4e52522b81..9e7fdc6e14 100755 --- a/test/functional/p2p_i2p_sessions.py +++ b/test/functional/p2p_i2p_sessions.py @@ -23,12 +23,12 @@ class I2PSessions(BitcoinTestFramework): self.log.info("Ensure we create a persistent session when -i2pacceptincoming=1") node0 = self.nodes[0] - with node0.assert_debug_log(expected_msgs=[f"Creating persistent SAM session"]): + with node0.assert_debug_log(expected_msgs=["Creating persistent SAM session"]): node0.addnode(node=addr, command="onetry") self.log.info("Ensure we create a transient session when -i2pacceptincoming=0") node1 = self.nodes[1] - with node1.assert_debug_log(expected_msgs=[f"Creating transient SAM session"]): + with node1.assert_debug_log(expected_msgs=["Creating transient SAM session"]): node1.addnode(node=addr, command="onetry")