tor-cell: Implement IntroduceAck and IntroEstablished

These are fairly simple, since the bulk of them is just an extension
list with no supported extensions.
This commit is contained in:
Nick Mathewson 2023-02-27 13:46:34 -05:00
parent c302246e57
commit 7af2efdb82
2 changed files with 104 additions and 19 deletions

View File

@ -4,10 +4,12 @@
// TODO hs: we'll need accessors for the useful fields in all these types.
use self::ext::{decl_extension_group, ExtGroup, ExtList};
use super::msg::{self, Body};
use caret::caret_int;
use tor_bytes::{EncodeError, EncodeResult, Error as BytesError, Result};
use tor_bytes::{Reader, Writer};
use tor_bytes::{Readable, Reader, Writeable, Writer};
use tor_hscrypto::RendCookie;
use tor_llcrypto::pk::rsa::RsaIdentity;
@ -223,52 +225,116 @@ impl Body for Rendezvous2 {
}
}
caret_int! {
/// The recognized extension types for an `IntroEstablished` message.
#[derive(Ord, PartialOrd)]
pub struct IntroEstablishedExtType(u8) {
}
}
decl_extension_group! {
/// An extension to an IntroEstablished message.
///
/// (Currently, no extensions of this type are recognized)
#[derive(Debug,Clone)]
enum IntroEstablishedExt [ IntroEstablishedExtType ] {
}
}
/// Reply sent from the introduction point to the onion service, telling it that
/// an introduction point is now established.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct IntroEstablished {
/// The extensions included in this cell.
//
// TODO hs: we should extract this with any DOS related extensions, depending on what we
// decide to do with extension in general.
extensions: Vec<IntroEstExtension>,
extensions: ExtList<IntroEstablishedExt>,
}
impl IntroEstablished {
/// Create a new IntroEstablished message.
pub fn new() -> Self {
Self::default()
}
}
impl Body for IntroEstablished {
fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
todo!()
let extensions = r.extract()?;
Ok(Self { extensions })
}
fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
todo!()
w.write(&self.extensions)?;
Ok(())
}
}
/// An extension included in an [`IntroEstablished`] message.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum IntroEstExtension {
/// An unrecognized extension.
Unrecognized(Vec<u8>),
caret_int! {
/// A status code returned in response to an INTRODUCE1 message.
pub struct IntroduceAckStatus(u16) {
/// The message was relayed successfully.
SUCCESS = 0x0000,
/// The introduction point does not have a live circuit from the
/// identified service.
NOT_RECOGNIZED = 0x0001,
/// There was a failure while parsing the INTRODUCE1 message.
BAD_MESSAGE_FORMAT = 0x0002,
/// The introduction point was unable to deliver the message to the service.
CANT_RELAY = 0x0003,
}
}
caret_int! {
/// The recognized extension types for an `IntroEstablished` message.
#[derive(Ord, PartialOrd)]
pub struct IntroduceAckExtType(u8) {
}
}
decl_extension_group! {
/// An extension to an IntroduceAct message.
///
/// (Currently, no extensions of this type are recognized.)
#[derive(Debug,Clone)]
enum IntroduceAckExt [ IntroduceAckExtType ] {
}
}
/// A reply from the introduction point to the client, telling it that its
/// introduce1 was received.
#[derive(Clone, Debug)]
pub struct IntroduceAck {
// TODO hs: use a caret enum for this.
/// The status reported for the Introduce1 message.
status_code: u16,
// TODO hs: add extensions.
status_code: IntroduceAckStatus,
/// The extensions on this message.
extensions: ExtList<IntroduceAckExt>,
}
impl IntroduceAck {
/// Create a new IntroduceAck message with a provided status code.
pub fn new(status_code: IntroduceAckStatus) -> Self {
Self {
status_code,
extensions: Default::default(),
}
}
/// Return the status code from this message.
pub fn status(&self) -> IntroduceAckStatus {
self.status_code
}
}
impl Body for IntroduceAck {
fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
todo!()
let status_code = r.take_u16()?.into();
let extensions = r.extract()?;
Ok(IntroduceAck {
status_code,
extensions,
})
}
fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
todo!()
w.write_u16(self.status_code.into());
w.write(&self.extensions)?;
Ok(())
}
}

View File

@ -793,3 +793,22 @@ fn test_rendezvous() {
let rend2: Rendezvous2 = rend1.into();
msg(cmd2, "123456", &rend2.into());
}
#[test]
fn test_introduce_ack() {
use tor_cell::relaycell::hs::{IntroduceAck, IntroduceAckStatus};
let cmd = RelayCmd::INTRODUCE_ACK;
let status = IntroduceAckStatus::SUCCESS;
let introduce_ack = IntroduceAck::new(status);
msg(cmd, "0000 00", &introduce_ack.into())
}
#[test]
fn test_intro_established() {
use tor_cell::relaycell::hs::IntroEstablished;
let cmd = RelayCmd::INTRO_ESTABLISHED;
let intro_est = IntroEstablished::new();
msg(cmd, "00", &intro_est.into())
}