Skip to content

Conversation

vasild
Copy link
Contributor

@vasild vasild commented Oct 27, 2020

This PR is mostly for experiments, testing and discussion. It works but see below.

Add I2P support:

  • Outgoing connections to I2P destinations use the I2P socks5 proxy i2pd, i2p from the newly added option -i2pproxy=addr:port.
  • Incoming connections from I2P (listen) use statically configured destinations i2pd, i2p, similarly to statically configured Tor hidden services where the I2P/Tor daemon redirects incoming connections to an application listening on a normal TCP port. The user has to configure the I2P/Tor daemon separately from bitcoind.

What's missing:

  • -onlynet=i2p
  • -bind=127.0.0.1:8335=i2p in order to distinguish incoming I2P from incoming clearnet connections

It is possible to accept incoming connections using the SAM I2P protocol. This would make it possible to configure the destination (hidden service) automatically (so the user does not have to extra-configure the I2P daemon). It would also resolve the problem with distinguishing incoming I2P connections. I am looking into doing that.

If that is done, it will supersede this PR because both outgoing and incoming connections would be made via SAM. Thus this PR is a draft.


A bitcoin node is running at yfsvsy467mt5xafaq7zaukkjyzehvmew445yaaejvrwpk53acejq.b32.i2p:31872.

I2P addresses are Base32 encoded but have the padding `=` omitted.
Extend `DecodeBase32()` to support that.
Add a new config option so that users can specify a dedicated SOCKS5
proxy for reaching I2P peers.

I2P is a closed network (almost). The I2P proxy cannot be used to reach
non-I2P peers and the other proxies (the generic one and the Tor one)
cannot be used to reach I2P peers. Thus the new option is unrelated to
the other options: does not default to `-proxy` and `-proxy` is not used
to reach I2P peers.

When the new option is set the I2P network will be set as reachable,
thus making the node relay I2P addresses to its peers (see
`RelayAddress()`).
Recognize also I2P addresses in the form `base32encodedpublickey.b32.i2p`
from `CNetAddr::SetSpecial()`.

This makes `Lookup()` support them, which in turn makes it possible to
manually connect to an I2P node by using
`-i2pproxy=i2p_proxy:port -addnode=i2p_address.b32.i2p:port`
With this change the output of `getpeerinfo` and `getnetworkinfo`
contains proper `i2p` instead of an empty string:

```
bitcoin-cli getpeerinfo 2>&1 |jq '.[].network'
bitcoin-cli getnetworkinfo 2>&1 |jq '.networks[].name'
```
@fanquake fanquake added the P2P label Oct 27, 2020
@DrahtBot
Copy link
Contributor

DrahtBot commented Oct 27, 2020

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@Saibato
Copy link
Contributor

Saibato commented Oct 27, 2020

̶p̶l̶s̶ ̶n̶o̶t̶e̶ ̶t̶h̶e̶ ̶i̶2̶p̶ ̶p̶r̶o̶x̶y̶ ̶t̶a̶k̶e̶s̶ ̶a̶d̶d̶r̶e̶s̶s̶e̶s̶ ̶i̶n̶ ̶t̶h̶e̶ ̶f̶o̶r̶m̶ ̶y̶f̶s̶v̶s̶y̶4̶6̶7̶m̶t̶5̶x̶a̶f̶a̶q̶7̶z̶a̶u̶k̶k̶j̶y̶z̶e̶h̶v̶m̶e̶w̶4̶4̶5̶y̶a̶a̶e̶j̶v̶r̶w̶p̶k̶5̶3̶a̶c̶e̶j̶q̶.̶i̶2̶p̶
̶w̶i̶t̶h̶o̶u̶t̶ ̶.̶b̶3̶2̶.̶ ̶A̶F̶A̶I̶K̶
@vasild is ur node up? I was unable to reach from remote or is it by now just local?
And by what directory is it published, AFAIK one has to import that directory and address mappings before u can use an address.

@vasild
Copy link
Contributor Author

vasild commented Oct 27, 2020

Yes, it is up. From another computer:

2020-10-27T14:31:09Z New outbound peer connected: version: 70015, blocks=654455, peer=0, peeraddr=yfsvsy467mt5xafaq7zaukkjyzehvmew445yaaejvrwpk53acejq.b32.i2p:31872 (full-relay)

The .b32 must be present. See "B32" in https://i2pplus.com/glossary/. The port seems to be irrelevant. I guess we can skip it altogether.

@Saibato
Copy link
Contributor

Saibato commented Oct 27, 2020

