[mdns] - Support for long mDNS names (Bug #1232)#1287
Conversation
…tably `misc/mdns`, so that I could run these tests)
…al QNAME encoding bytes
…reater than 63 characters
|
I agree that should have this change, but I'm a bit confused by the specs. The fact that you have to modify the code of |
|
I don't think the Rust implementation would ever create an oversized DNS label because it only responds to queries with the locally generated SHA2256 I would like to retain the code in @tomaka, would you be more comfortable seeing those changes, given your concerns about the spec being a bit loose? |
The scope of the changes is good (IMO). I'll probably review early next week. |
| const MAX_INLINE_KEY_LENGTH: usize = 42; | ||
| // | ||
| // Note: see `from_public_key` for how this value will be used in the future. | ||
| // const MAX_INLINE_KEY_LENGTH: usize = 42; |
|
|
||
| /// If a peer ID is longer than 63 characters, split it into segments to | ||
| /// be compatible with RFC 1035. | ||
| fn segment_peer_id(peer_id: &String) -> String { |
There was a problem hiding this comment.
| fn segment_peer_id(peer_id: &String) -> String { | |
| fn segment_peer_id(peer_id: String) -> String { |
It might be premature optimization, but we could add some pass-through:
if peer_id.as_bytes().len() <= 63 { return peer_id }
| /// If a peer ID is longer than 63 characters, split it into segments to | ||
| /// be compatible with RFC 1035. | ||
| fn segment_peer_id(peer_id: &String) -> String { | ||
| // This will only perform one allocation except in extreme circumstances. |
There was a problem hiding this comment.
I think you can replace the function's body with something like this:
| // This will only perform one allocation except in extreme circumstances. | |
| String::from_utf8(peer_id.as_bytes().chunks(63).join(&b'.')).expect("we copy from a UTF8 string; qed") |
There was a problem hiding this comment.
The problem is that .chunks can't .join (in 1.38.0) ... I went through several iterations to see if I could make that work elegantly, and ended up with the for ... in loop for clarity and minimal number of allocations.
There was a problem hiding this comment.
I looked further into this as I was curious, I guess not because it really matters in this case. I am sorry if this is just useless noise to the discussion.
Under the assumption that the string only contains ASCII characters, why not do:
let b = peer_id
.as_bytes()
.chunks(MAX_LABEL_LENGTH)
.collect::<Vec<_>>()
.join(&b'.');
String::from_utf8(b).expect("we copy from a UTF8 string; qed")Using a for-loop and manually preallocating the right amount of memory seems like an early optimization to me. I have benchmarked this here. Using iterators with join allows one to not copy the characters one by one as in the for loop, but instead in chunks (See https://doc.rust-lang.org/src/alloc/slice.rs.html#664).
Running the above linked benchmarks in criterion shows that the above would be twice as fast (on my machine) as the for loop. In addition I find it easier to comprehend.
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
… that don't need to be segmented
| // This will only perform one allocation except in extreme circumstances. | ||
| let mut out = String::with_capacity(peer_id.len() + 8); | ||
|
|
||
| for (idx, chr) in peer_id.chars().enumerate() { |
There was a problem hiding this comment.
This line bothers me a bit. We know the string only contains ASCII characters, so I guess it's fine. I would have preferred using bytes.
* Dead code -- commenting out with a note referencing future implementation * Adding "std" feature so that cargo can build in other directories (notably `misc/mdns`, so that I could run these tests) * Permitting `PeerID` to be built from an `Identity` multihash * The length limit for DNS labels is 63 characters, as per RFC1035 * Allocates the vector with capacity for the service name plus additional QNAME encoding bytes * Added support for encoding/decoding peer IDs with an encoded length greater than 63 characters * Removing "std" from ring features Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> * Retaining MAX_INLINE_KEY_LENGTH with comment about future usage * `segment_peer_id` consumes `peer_id` ... plus an early return for IDs that don't need to be segmented * Fixing logic
* Implement Debug for (ed25519|secp256k1)::(Keypair|SecretKey) (#1285) * Fix possible arithmetic overflow in libp2p-kad. (#1291) When the number of active queries exceeds the (internal) JOBS_MAX_QUERIES limit, which is only supposed to bound the number of concurrent queries relating to background jobs, an arithmetic overflow occurs. This is fixed by using saturating subtraction. * protocols/plaintext: Add example on how to upgrade with PlainTextConfig1 (#1286) * [mdns] - Support for long mDNS names (Bug #1232) (#1287) * Dead code -- commenting out with a note referencing future implementation * Adding "std" feature so that cargo can build in other directories (notably `misc/mdns`, so that I could run these tests) * Permitting `PeerID` to be built from an `Identity` multihash * The length limit for DNS labels is 63 characters, as per RFC1035 * Allocates the vector with capacity for the service name plus additional QNAME encoding bytes * Added support for encoding/decoding peer IDs with an encoded length greater than 63 characters * Removing "std" from ring features Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> * Retaining MAX_INLINE_KEY_LENGTH with comment about future usage * `segment_peer_id` consumes `peer_id` ... plus an early return for IDs that don't need to be segmented * Fixing logic * Bump most dependencies (#1268) * Bump most dependencies This actually builds 😊. * Bump all dependencies Includes the excellent work of @rschulman in #1265. * Remove use of ed25519-dalek fork * Monomorphize more dependencies * Add compatibility hack for rand Cargo allows a crate to depend on multiple versions of another, but `cargo-web` panics in that situation. Use a wrapper crate to work around the panic. * Use @tomaka’s idea for using a newer `rand` instead of my own ugly hack. * Switch to Parity master as its dependency-bumping PR has been merged. * Update some depenendencies again * Remove unwraps and `#[allow(deprecated)]`. * Remove spurious changes to dependencies Bumping minor or patch versions is not needed, and increases likelyhood of merge conflicts. * Remove some redundant Cargo.toml changes * Replace a retry loop with an expect `ed25519::SecretKey::from_bytes` will never fail for 32-byte inputs. * Revert changes that don’t belong in this PR * Remove using void to bypass ICE (#1295) * Publish 0.13.0 (#1294)
Hey folks,
I believe this adds support for long mDNS names, as reported in issue #1232
There are a couple of additional changes that I made in order to test the scenario where long mDNS names are encountered, so I'd love to get feedback about unintended consequences:
I added thestdfeature forringin the top-levelCargo.toml. I wasn't able to build or test within the mdns directory without it (eg:cd misc/mdns; cargo testwould fail onringerror traits).PeerIdfrom theIdentitymultihash. It's in line with the spec, but I'm not familiar with the nuances. This was done so that I could generate long mDNS names for tests.Cheers!