1
//! Implementation for the style of router descriptors used in
2
//! microdesc consensus documents.
3

            
4
use super::{FromRsString, GenericRouterStatus};
5
use crate::doc::microdesc::MdDigest;
6
use crate::doc::netstatus::{
7
    ConsensusFlavor, NetstatusKwd, ParseRouterStatus, RelayFlags, RelayWeight, RouterStatus,
8
};
9
use crate::types::misc::*;
10
use crate::{parse::parser::Section, util::private::Sealed};
11
use crate::{Error, Result};
12
use std::net;
13

            
14
use std::convert::TryInto;
15
use tor_error::internal;
16
use tor_llcrypto::pk::rsa::RsaIdentity;
17
use tor_protover::Protocols;
18

            
19
/// A single relay's status, as represented in a microdesc consensus.
20
28166
#[derive(Debug, Clone)]
21
pub struct MdConsensusRouterStatus {
22
    /// Underlying generic routerstatus object.
23
    ///
24
    /// This is private because we don't want to leak that these two
25
    /// types have the same implementation "under the hood".
26
    rs: GenericRouterStatus<MdDigest>,
27
}
28

            
29
impl From<GenericRouterStatus<MdDigest>> for MdConsensusRouterStatus {
30
38727
    fn from(rs: GenericRouterStatus<MdDigest>) -> Self {
31
38727
        MdConsensusRouterStatus { rs }
32
38727
    }
33
}
34

            
35
super::implement_accessors! {MdConsensusRouterStatus}
36

            
37
impl MdConsensusRouterStatus {
38
    /// Return the expected microdescriptor digest for this routerstatus
39
11029992
    pub fn md_digest(&self) -> &MdDigest {
40
11029992
        &self.rs.doc_digest
41
11029992
    }
42
}
43

            
44
impl Sealed for MdConsensusRouterStatus {}
45

            
46
impl RouterStatus for MdConsensusRouterStatus {
47
    type DocumentDigest = MdDigest;
48

            
49
    /// Return the expected microdescriptor digest for this routerstatus
50
6198592
    fn rsa_identity(&self) -> &RsaIdentity {
51
6198592
        &self.rs.identity
52
6198592
    }
53

            
54
    fn doc_digest(&self) -> &MdDigest {
55
        self.md_digest()
56
    }
57
}
58

            
59
impl ParseRouterStatus for MdConsensusRouterStatus {
60
2668
    fn flavor() -> ConsensusFlavor {
61
2668
        ConsensusFlavor::Microdesc
62
2668
    }
63

            
64
671
    fn from_section(sec: &Section<'_, NetstatusKwd>) -> Result<MdConsensusRouterStatus> {
65
671
        let rs = GenericRouterStatus::from_section(sec, true)?;
66
668
        Ok(MdConsensusRouterStatus { rs })
67
671
    }
68
}
69

            
70
impl FromRsString for MdDigest {
71
669
    fn decode(s: &str) -> Result<MdDigest> {
72
669
        s.parse::<B64>()?
73
668
            .check_len(32..=32)?
74
668
            .as_bytes()
75
668
            .try_into()
76
668
            .map_err(|_| Error::from(internal!("correct length on digest, but unable to convert")))
77
669
    }
78
}