Yes, it is up. From another computer:

thx, maybe i must update my version i use i2pd 2.29.0 ?

ediit@saibato
@vasild
Was able to connect 👍
I had forgot to create a fixed i2p client tunnel in i2pd for port 31872.

concept tACK

cmd line -connect=yfsvsy467mt5xafaq7zaukkjyzehvmew445yaaejvrwpk53acejq.b32.i2p:31872 then worked.

@vasild
Copy link
Contributor Author

vasild commented Oct 27, 2020

Was able to connect

Excellent!

However I got:

pid 82450 (i2pd), jid 0, uid 255: exited on signal 10
pid 19775 (i2pd), jid 0, uid 255: exited on signal 6
pid 19909 (i2pd), jid 0, uid 255: exited on signal 6
pid 20207 (i2pd), jid 0, uid 255: exited on signal 6

I stopped it until I figure out what's going on.

@Saibato
Copy link
Contributor

Saibato commented Oct 27, 2020

I stopped it until I figure out what's going on.

tyi, while testing i also direct connected with netcat and connect-proxy without the bitcoin client and hammered on my keyboard, happy fuzzing! Maybe something @practicalswift might want to look in?

@jonatack
Copy link
Member

jonatack commented Nov 3, 2020

@vasild Yay! My node is connected to your I2P peer and you even sent me a block.

If you pull the last commit of https://github.com/jonatack/bitcoin/commits/netinfo-add-i2p into this draft PR, -netinfo will display I2P peers.

Peer connections sorted by direction and min ping
<-> relay   net  mping   ping send recv  txn  blk  age  asmap id address                                                        version
out  full   i2p   1375   1375    1    3    0    1    6        44 yfsvsy467mt5xafaq7zaukkjyzehvmew445yaaejvrwpk53acejq.b32.i2p   70015/Satoshi:0.20.1/
                    ms     ms  sec  sec  min  min  min

        ipv4    ipv6   onion     i2p   total  block-relay
in         0       0       0       0       0       0
out        6       0      12       1      19       2
total      6       0      12       1      19       2

@@ -457,12 +457,13 @@ void SetupServerArgs(NodeContext& node)
argsman.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)", DEFAULT_MAX_TIME_ADJUSTMENT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxuploadtarget=<n>", 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=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-i2pproxy=<ip:port>", "SOCKS5 proxy to reach I2P peers (default: none, I2P peers are not reachable)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if -proxy=<ip:port>=i2p would make more sense

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe yes. Anyway, I am working on a support for the I2P SAM protocol which would be used to accept incoming connections - it allows us to know that it is an I2P incoming connection and also to know the peer's I2P address. That will be -i2psam=<addr:port>. Once we have that we can use it also for making outgoing connections, so -i2pproxy= will not be needed.


/**
* Base32 decode.
* If `allow_nopad` is true, then the input is allowed to have length that is not
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is outdated?

Copy link
Contributor Author

@vasild vasild Nov 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed! I renamed the parameter so that the default behavior is with a true argument, to be in line with EncodeBase32().

@vasild
Copy link
Contributor Author

vasild commented Nov 13, 2020

pid 82450 (i2pd), jid 0, uid 255: exited on signal 10
I stopped it until I figure out what's going on.

PurpleI2P/i2pd#1568

@luke-jr
Copy link
Member

luke-jr commented Nov 27, 2020

Is it intentional that this (alone) ignores the bare -proxy setting?

@vasild
Copy link
Contributor Author

vasild commented Nov 27, 2020

@luke-jr yes, usually an I2P socks5 proxy can be used only for connecting to I2P addresses*, so if we point -proxy to such a proxy, then one will not be able to make connections to IPv4, IPv6 or Tor addresses.

*there could be exceptions and there may be out-routers for going out of the I2P network, but that is unreliable.

Copy link
Contributor

@lontivero lontivero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was implementing a pretty similar subset of this PR. You could take the UTs from here: https://github.com/lontivero/bitcoin/blob/6b07fb122a9690f0480766fe45d4dc789dbca2e3/src/test/net_tests.cpp#L349-L367

@vasild
Copy link
Contributor Author

vasild commented Dec 16, 2020

You could take the UTs from here...

Done in vasild@2f49323 (part of the I2P SAM implementation which I am going to PR soon to supersede this PR).

Thanks!

@vasild
Copy link
Contributor Author

vasild commented Dec 17, 2020

Closing this as superseded by #20685

@vasild vasild closed this Dec 17, 2020
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants