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

Update the experimental multiaddr WebRTC support #2722

Merged
merged 5 commits into from
Sep 8, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 35 additions & 25 deletions src/libp2p/multiaddr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ pub enum ProtocolRef<'a> {
DnsAddr(DomainNameRef<'a>),
Ip4([u8; 4]),
Ip6([u8; 16]),
P2p(Cow<'a, [u8]>), // TODO: a bit hacky
P2p(Cow<'a, [u8]>), // TODO: a bit hacky because there's no "owned" equivalent to MultihashRef
Quic,
Tcp(u16),
Tls,
Expand All @@ -207,11 +207,9 @@ pub enum ProtocolRef<'a> {
Wss,
// TODO: unclear what the payload is; see https://github.com/multiformats/multiaddr/issues/127
Memory(u64),
// TODO: these protocols are inventions for prototyping, see https://github.com/libp2p/specs/pull/412
ExperimentalWebRtc,
// TODO: these protocols are inventions for prototyping, see https://github.com/libp2p/specs/pull/412
/// Contains the SHA-256 hash of the TLS certificate.
ExperimentalCertHash([u8; 32]),
WebRtc,
tomaka marked this conversation as resolved.
Show resolved Hide resolved
/// Contains the multihash of the TLS certificate.
CertHash(Cow<'a, [u8]>), // TODO: a bit hacky because there's no "owned" equivalent to MultihashRef
tomaka marked this conversation as resolved.
Show resolved Hide resolved
}

impl<'a> ProtocolRef<'a> {
Expand Down Expand Up @@ -279,13 +277,16 @@ impl<'a> ProtocolRef<'a> {
.map_err(|_| ParseError::InvalidMemoryPayload)?,
))
}
"experimental-webrtc" => Ok(ProtocolRef::ExperimentalWebRtc),
"experimental-certhash" => {
let string_hash = iter.next().ok_or(ParseError::UnexpectedEof)?;
let parsed = hex::decode(string_hash).map_err(|_| ParseError::InvalidDomainName)?; // TODO: wrong error; proper errors should be added to ParseError when it's no longer experimental
let correct_len =
<[u8; 32]>::try_from(&parsed[..]).map_err(|_| ParseError::InvalidDomainName)?; // TODO: wrong error
Ok(ProtocolRef::ExperimentalCertHash(correct_len))
"webrtc" => Ok(ProtocolRef::WebRtc),
"certhash" => {
let s = iter.next().ok_or(ParseError::UnexpectedEof)?;
let decoded = bs58::decode(s)
tomaka marked this conversation as resolved.
Show resolved Hide resolved
.into_vec()
.map_err(|_| ParseError::NotBase58)?;
if let Err(err) = multihash::MultihashRef::from_bytes(&decoded) {
return Err(ParseError::InvalidMultihash(err));
}
Ok(ProtocolRef::CertHash(Cow::Owned(decoded)))
}
_ => Err(ParseError::UnrecognizedProtocol),
}
Expand All @@ -309,8 +310,8 @@ impl<'a> ProtocolRef<'a> {
ProtocolRef::Ws => 477,
ProtocolRef::Wss => 478,
ProtocolRef::Memory(_) => 777,
ProtocolRef::ExperimentalWebRtc => 991234, // TODO: these numbers are complete invention
ProtocolRef::ExperimentalCertHash(_) => 991235, // TODO: these numbers are complete invention
ProtocolRef::WebRtc => 280,
ProtocolRef::CertHash(_) => 466,
};

// TODO: optimize by not allocating a Vec
Expand All @@ -335,7 +336,13 @@ impl<'a> ProtocolRef<'a> {
}
ProtocolRef::Tcp(port) | ProtocolRef::Udp(port) => port.to_be_bytes().to_vec(),
ProtocolRef::Memory(payload) => payload.to_be_bytes().to_vec(),
ProtocolRef::ExperimentalCertHash(hash) => hash.to_vec(),
ProtocolRef::CertHash(multihash) => {
// TODO: what if not a valid multihash? the enum variant can be constructed by the user
let mut out = Vec::with_capacity(multihash.len() + 4);
out.extend(crate::util::leb128::encode_usize(multihash.len()));
out.extend_from_slice(multihash);
out
}
_ => Vec::new(),
};

Expand Down Expand Up @@ -368,9 +375,10 @@ impl<'a> fmt::Display for ProtocolRef<'a> {
ProtocolRef::Ws => write!(f, "/ws"),
ProtocolRef::Wss => write!(f, "/wss"),
ProtocolRef::Memory(payload) => write!(f, "/memory/{}", payload),
ProtocolRef::ExperimentalWebRtc => write!(f, "/experimental-webrtc"),
ProtocolRef::ExperimentalCertHash(hash) => {
write!(f, "/experimental-certhash/{}", hex::encode(hash))
ProtocolRef::WebRtc => write!(f, "/webrtc"),
ProtocolRef::CertHash(multihash) => {
// Base58 encoding doesn't have `/` in its characters set.
write!(f, "/certhash/{}", bs58::encode(multihash).into_string())
tomaka marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down Expand Up @@ -507,12 +515,14 @@ fn protocol<'a, E: nom::error::ParseError<&'a [u8]>>(
478 => Ok((bytes, ProtocolRef::Wss)),
// TODO: unclear what the /memory payload is, see https://github.com/multiformats/multiaddr/issues/127
777 => nom::combinator::map(nom::number::complete::be_u64, ProtocolRef::Memory)(bytes),
991234 => Ok((bytes, ProtocolRef::ExperimentalWebRtc)), // TODO: these numbers are complete invention
991235 => {
nom::combinator::map(nom::bytes::complete::take(32_u32), |hash: &'a [u8]| {
ProtocolRef::ExperimentalCertHash(<[u8; 32]>::try_from(hash).unwrap())
})(bytes)
} // TODO: these numbers are complete invention
280 => Ok((bytes, ProtocolRef::WebRtc)),
466 => nom::combinator::map(
nom::combinator::verify(
nom::multi::length_data(crate::util::leb128::nom_leb128_usize),
|s| multihash::MultihashRef::from_bytes(s).is_ok(),
),
|b| ProtocolRef::CertHash(Cow::Borrowed(b)),
)(bytes),
_ => Err(nom::Err::Error(nom::error::make_error(
bytes,
nom::error::ErrorKind::Tag,
Expand Down