Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use a random string as peer-name in mDNS #368

Merged
merged 1 commit into from
Oct 12, 2021

Conversation

marten-seemann
Copy link
Contributor

We don't use the <peer-name> for anything, we only should make sure that there's no collision in the network (I think). This was part of the initial design requirements: libp2p/libp2p#28 (Proposal section).

Instead of figuring out how to best encode a peer ID such that it fits into 63 characters, a problem we've struggled with for a very long time, we can just admit that we're only filling this field because the RFC requires us to do so, and use random garbage.

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

I am not an expert on mDNS. Proposal is fine by me.

Could you bump the spec version @marten-seemann?

//CC @dvc94ch as you have been working a bunch on the Rust mDNS implementation and thus might have opinions.

Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

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

This is fine by me. I think this peer name could have been used to query for specific peers on the local network, but we're unlikely to ever do that (we'd end up sending a lot of mDNS spam).

@dvc94ch
Copy link

dvc94ch commented Oct 7, 2021

The problem is a different one. Why are peer ids allowed to be longer than 63 characters. Also the name can be segmented using the DNS segmentation algorithm if I recall. rust-libp2p does this.

@aschmahmann
Copy link
Contributor

Why are peer ids allowed to be longer than 63 characters

AFAIK this is only possible if someone decides to encode peerIDs as CIDs using a base smaller than 36. Perhaps there's a reasonable argument for decoupling here in the event that at some point it became necessary to switch the hash function used for keys to be something longer than sha2-256 that won't fit into a lowercase encoding.

Also the name can be segmented using the DNS segmentation algorithm if I recall

What do you mean? Is there an example or a spec I can look at?

@dvc94ch
Copy link

dvc94ch commented Oct 7, 2021

something longer than sha2-256 that won't fit into a lowercase encoding

so you mean a 512 bit hash for pq security?

What do you mean? Is there an example or a spec I can look at?

so according to the spec a label is 63 characters [0]. rust-libp2p [1] works around it by splitting a peer_id longer than 63 characters into multiple labels and joining them as subdomains with a ..

@aschmahmann
Copy link
Contributor

aschmahmann commented Oct 7, 2021

so you mean a 512 bit hash for pq security?

There are a variety of reasons I could imagine someone proposing a change in the hash function, but yes e.g. someone wanting a 512 bit one.

rust-libp2p [1] works around it by splitting a peer_id longer than 63 characters into multiple labels and joining them as subdomains with a .

Ah, ya. I'm not sure what the tradeoffs are here. It might just work in the mDNS case, but I'm not sure what types of things the tooling around mDNS expects. We have a similar problem in go-ipfs (ipfs/kubo#7318) where the . splitting isn't a great solution basically because no one will grant *.*.mydomain certificates even though it seems like the kind of thing that's reasonable and not a spec problem.

@dvc94ch
Copy link

dvc94ch commented Oct 7, 2021

In any case that seems like an ipfs problem. Not sure why getting TLS certificates from some CA for . split peer IDs has anything to do with libp2p.

@aschmahmann
Copy link
Contributor

aschmahmann commented Oct 7, 2021

Yes. My point was just that there is already evidence that DNS tooling exists that won't be happy with arbitrary . splits. It might not be a big deal in most mDNS contexts, but wanted to flag that it's not quite as simple as "works on my machine".

@dvc94ch
Copy link

dvc94ch commented Oct 7, 2021

My suggestion would be to leave it as is and design your own protocol once you have the bandwidth. The libp2p-mdns seems shoe horned onto an mdns spec. You can probably build something much simpler for discovering peers and their addresses in local networks using multicast, at least in terms of the packet format.

@dvc94ch
Copy link

dvc94ch commented Oct 7, 2021

It might not be a big deal in most mDNS contexts, but wanted to flag that it's not quite as simple as "works on my machine".

Actyx has deployed the rust-libp2p mdns on Android/windows/Linux in the mission critical context of factories. I think it's pretty clear that it works on more than just my machine

@aschmahmann
Copy link
Contributor

Is Actyx using the . delimited names? I'd think all their names would fit in the 63 character limit.

@dvc94ch
Copy link

dvc94ch commented Oct 7, 2021

Is Actyx using the . delimited names? I'd think all their names would fit in the 63 character limit.

Probably. But we also don't care about mdns compatibility. We only care about discovering other local rust-libp2p nodes, and I presume that's the sentiment of many rust-libp2p users.

@marten-seemann
Copy link
Contributor Author

I was trying to avoid having to solve the problem of how to map peer IDs to subdomains.
We've had this discussion for a long time, with no clear solution so far. I suggest we don't try to solve this problem here, because for mDNS, we don't need to solve it.

All we need for mDNS is a unique identifier shorter than 64 characters, and this PR suggests the (probably) easiest solution to achieve this property.

@dvc94ch
Copy link

dvc94ch commented Oct 11, 2021

I guess it's backwards compatible with existing implementations as long as they use peer ids shorter than 64 characters

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

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

Looks sensible.

  • While we don't need TLS wildcard certificates in mDNS context, subdomain splitting might cause issues with existing mDNS libraries.
  • The simplified spec proposed here makes it easier to implement and reduces potential issues with naive mdns implementations that do not support subdomains, giving us backward-compatibility for free.

Small suggestions inline, but feel free to merge without them.

Comment on lines 168 to 169
- `name`._p2p._udp.local IN TXT dnsaddr=/ip6/fe80::7573:b0a8:46b0:bfea/tcp/4001/p2p/`id`
- `name`._p2p._udp.local IN TXT dnsaddr=/ip4/192.168.178.21/tcp/4001/p2p/'id'
- `name`._p2p._udp.local IN TXT dnsaddr=/ip4/192.168.178.21/tcp/4001/p2p/`id`
Copy link
Member

Choose a reason for hiding this comment

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

nit; i assume the name should be renamed to peer-name here for consistency?


If the encoding of the peer's ID exceeds 63 characters, then the [Split at 63rd character](https://github.com/ipfs/in-web-browsers/issues/89#issue-341357014) workaround can be used.
As the this field doesn't carry any meaning, it is sufficient to ensure the uniqueness of this identifier. Peers SHOULD generate a random, lower-case alphanumeric string of least 32 characters in length when booting up their node.
Copy link
Member

@lidel lidel Oct 11, 2021

Choose a reason for hiding this comment

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

Perhaps it's better to give people some hints to limit bad names with low entropy?

Suggested change
As the this field doesn't carry any meaning, it is sufficient to ensure the uniqueness of this identifier. Peers SHOULD generate a random, lower-case alphanumeric string of least 32 characters in length when booting up their node.
As the this field doesn't carry any meaning, it is sufficient to ensure the uniqueness of this identifier. Peers SHOULD generate a random, lower-case alphanumeric string of least 32 characters in length when booting up their node. Peers SHOULD not use their Peer ID here because a future Peer ID could exceed the DNS label limit of 63 characters. When access to reliable randomness is difficult, implementer can derive `peer-name` from Peer ID using a cryptographic hash function that produces digests with lower-case alphanumeric representation shorter than DNS label limit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I took the first part of your suggestion. I'm not too worried about peers without access to randomness.

@mxinden
Copy link
Member

mxinden commented Oct 12, 2021

Could you bump the spec version @marten-seemann?

Friendly ping :)

