libtorrent
libtorrent copied to clipboard
Identify I2P peers
Can't find a way to identify I2P peers. peer_info
contains only IP and port number which are meaningless for I2P.
Actually there is torrent_peer::dest()
that could have a counterpart in peer_info
(even better in base32 i2p name form).
Unfortunately I have a feeling that @arvidn will upset us again by not being able to add some new field in peer_info
, as this will break ABI compatibility.
I've had same problem while trying to make deluge-torrent show i2p peers. My "solution" has been showing peer_id in place of ip:port to make some sense.
My "solution" has been showing peer_id in place of ip:port to make some sense.
IIRC, peer_id has the same meaning for regular and i2p peers while i2p destination is more appropriate counterpart of IP:port
.
My "solution" has been showing peer_id in place of ip:port to make some sense.
I think that putting non-addresses into address column is inappropriate. For me it is better to have no data there at all until proper solution is developed.
@glassez @Vort you're both right but as long as there's no way to get i2p destinations I thought that having an unique identifier for an i2p peer was better (just for visualizarion) than a list of empty addresses with no meaning. Biglybt as I know has an internal minimal i2p router implementation so it can retrieve destinations. I've never used it so I don't know if those are shown even when using a standalone "external" i2p router (java or i2pd). Did you tried it?
Can't find a way to identify I2P peers.
peer_info
contains only IP and port number which are meaningless for I2P.
It seems that peers do not have any (common) unique identifier at all (at least accessible to the client application), so that by obtaining two consecutive peer_info
sets, we could uniquely determine the peers common to both sets.
After making small changes to libtorrent and adding its support to qBittorrent, I can offer the following:
@glassez Seems you've found a way!
@glassez Please take into consideration options to disable dht and pex for i2p torrents when mixed mode is not enabled (if possible) since those can't be done over i2p yet (till libtorrent doesn't implement them) and to check if the client tries to resolve the tracker's address on clearnet (it obviously fails but it's still a leak). For the rest....Great job!!
it's true that adding a field to hold the i2p destination in peer_info
would break ABI. An alternative approach would be to ensure the peer-id is unique (or maybe even contain the first part of the destination).
I imagine that the actual destination isn't really important. I would expect all of them to be ephemeral keys set up just for this connection. If you disconnect and reconnect to the same peer later, it may have a different destination address.
Are those destination addresses base32? (it looks like the .b32
part of the address might indicate that). Does that mean they are 32 byte keys? If so, the current fields ip
and local_endpoint
could be turned into a union holding those 32 bytes of key, when the peer is an i2p peer.
Are those destination addresses base32? (it looks like the .b32 part of the address might indicate that). Does that mean they are 32 byte keys?
"I2P uses 52 characters (256 bits) to represent the full SHA-256 hash. The form is {52 chars}.b32.i2p." https://geti2p.net/en/docs/naming#base32
Are those destination addresses base32? (it looks like the .b32 part of the address might indicate that). Does that mean they are 32 byte keys?
"I2P uses 52 characters (256 bits) to represent the full SHA-256 hash. The form is {52 chars}.b32.i2p." https://geti2p.net/en/docs/naming#base32
I2P destination is base64 encoded fingerprint of peer. Base32 I2P address is base32encode(sha256(base64decode(destination)))
with removed trailing pad characters, converted to lower case and appended with .b32.i2p
.
Actually there are two kind of issues: unique identification of peers within current set in general, and (possibly as a subproblem), the lack of providing analog of IP addresses for I2P peers.
it's true that adding a field to hold the i2p destination in
peer_info
would break ABI. An alternative approach would be to ensure the peer-id is unique (or maybe even contain the first part of the destination).
IIRC, peer_id
just provides corresponding field reported by peers to tracker. So many people expect to have exactly this data there in order to use it in the traditional way. The problem is that many peers have it empty at all (at least that's how it looks when I get a peer_info
's from libtorrent
). So we can't use it as unique identifier.
I imagine that the actual destination isn't really important. I would expect all of them to be ephemeral keys set up just for this connection. If you disconnect and reconnect to the same peer later, it may have a different destination address.
It would still be useful for the purposes of visual distinguishing the currently displayed peers.
Does that mean they are 32 byte keys? If so, the current fields
ip
andlocal_endpoint
could be turned into a union holding those 32 bytes of key, when the peer is an i2p peer.
32 byte is enough to provide address in intermediate sha256 encoded form. Although I feel it as a workaround, we can still use it until next update.
IMO, the main things that we should take out of the discussion of problems like this is the changes that should be added to the master
(since we can't add them to the release branches), and how to modify the API of the master
so that in the future we have fewer such problems with ABI compatibility.
Base32 I2P address is base32encode(sha256(base64decode(destination))) with removed trailing pad characters, converted to lower case and appended with .b32.i2p.
So, exposing the SHA-256 hashes for peers, that would be a reasonable, long-term format for the API, right?
looking over this code, it would be really nice to switch to using this format for i2p destinations internally too, to avoid string handling and heap allocations.
Not sure what place are you talking about, but full base64 keys are needed for interactions with SAM.
Not sure what place are you talking about, but full base64 keys are needed for interactions with SAM.
That's not what the documentation says (here):
NOTE: Since about 2014 (SAM v3.1), Java I2P has also supported hostnames and b32 addresses for the $destination, but this was previously undocumented. Hostnames and b32 addresses are now officially supported by Java I2P as of release 0.9.48
I also find it quite confusing to refer to the kind of destination address by what encoding it's using, as if that was the main distinction. The "base32" addresses are just the sha256 hash of a destination, and a destination is the full key (afaiu).
The former is usually encoded with base32 and the latter is usually encoded with base64.
That's not what the documentation says
STREAM ACCEPT
uses full key:
"SAM bridge sends the client a ASCII line containing the base64 public destination key of the requesting peer"
https://geti2p.net/en/docs/api/samv3
I don't understand what point you're making. My reading of the document I linked to allows me to SHA-256
that base64 encoded destination string and use that hash to refer to that peer. If I want to connect back to it, I just base32 encode the hash and append .b32.i2p
and I'm good to go.
Ok, I agree that it may be possible. However I'm not sure which approach will be faster.
- Frequent "string handling and heap allocations" vs occasional SHA256.
- Making base32 -> base64 lookups manually vs allowing i2p software to make them instead.
I asked @orignal and he said that storing of base32 addresses is good solution.
There is undocumented hack that both i2pd and Java I2p allows .i2p addresses in STREAM CONNECT directly, including .b32.i2p
In i2pd if (destination.find(".i2p") != std::string::npos) addr = context.GetAddressBook().GetAddress (destination);
So you don't need full base64 address to connect to a destination. b32 address in enough to store.
It also works with B33 addresses(encrypted LeaseSet) where full base64 address doesn't exist.
@orignal it's even documented and officially supported by now (as I quoted here).
@glassez how does this look? https://github.com/arvidn/libtorrent/pull/7356
There are a few other commits in there to fix up i2p support, but the main commit is adding lt::sha256_hash peer_info::i2p_destination()
.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.