//! //! A "router descriptor" is a signed statement that a relay makes //! about itself, explaining its keys, its capabilities, its location, //! and its status. //! //! Relays upload their router descriptors to authorities, which use //! them to build consensus documents. Old clients and relays used to //! fetch and use router descriptors for all the relays, but nowadays they use //! microdescriptors instead. //! //! Clients still use router descriptors when communicating with //! bridges: since bridges are not passed through an authority, //! clients accept their descriptors directly. //! //! For full information about the router descriptor format, see //! [dir-spec.txt](https://spec.torproject.org/dir-spec). //! //! # Limitations //! //! TODO: This needs to get tested much more! //! //! TODO: This implementation can be memory-inefficient. In practice, //! it gets really expensive storing policy entries, family //! descriptions, parsed keys, and things like that. We will probably want to //! de-duplicate those. //! //! TODO: There should be accessor functions for some or all of the //! fields in RouterDesc. I'm deferring those until I know what they //! should be. //! //! # Availability //! //! Most of this module is only available when this crate is built with the //! `routerdesc` feature enabled. use crate::encode::{ItemEncoder, ItemValueEncodable}; use crate::parse::keyword::Keyword; use crate::parse::parser::{Section, SectionRules}; use crate::parse::tokenize::{ItemResult, NetDocReader}; use crate::parse2::{ArgumentError, ErrorProblem, ItemValueParseable, UnparsedItem}; use crate::types::family::{RelayFamily, RelayFamilyIds}; use crate::types::policy::*; use crate::types::routerdesc::*; use crate::types::version::TorVersion; use crate::types::{EmbeddedCert, misc::*}; use crate::util::PeekableIterator; use crate::{AllowAnnotations, Error, KeywordEncodable, NetdocErrorKind as EK, Result}; use derive_deftly::Deftly; use ll::pk::ed25519::Ed25519Identity; use saturating_time::SaturatingTime; use std::fmt::Display; use std::sync::LazyLock; use std::{iter, net, time}; use tor_basic_utils::intern::Intern; use tor_cert::{CertType, KeyUnknownCert}; use tor_checkable::{Timebound, signed, timed}; use tor_error::{internal, into_internal}; use tor_llcrypto as ll; use tor_llcrypto::pk::rsa::RsaIdentity; use digest::Digest; /// Length of a router descriptor digest pub const DOC_DIGEST_LEN: usize = 20; /// The digest of a RouterDesc document, as reported in a NS consensus. pub type RdDigest = [u8; DOC_DIGEST_LEN]; /// The digest of an ExtraInfo document, as reported in a RouterDesc. pub type ExtraInfoDigest = [u8; DOC_DIGEST_LEN]; /// A router descriptor, with possible annotations. #[non_exhaustive] pub struct AnnotatedRouterDesc { /// Annotation for this router descriptor; possibly empty. pub ann: RouterAnnotation, /// Underlying router descriptor; signatures not checked yet. pub router: UncheckedRouterDesc, } /// Annotations about a router descriptor, as stored on disc. #[derive(Default)] #[non_exhaustive] pub struct RouterAnnotation { /// Description of where we got this router descriptor pub source: Option, /// When this descriptor was first downloaded. pub downloaded: Option, /// Description of what we're willing to use this descriptor for. pub purpose: Option, } /// Information about a relay, parsed from a router descriptor. /// /// This type does not hold all the information in the router descriptor /// /// # Limitations /// /// See module documentation. /// /// Additionally, some fields that from router descriptors are not yet /// parsed: see the comments in ROUTER_BODY_RULES for information about those. /// /// Before using this type to connect to a relay, you MUST check that /// it is valid, using is_expired_at(). /// /// # Specification /// /// #[derive(Clone, Debug, Deftly, PartialEq, Eq)] #[derive_deftly(NetdocParseableUnverified)] #[non_exhaustive] pub struct RouterDesc { /// `router` --- Introduce a router descriptor. /// * `router
` /// * At start, exactly once. pub router: RouterDescIntroItem, /// `identity-ed25519` --- Specify the router's ed25519 identity. /// /// pub identity_ed25519: EmbeddedCert, /// `master-key-ed25519` --- Redundantly specify the router's ed25519 identity. /// /// * `master-key-ed25519 ` /// * Exactly once. // TODO DIRAUTH when implementing verification, don't forget to check this! #[deftly(netdoc(single_arg))] pub master_key_ed25519: Ed25519Public, /// `bandwidth` --- Report router's network bandwidth. /// /// * `bandwidth ` /// * Exactly once. pub bandwidth: Bandwidth, /// `platform` --- Describe the platform on which this relay is running. /// /// * `platform ` /// * At most once. pub platform: Option, /// `published` --- Time this descriptor (and extra-info) was generated. /// /// * `published