@lidel lidel deleted the mdns-random-peer-name branch October 13, 2021 14:44
mxinden added a commit to libp2p/rust-libp2p that referenced this pull request Nov 25, 2021
With libp2p/specs#368 the definition of the _peer name_
changed in the mDNS specification.

> peer-name is the case-insensitive unique identifier of the peer, and is less
> than 64 characters.
>
> As the this field doesn't carry any meaning, it is sufficient to ensure the
> uniqueness of this identifier. Peers SHOULD generate a random, lower-case
> alphanumeric string of least 32 characters in length when booting up their
> node. Peers SHOULD NOT use their Peer ID here because a future Peer ID could
> exceed the DNS label limit of 63 characters.

https://github.com/libp2p/specs/blob/master/discovery/mdns.md

This commit adjusts `libp2p-mdns` accordingly.

Also see libp2p/go-libp2p#1222 for the corresponding
change on the Golang side.

Co-authored-by: Max Inden <mail@max-inden.de>
vnermolaev pushed a commit to vnermolaev/rust-libp2p that referenced this pull request Nov 30, 2021
…p#2311)

With libp2p/specs#368 the definition of the _peer name_
changed in the mDNS specification.

> peer-name is the case-insensitive unique identifier of the peer, and is less
> than 64 characters.
>
> As the this field doesn't carry any meaning, it is sufficient to ensure the
> uniqueness of this identifier. Peers SHOULD generate a random, lower-case
> alphanumeric string of least 32 characters in length when booting up their
> node. Peers SHOULD NOT use their Peer ID here because a future Peer ID could
> exceed the DNS label limit of 63 characters.

https://github.com/libp2p/specs/blob/master/discovery/mdns.md

This commit adjusts `libp2p-mdns` accordingly.

Also see libp2p/go-libp2p#1222 for the corresponding
change on the Golang side.

Co-authored-by: Max Inden <mail@max-inden.de>
santos227 pushed a commit to santos227/rustlib that referenced this pull request Jun 20, 2022
With libp2p/specs#368 the definition of the _peer name_
changed in the mDNS specification.

> peer-name is the case-insensitive unique identifier of the peer, and is less
> than 64 characters.
>
> As the this field doesn't carry any meaning, it is sufficient to ensure the
> uniqueness of this identifier. Peers SHOULD generate a random, lower-case
> alphanumeric string of least 32 characters in length when booting up their
> node. Peers SHOULD NOT use their Peer ID here because a future Peer ID could
> exceed the DNS label limit of 63 characters.

https://github.com/libp2p/specs/blob/master/discovery/mdns.md

This commit adjusts `libp2p-mdns` accordingly.

Also see libp2p/go-libp2p#1222 for the corresponding
change on the Golang side.

Co-authored-by: Max Inden <mail@max-inden.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants