Skip to main content

deaddrop_core/
envelope.rs

1use crate::destination::Destination;
2use crate::ids::{ContentId, ManifestId, ObjectId, PeerId};
3use crate::limits::{MAX_EXTENSIONS, NONCE_LEN};
4use crate::priority::Priority;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum RoutingPolicyKind {
10    Direct,
11    Epidemic,
12    #[default]
13    SprayAndWait,
14    Encounter,
15    Utility,
16    Adaptive,
17}
18
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
20pub struct RoutingPolicy {
21    pub kind: RoutingPolicyKind,
22    pub replication_budget: u32,
23    #[serde(default)]
24    pub trusted_only: bool,
25}
26
27impl Default for RoutingPolicy {
28    fn default() -> Self {
29        Self {
30            kind: RoutingPolicyKind::Adaptive,
31            replication_budget: crate::limits::DEFAULT_REPLICATION_BUDGET,
32            trusted_only: false,
33        }
34    }
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38#[serde(tag = "kind", rename_all = "snake_case")]
39pub enum PayloadDescriptor {
40    Inline {
41        length: u64,
42        content_id: ContentId,
43    },
44    Blob {
45        length: u64,
46        content_id: ContentId,
47    },
48    Chunked {
49        length: u64,
50        manifest_id: ManifestId,
51        content_id: ContentId,
52    },
53    Manifest {
54        manifest_id: ManifestId,
55    },
56    /// EXPERIMENTAL: streaming manifests are not implemented in v0.2.
57    StreamManifest {
58        manifest_id: ManifestId,
59    },
60    Collection {
61        members: Vec<ObjectId>,
62    },
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
66pub struct RecipientWrap {
67    pub peer: PeerId,
68    #[serde(with = "serde_bytes")]
69    pub eph_pk: [u8; 32],
70    #[serde(with = "serde_bytes")]
71    pub nonce: [u8; NONCE_LEN],
72    #[serde(with = "serde_bytes")]
73    pub wrapped_key: Vec<u8>,
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
77pub struct SecurityDescriptor {
78    pub scheme: String,
79    pub public: bool,
80    pub wraps: Vec<RecipientWrap>,
81    #[serde(with = "serde_bytes")]
82    pub content_nonce: [u8; NONCE_LEN],
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86pub struct Extension {
87    pub name: String,
88    pub critical: bool,
89    #[serde(with = "serde_bytes")]
90    pub data: Vec<u8>,
91}
92
93#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
94pub struct DropEnvelope {
95    pub protocol_version: u16,
96    pub object_id: ObjectId,
97    pub source: PeerId,
98    pub destination: Destination,
99    pub creation_time: u64,
100    pub expiration: u64,
101    pub priority: Priority,
102    pub hop_limit: u8,
103    pub hop_count: u8,
104    pub payload_descriptor: PayloadDescriptor,
105    pub routing_policy: RoutingPolicy,
106    pub security_descriptor: SecurityDescriptor,
107    pub application: String,
108    pub topic: Option<String>,
109    pub extensions: Vec<Extension>,
110    #[serde(with = "serde_bytes")]
111    pub author_pk: [u8; 32],
112    #[serde(with = "serde_bytes")]
113    pub signature: [u8; 64],
114}
115
116impl DropEnvelope {
117    pub fn remaining_hops(&self) -> u8 {
118        self.hop_limit.saturating_sub(self.hop_count)
119    }
120
121    pub fn is_expired(&self, now: u64) -> bool {
122        now >= self.expiration
123    }
124
125    pub fn validate_extension_count(&self) -> crate::Result<()> {
126        if self.extensions.len() > MAX_EXTENSIONS {
127            return Err(crate::DdError::protocol(
128                crate::ErrorCode::Ddp1006LimitExceeded,
129                "too many extensions",
130            ));
131        }
132        Ok(())
133    }
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct PublicIdentity {
138    pub version: u8,
139    #[serde(with = "serde_bytes")]
140    pub ed25519_pk: [u8; 32],
141    #[serde(with = "serde_bytes")]
142    pub x25519_pk: [u8; 32],
143    #[serde(with = "serde_bytes")]
144    pub signature: [u8; 64],
145}