Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
node: Add support for `.onion` addresses in wire
cloudhead committed 2 years ago
commit 7a1ba7d4b109c4bd45cac9c93755c6fa55823e3f
parent ae709b00edc91971136774e217dfc3957137dd50
3 files changed +37 -5
modified radicle-node/src/wire.rs
@@ -15,6 +15,7 @@ use std::string::FromUtf8Error;
use std::{io, mem};

use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
+
use cyphernet::addr::tor;

use crate::crypto::{PublicKey, Signature, Unverified};
use crate::git;
@@ -56,6 +57,8 @@ pub enum Error {
    InvalidControlMessage(u8),
    #[error("invalid protocol version header `{0:x?}`")]
    InvalidProtocolVersion([u8; 4]),
+
    #[error("invalid onion address: {0}")]
+
    InvalidOnionAddr(#[from] tor::OnionAddrDecodeError),
    #[error("unknown address type `{0}`")]
    UnknownAddressType(u8),
    #[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 {
    fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
        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)]
mod tests {
    use super::*;
modified radicle-node/src/wire/message.rs
@@ -1,7 +1,7 @@
use std::{io, mem, net};

use byteorder::{NetworkEndian, ReadBytesExt};
-
use cyphernet::addr::{Addr, HostName, NetAddr};
+
use cyphernet::addr::{tor, Addr, HostName, NetAddr};
use radicle::git::Oid;
use radicle::node::Address;

@@ -386,8 +386,12 @@ impl wire::Encode for Address {
                n += u8::from(AddressType::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)?;
@@ -418,7 +422,9 @@ impl wire::Decode for Address {
                HostName::Dns(dns)
            }
            Ok(AddressType::Onion) => {
-
                todo!();
+
                let onion: tor::OnionAddrV3 = wire::Decode::decode(reader)?;
+

+
                HostName::Tor(onion)
            }
            Err(other) => return Err(wire::Error::UnknownAddressType(other)),
        };
modified radicle/src/test/arbitrary.rs
@@ -6,6 +6,8 @@ use std::{iter, net};

use crypto::test::signer::MockSigner;
use crypto::{PublicKey, Unverified, Verified};
+
use cyphernet::addr::tor::OnionAddrV3;
+
use cyphernet::EcPk;
use nonempty::NonEmpty;
use qcheck::Arbitrary;

@@ -260,7 +262,7 @@ impl Arbitrary for RepoId {

impl Arbitrary for AddressType {
    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()
    }
@@ -285,7 +287,13 @@ impl Arbitrary for Address {
                .unwrap()
                .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 {