node: Add support for `.onion` addresses in wire
Adds support for encoding and decoding onion addresses in the gossip protocol.
This commit is contained in:
parent
ae709b00ed
commit
7a1ba7d4b1
|
|
@ -15,6 +15,7 @@ use std::string::FromUtf8Error;
|
||||||
use std::{io, mem};
|
use std::{io, mem};
|
||||||
|
|
||||||
use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
use cyphernet::addr::tor;
|
||||||
|
|
||||||
use crate::crypto::{PublicKey, Signature, Unverified};
|
use crate::crypto::{PublicKey, Signature, Unverified};
|
||||||
use crate::git;
|
use crate::git;
|
||||||
|
|
@ -56,6 +57,8 @@ pub enum Error {
|
||||||
InvalidControlMessage(u8),
|
InvalidControlMessage(u8),
|
||||||
#[error("invalid protocol version header `{0:x?}`")]
|
#[error("invalid protocol version header `{0:x?}`")]
|
||||||
InvalidProtocolVersion([u8; 4]),
|
InvalidProtocolVersion([u8; 4]),
|
||||||
|
#[error("invalid onion address: {0}")]
|
||||||
|
InvalidOnionAddr(#[from] tor::OnionAddrDecodeError),
|
||||||
#[error("unknown address type `{0}`")]
|
#[error("unknown address type `{0}`")]
|
||||||
UnknownAddressType(u8),
|
UnknownAddressType(u8),
|
||||||
#[error("unknown message type `{0}`")]
|
#[error("unknown message type `{0}`")]
|
||||||
|
|
@ -237,6 +240,12 @@ impl Encode for Refs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encode for cyphernet::addr::tor::OnionAddrV3 {
|
||||||
|
fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
|
||||||
|
self.into_raw_bytes().encode(writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Encode for Alias {
|
impl Encode for Alias {
|
||||||
fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
|
fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
|
||||||
self.as_ref().encode(writer)
|
self.as_ref().encode(writer)
|
||||||
|
|
@ -509,6 +518,15 @@ impl Decode for node::Features {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Decode for tor::OnionAddrV3 {
|
||||||
|
fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
|
||||||
|
let bytes: [u8; tor::ONION_V3_RAW_LEN] = Decode::decode(reader)?;
|
||||||
|
let addr = tor::OnionAddrV3::from_raw_bytes(bytes)?;
|
||||||
|
|
||||||
|
Ok(addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{io, mem, net};
|
use std::{io, mem, net};
|
||||||
|
|
||||||
use byteorder::{NetworkEndian, ReadBytesExt};
|
use byteorder::{NetworkEndian, ReadBytesExt};
|
||||||
use cyphernet::addr::{Addr, HostName, NetAddr};
|
use cyphernet::addr::{tor, Addr, HostName, NetAddr};
|
||||||
use radicle::git::Oid;
|
use radicle::git::Oid;
|
||||||
use radicle::node::Address;
|
use radicle::node::Address;
|
||||||
|
|
||||||
|
|
@ -386,8 +386,12 @@ impl wire::Encode for Address {
|
||||||
n += u8::from(AddressType::Dns).encode(writer)?;
|
n += u8::from(AddressType::Dns).encode(writer)?;
|
||||||
n += dns.encode(writer)?;
|
n += dns.encode(writer)?;
|
||||||
}
|
}
|
||||||
|
HostName::Tor(addr) => {
|
||||||
|
n += u8::from(AddressType::Onion).encode(writer)?;
|
||||||
|
n += addr.encode(writer)?;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
todo!();
|
return Err(io::ErrorKind::Unsupported.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n += self.port().encode(writer)?;
|
n += self.port().encode(writer)?;
|
||||||
|
|
@ -418,7 +422,9 @@ impl wire::Decode for Address {
|
||||||
HostName::Dns(dns)
|
HostName::Dns(dns)
|
||||||
}
|
}
|
||||||
Ok(AddressType::Onion) => {
|
Ok(AddressType::Onion) => {
|
||||||
todo!();
|
let onion: tor::OnionAddrV3 = wire::Decode::decode(reader)?;
|
||||||
|
|
||||||
|
HostName::Tor(onion)
|
||||||
}
|
}
|
||||||
Err(other) => return Err(wire::Error::UnknownAddressType(other)),
|
Err(other) => return Err(wire::Error::UnknownAddressType(other)),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ use std::{iter, net};
|
||||||
|
|
||||||
use crypto::test::signer::MockSigner;
|
use crypto::test::signer::MockSigner;
|
||||||
use crypto::{PublicKey, Unverified, Verified};
|
use crypto::{PublicKey, Unverified, Verified};
|
||||||
|
use cyphernet::addr::tor::OnionAddrV3;
|
||||||
|
use cyphernet::EcPk;
|
||||||
use nonempty::NonEmpty;
|
use nonempty::NonEmpty;
|
||||||
use qcheck::Arbitrary;
|
use qcheck::Arbitrary;
|
||||||
|
|
||||||
|
|
@ -260,7 +262,7 @@ impl Arbitrary for RepoId {
|
||||||
|
|
||||||
impl Arbitrary for AddressType {
|
impl Arbitrary for AddressType {
|
||||||
fn arbitrary(g: &mut qcheck::Gen) -> Self {
|
fn arbitrary(g: &mut qcheck::Gen) -> Self {
|
||||||
let t = *g.choose(&[1, 2, 3]).unwrap() as u8;
|
let t = *g.choose(&[1, 2, 3, 4]).unwrap() as u8;
|
||||||
|
|
||||||
AddressType::try_from(t).unwrap()
|
AddressType::try_from(t).unwrap()
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +287,13 @@ impl Arbitrary for Address {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
AddressType::Onion => todo!(),
|
AddressType::Onion => {
|
||||||
|
let pk = PublicKey::arbitrary(g);
|
||||||
|
let addr = OnionAddrV3::from(
|
||||||
|
cyphernet::ed25519::PublicKey::from_pk_compressed(**pk).unwrap(),
|
||||||
|
);
|
||||||
|
cyphernet::addr::HostName::Tor(addr)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Address::from(cyphernet::addr::NetAddr {
|
Address::from(cyphernet::addr::NetAddr {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue