Part 06 — DTN / Store-Carry-Forward Architecture
Reusable P2P Communication Platform
Status: Architecture specification
Part: 06 of 24
Primary language: Rust
Primary goals: communication without continuous end-to-end connectivity, store-carry-forward, opportunistic routing, transport independence, emergency resilience, bounded replication, privacy, crash safety, reusable across messaging/files/ERP/custom applications
1. Purpose
A normal network assumes that a route exists between sender and receiver at the time of communication.
A disaster-resilient P2P system cannot make that assumption.
A sender may have:
no Internet
no router
no direct Wi-Fi path
no direct Bluetooth path to destination
yet there may still be a sequence of future encounters:
Alice
↓
Bob
↓
Carol
↓
Gateway
↓
Destination
The DTN subsystem provides this behavior.
DTN means:
Persist the payload locally, carry it across time, and forward it when useful connectivity appears.
This architecture must work with:
- text messages
- message receipts
- emergency reports
- SOS
- small file metadata
- selected file chunks
- authority alerts
- custom application events
It must not require a central server.
2. Fundamental Principle
Do not design DTN as:
Bluetooth forwarding logic
or:
Emergency-only forwarding
Instead:
Application Payload
↓
DTN Bundle
↓
Durable Relay Store
↓
Encounter Protocol
↓
Forwarding Policy
↓
Any Available Transport
Transport can be:
BLE
Bluetooth Classic
Wi-Fi Direct
Wi-Fi Aware
LAN
Iroh
future radio
DTN is a routing/delivery model, not a radio technology.
3. Architectural Position
Messaging / Files / Emergency / Custom App
↓
Delivery Intent
↓
Transport/Routing Engine
↓
DTN Adapter / DTN Engine
↓
Durable Bundle Store
↓
Encounter / Reconciliation
↓
BLE / Wi-Fi / LAN / Iroh / Relay
Part 03 decides whether DTN is allowed.
Part 06 decides how DTN forwarding happens.
4. DTN Responsibilities
The DTN subsystem owns:
- bundle creation
- durable bundle persistence
- expiry
- hop/replication limits
- peer encounter exchange
- inventory summaries
- bundle deduplication
- opportunistic forwarding
- relay storage quotas
- next-hop scoring
- custody-like state
- gateway handoff
- delivery confirmation propagation
- eviction
- route history
- privacy-aware routing metadata
- priority scheduling
- multi-transport handoff
It does not own:
- chat semantics
- message rendering
- file decoding
- account UI
- codec logic
- raw Bluetooth APIs
5. Bundle Concept
A DTN bundle is an opaque transferable object.
#![allow(unused)] fn main() { pub struct BundleId([u8; 32]); }
A bundle represents:
payload + routing metadata + security metadata + delivery policy
The relay does not need to understand the application payload.
6. Bundle Structure
Conceptually:
#![allow(unused)] fn main() { pub struct DtnBundle { pub bundle_id: BundleId, pub source: DtnSource, pub destination: DtnDestination, pub payload_type: PayloadTypeId, pub created_at: Timestamp, pub expires_at: Timestamp, pub priority: DtnPriority, pub hop_limit: u8, pub replication_budget: u8, pub forwarding_class: ForwardingClass, pub payload_ref: PayloadReference, pub integrity: BundleIntegrity, } }
Large content should usually be referenced by blob/chunk identity rather than embedded directly.
7. Bundle Payload
Supported forms:
#![allow(unused)] fn main() { pub enum PayloadReference { Inline(Bytes), Blob(BlobId), Chunk { blob: BlobId, chunk_index: u32, }, Event(EventId), } }
Inline payloads must be strictly bounded.
8. Bundle Security Principle
Private payloads should already be end-to-end encrypted before entering DTN.
Flow:
plaintext
↓
application E2EE
↓
ciphertext payload
↓
DTN bundle
↓
unknown relay peers
Relay nodes should not need conversation/file decryption keys.
9. Relay Trust Model
A relay may be:
unknown
known contact
trusted device
organization node
emergency gateway
But forwarding private ciphertext should not require trusting the relay with plaintext.
Separate:
trusted to carry
from:
trusted to read
10. Bundle Destination
Use opaque destination identifiers.
Avoid plaintext:
phone number
email
display name
in relay-visible headers.
Possible destination forms:
#![allow(unused)] fn main() { pub enum DtnDestination { DeviceOpaque(RouteToken), AccountOpaque(RouteToken), GroupOpaque(RouteToken), LocalBroadcast(BroadcastScope), } }
11. Routing Tokens
A routing token should be:
- opaque
- short-lived where possible
- difficult to correlate long-term
- sufficient for authorized forwarding
Permanent account IDs should not be advertised unnecessarily in public BLE beacons or relay headers.
12. Bundle ID
BundleId must be stable across retries and replicas.
This enables:
deduplication
delivery tracking
idempotency
Do not create a new BundleId for every hop.
13. Bundle Immutability
Once created, routing-critical bundle fields should be immutable except hop-local metadata.
Example immutable:
bundle_id
destination
expiry
payload identity
origin signature
Hop-local mutable state:
remaining replication copies
local forwarding history
last-seen timestamp
Keep these separate.
14. Bundle Envelope vs Local Record
Separate:
WireBundle
from:
LocalBundleRecord
Local record may contain:
storage path
local retry count
peer history
custody state
These do not belong on wire.
15. Durable Store
Every accepted DTN bundle must be persisted before claiming it is being carried.
Create bundle
↓
write durable record
↓ COMMIT
eligible for forwarding
Part 04 event log can record semantic lifecycle transitions.
16. Bundle Store Interface
#![allow(unused)] fn main() { pub trait BundleStore: Send + Sync { async fn put(&self, bundle: StoredBundle) -> Result<(), DtnStoreError>; async fn get(&self, id: BundleId) -> Result<Option<StoredBundle>, DtnStoreError>; async fn mark_forwarded(&self, ...); async fn mark_delivered(&self, ...); async fn remove(&self, id: BundleId) -> Result<(), DtnStoreError>; async fn list_candidates(&self, query: ForwardQuery) -> Result<Vec<StoredBundle>, DtnStoreError>; } }
17. Storage Classes
Bundles can be:
LocalOrigin
Relay
CriticalEmergency
DeliveryReceipt
Each can have different retention and eviction policies.
18. Bundle State Machine
Created
↓
Stored
↓
Eligible
↓
Forwarded
↓
ForwardedAgain
↓
DestinationReached
↓
Acknowledged
↓
Completed
Alternative terminal states:
Expired
Evicted
Cancelled
Rejected
19. Delivery Semantics
Do not equate:
forwarded
with:
delivered
The UI and API must distinguish:
Stored locally
Carried by relay
Reached gateway
Reached destination device
Acknowledged by destination
20. Expiry
Every DTN bundle should have explicit expiry.
Examples:
typing indicator → not DTN
SOS → 24–72h
normal message → application-defined
temporary route hint → minutes
Expired bundles are never forwarded.
21. Hop Limit
Each bundle may have:
hop_limit
Every forward decrements local remaining hop budget.
At zero:
do not forward further
This prevents uncontrolled propagation.
22. Replication Budget
Hop count alone is insufficient.
Use:
replication_budget
Example:
normal message = 2
important message = 4
SOS = 8
This bounds duplicate copies.
23. Spray-and-Wait Baseline
A good initial opportunistic strategy is:
Spray:
create a limited number of copies
Wait:
copies seek destination/gateway
This is more controlled than epidemic flooding.
24. Epidemic Routing
Full epidemic routing:
send everything to everyone
is unsuitable as the default because it causes:
- battery drain
- bandwidth waste
- storage explosion
- metadata leakage
Use only for tightly bounded critical emergency classes, if at all.
25. Direct Delivery
If encountered peer is the destination:
deliver immediately
This always outranks relay forwarding.
26. Gateway Delivery
If peer has reliable Internet or destination reachability:
forward to gateway
Gateway can bridge:
BLE → Iroh
Wi-Fi → Internet
LAN → remote peer
without decrypting private content.
27. Encounter Protocol
When two DTN-capable peers meet:
HELLO
↓
authenticated capability exchange
↓
inventory summary
↓
request useful bundles
↓
transfer
↓
acknowledge stored copies
Do not immediately dump all bundles.
28. Encounter Identity
Nearby discovery can use ephemeral IDs.
Before forwarding sensitive bundles:
authenticate peer/session
when policy requires.
Unknown relays may still be eligible for opaque emergency/relay traffic according to application policy.
29. Inventory Summary
Do not exchange full BundleId lists if store is large.
Initial options:
Bloom filter
range summary
bounded recent-ID list
Later:
IBLT
Merkle-set reconciliation
30. Bloom Filter Use
A Bloom filter can summarize:
bundles I already have
False positives are acceptable if they only cause missed redundant transfer opportunities.
Do not use Bloom filters for authorization/security decisions.
31. Reconciliation Flow
Peer A summary
↓
Peer B identifies potentially useful missing bundles
↓
B requests IDs or classes
↓
A sends selected bundles
Selection depends on:
priority
expiry
destination likelihood
replication budget
storage
battery
transport bandwidth
32. Peer Utility Score
A peer can receive a forwarding score.
Conceptually:
score =
destination likelihood
+ gateway probability
+ recent encounter usefulness
+ available storage
+ connectivity quality
+ energy capacity
- congestion
Use deterministic heuristics initially.
33. Destination Likelihood
Useful hints:
peer recently saw destination
peer is destination's own device
peer is known gateway
peer belongs to same local group
Do not require a global social graph.
34. Encounter History
Maintain bounded history:
peer
last_seen
frequency
successful forwards
gateway_seen
This can improve forwarding.
Do not retain unlimited mobility history.
35. Privacy of Encounter History
Encounter logs can reveal movement patterns.
Keep:
- local
- bounded
- coarse
- retention-limited
Do not upload them by default.
36. DTN Priority
Recommended:
#![allow(unused)] fn main() { pub enum DtnPriority { Critical, High, Normal, Low, Bulk, } }
Examples:
SOS → Critical
delivery receipt → High
text → Normal
thumbnail → Low/Normal
large file chunk → Bulk
37. Scheduler
Per encounter:
Critical
↓
Control/ACK
↓
Text
↓
Small emergency media
↓
Voice
↓
Thumbnail
↓
Bulk chunks
Use weighted fairness to avoid total starvation.
38. Transport-Aware Scheduling
BLE:
small bundles only
Wi-Fi Direct:
larger bundles/chunks
Iroh:
full functionality
DTN scheduler must understand transport capacity.
39. Bundle Size Classes
Example:
Tiny < 4 KiB
Small < 64 KiB
Medium < 1 MiB
Large >= 1 MiB
These are tunable.
Routing policy can forbid large bundles on BLE.
40. File Integration
Part 05 blob subsystem should provide:
BlobId
ChunkId
Thumbnail BlobId
DTN may carry:
manifest
thumbnail
selected chunks
rather than full multi-gigabyte file by default.
41. Chunk Carriage
A DTN bundle can wrap:
Blob X
Chunk 17
The receiving node stores opaque chunk ciphertext.
Later it can forward or deliver it.
42. Chunk Deduplication
Chunk identity enables:
same chunk seen twice
→ store once
This reduces relay storage.
43. Manifest First
For large files:
manifest
↓
recipient/relay decides useful chunks
Do not blindly send random chunks without object context.
44. Thumbnail-First Emergency Media
Emergency photo flow:
SOS
↓
8–20 KB thumbnail
↓
preview
↓
full photo later on fast path
This greatly improves utility over constrained mesh.
45. Voice Notes
Low-bitrate Opus voice can be DTN-carried in chunks.
Priority typically above full-resolution images but below text/location.
46. Realtime Media
DTN does not carry realtime call frames.
Calls require:
continuous path
If unavailable:
voice note
text
SOS
becomes fallback.
47. Message Integration
Messaging creates:
MessageQueued
If no direct route:
routing engine chooses DTN
↓
DTN bundle created
The original MessageId remains stable.
48. Message Deduplication
Destination may receive same message via:
Internet
+
DTN relay
Recipient deduplicates by MessageId.
Bundle deduplication and message deduplication are distinct.
49. Delivery ACK
Destination emits a delivery acknowledgement.
ACK itself can be:
direct
or DTN-carried
This lets origin eventually know destination reached.
50. ACK Compression
Acknowledgements can aggregate:
multiple delivered BundleIds
into compact summaries.
Useful in low-bandwidth encounters.
51. Custody-Like Transfer
A relay may say:
I have durably stored this bundle
Origin can then reduce its replication pressure.
Do not call this strict DTN custody transfer unless implementing full custody semantics.
Use a simpler term such as:
DurableRelayAck
initially.
52. Durable Relay Ack
Means:
relay persisted bundle
not:
destination received
These must never be confused.
53. Copy Retirement
Origin may retire redundant copies after:
destination ACK
or according to policy after sufficient durable relay acknowledgements.
Critical data may retain extra copies longer.
54. Eviction
Relay storage eviction order:
expired
↓
delivered
↓
cancelled
↓
bulk low-priority
↓
old normal
↓
high
↓
critical last
Never use FIFO blindly.
55. Storage Quotas
Per node:
max DTN bytes
max bundles
max per-peer bytes
max critical reserve
Unknown peers should have stricter quotas.
56. Critical Reserve
Reserve storage for:
SOS
authority alerts
delivery ACKs
so bulk content cannot consume all relay capacity.
57. Per-Peer Quota
Prevent one malicious peer from filling store.
unknown peer = low quota
verified contact = moderate quota
trusted authority = policy-defined
Authorization and quota are separate.
58. Admission Control
Before accepting a relay bundle:
validate size
verify envelope
check expiry
check replication budget
check quota
check forwarding policy
check duplicate
Only then persist.
59. Bundle Validation
Validate:
version
header size
payload size
expiry
hop limit
signature/integrity
destination format
Remote input is hostile.
60. Oversized Bundle
Reject before allocation/storage reservation.
Never trust remote size fields.
61. Malformed Metadata
Malformed bundle should not affect other stored bundles.
Parsing must be isolated and bounded.
62. Bundle Encryption
Relay-visible header should reveal only what is needed.
Private payload remains E2EE ciphertext.
Potentially sensitive metadata such as original sender identity may also be minimized/obfuscated depending on routing design.
63. Source Privacy
Permanent source identity may not need to be visible to relay.
Use:
opaque origin reference
if protocol can still authenticate end-to-end.
64. Destination Privacy
Avoid stable public destination tags.
Use rotating capability/routing tokens where feasible.
Part 14 proximity/discovery architecture can help here.
65. Linkability Trade-Off
Perfect unlinkability can conflict with efficient routing.
Architecture should document trade-offs explicitly.
Do not claim anonymity simply because payloads are encrypted.
66. Replay Protection
Same BundleId received repeatedly:
do not duplicate storage
But metadata differences for same ID indicate:
protocol violation/tampering
67. Bundle Integrity
Bundle should authenticate:
bundle_id
destination
expiry
payload reference
priority
origin binding
so relays cannot alter routing-critical fields unnoticed.
68. Hop-Local Metadata
Fields changed per hop must not be covered as immutable origin-authenticated data unless represented separately.
Example:
remaining copy budget
local receipt state
69. Cancel Bundle
Origin may issue:
BundleCancel
for still-undelivered bundles.
Cancellation propagation is best effort.
Cannot erase already-delivered plaintext.
70. Expired Bundle Handling
Expired bundles:
do not forward
delete according to retention policy
Optional compact expiry summary can help peers discard stale references.
71. Time Without Internet
Device clocks may be wrong.
Use:
creation timestamp
+
monotonic local age
+
bounded tolerance
where possible.
For security-critical expiry, avoid relying solely on untrusted remote wall clock.
72. Relative Lifetime
Bundle can include:
lifetime duration
in addition to creation time.
Local node computes age relative to first trusted observation where appropriate.
73. Gateway Detection
A peer may advertise:
Internet gateway available
as capability.
Routing must verify the path works before trusting strongly.
74. Gateway Capability
#![allow(unused)] fn main() { pub struct GatewayCapability { pub internet: bool, pub relay_access: bool, pub estimated_capacity: CapacityClass, } }
This is a hint, not identity.
75. Gateway Forwarding
Gateway flow:
receive encrypted bundle
↓
persist
↓
obtain Internet
↓
resolve destination
↓
Iroh/relay/direct delivery
↓
receive destination ACK
↓
propagate ACK back via DTN if necessary
76. Cross-Transport Bridge
Example:
Phone A
↓ BLE
Phone B
↓ Wi-Fi Direct
Laptop C
↓ LAN
Gateway D
↓ Iroh
Destination
Same bundle survives all hops.
77. Transport Upgrade
During encounter:
discover over BLE
↓
both support Wi-Fi Direct
↓
upgrade bulk transfer to Wi-Fi
DTN session retains bundle semantics.
78. Transport Downgrade
If Wi-Fi fails:
continue small critical bundles over BLE
bulk pauses
No data model reset.
79. Encounter Session
Define:
#![allow(unused)] fn main() { pub struct EncounterSession { pub peer: PeerSession, pub transport: TransportKind, pub capacity: EncounterCapacity, pub expires_at: Option<Timestamp>, } }
80. Encounter Capacity
#![allow(unused)] fn main() { pub struct EncounterCapacity { pub max_bytes: u64, pub estimated_duration: Option<Duration>, pub bandwidth_class: BandwidthClass, } }
Useful for deciding what to exchange first.
81. Encounter Deadline
A BLE/Wi-Fi peer may disappear quickly.
Scheduler should prioritize:
small critical objects first
rather than starting one giant file.
82. Contact Duration Prediction
Optional heuristic:
recent encounter history
signal trend
transport type
can estimate contact duration.
Do not overcomplicate v1.
83. Store-and-Forward Policy
#![allow(unused)] fn main() { pub struct ForwardingPolicy { pub allow_unknown_relays: bool, pub max_hops: u8, pub replication_budget: u8, pub max_bundle_size: u64, pub expiry: Duration, } }
Applications can override safely.
84. Forwarding Classes
#![allow(unused)] fn main() { pub enum ForwardingClass { DirectOnly, TrustedRelays, AnyRelay, EmergencyBroadcast, } }
This cleanly separates privacy/security expectations.
85. DirectOnly
Bundle may be stored locally until destination encountered, but not handed to third-party relay.
Useful for highly sensitive payloads.
86. TrustedRelays
Forward only to:
verified contacts
own devices
organization nodes
87. AnyRelay
Encrypted payload can use unknown relay nodes.
Still subject to:
quota
rate limit
replication budget
88. EmergencyBroadcast
Special controlled dissemination mode.
May use broader forwarding but must remain:
bounded
signed
expiring
rate-limited
89. Local Broadcast
Public emergency alert can target:
local area / encounter domain
without individual destination.
This is different from private unicast.
90. Broadcast Scope
#![allow(unused)] fn main() { pub enum BroadcastScope { Nearby, LocalRegion, Organization, EmergencyDomain, } }
Geographic scoping may remain approximate/offline.
91. Authority Alerts
Authority alert requires:
origin signature
trusted issuer
expiry
scope
Relays can forward without trusting alert text personally; clients verify authority chain.
92. Spam Resistance
Open DTN can be abused.
Use:
rate limits
bundle size caps
per-origin quotas
proof-of-trust
issuer policy
critical-class restrictions
Do not let any unknown peer mark arbitrary traffic Critical.
93. Priority Authorization
Priority should be constrained by authority.
Example:
unknown peer
cannot claim AuthorityCritical
Map requested priority through local policy.
94. Priority Downgrade
If sender requests disallowed priority:
downgrade
or reject
Do not trust remote enum blindly.
95. Congestion
Relay store/transport congestion signals:
queue depth
storage pressure
encounter bandwidth
battery
Forwarding scheduler adapts.
96. Backpressure
If DTN store is full:
reject/defer low priority
Do not buffer incoming bundle indefinitely in memory.
97. Battery Awareness
Part 13 will expand this.
DTN already needs modes:
Normal
BatterySaver
EmergencyBalanced
EmergencyMaximumReach
These control:
scan frequency
forwarding volume
relay acceptance
Wi-Fi upgrade attempts
98. Low Battery Behavior
Example:
<10%
accept only:
critical
own messages
delivery ACK
small high-value bundles
Do not kill emergency functionality entirely unless unavoidable.
99. Charging Node
A charging device may become a better relay candidate.
Advertise coarse:
HighRelayCapacity
rather than exact battery percentage.
100. Thermal Awareness
If device is overheating:
reduce bulk relay
avoid Wi-Fi high-throughput upgrade
keep critical control traffic
101. Discovery Duty Cycle
DTN depends on peer encounters.
Scanning strategy must be battery-aware:
normal low duty cycle
nearby screen active higher
emergency high
battery saver low
Part 14 will define the proximity abstraction.
102. Peer Advertisement
Nearby advertisement should be tiny.
Possible:
protocol version
rotating node token
DTN capability bit
gateway hint
Do not include full bundle inventory in advertisements.
103. Session Authentication
After discovery:
establish secure session
then exchange:
inventory
bundle metadata
This limits metadata exposure.
104. Unknown Peer Mode
If product allows anonymous relays:
minimal authenticated ephemeral session
may still be used to prevent trivial spoofing/replay.
Application-level identity trust remains separate.
105. Relay Receipt
After persistence:
RelayStored(bundle_id)
can be sent.
Origin records:
one durable copy exists
Do not call it delivery.
106. Delivery Receipt Propagation
Destination creates:
DestinationAck(bundle_id)
This may travel back through any path.
Once origin receives it:
mark complete
stop forwarding
107. Ack Aggregation
For many bundles:
AckSummary
can contain ranges/Bloom-like compact structure.
Must not create false positive delivery semantics.
Use exact IDs/ranges where correctness matters.
108. Negative Acknowledgement
Peer can report:
RejectedQuota
Expired
Unsupported
Unauthorized
Useful to stop useless retries.
109. Route Learning
Successful delivery through peer can improve:
future utility score
Maintain only bounded local history.
110. No Global Routing Table
Mobile DTN topology changes too quickly.
Do not implement Internet-like full route tables.
Prefer:
neighbor knowledge
recent encounter utility
limited replication
gateway hints
111. Social-Aware Routing
Potential future optimization:
frequently encountered communities
but carries privacy risks.
Not recommended for initial release.
112. Prophet-Like Routing
Future predictive routing algorithms may use encounter probability.
Keep algorithm behind trait:
#![allow(unused)] fn main() { pub trait ForwardingStrategy { fn select( &self, bundle: &StoredBundle, peer: &PeerContext, ) -> ForwardDecision; } }
Start with simple deterministic policy.
113. ForwardDecision
#![allow(unused)] fn main() { pub enum ForwardDecision { Skip, Forward, ForwardCopy { copies: u8 }, DeliverDirect, } }
114. Strategy Plugability
Possible strategies:
DirectOnly
SprayAndWait
GatewayPreferred
EmergencyFloodLimited
Compile-time strategy selection initially.
115. Bundle Replication Counter
Keep local mutable:
copies_remaining
Do not let relay inflate it.
Origin-signed max budget constrains it.
116. Binary Spray-and-Wait
A practical scheme:
if copies = N
forward floor(N/2)
keep ceil(N/2)
until each copy has one remaining.
This spreads efficiently while bounded.
117. Delivery Probability
Peer can advertise or locally estimate:
gateway_probability
destination_probability
Use coarse scores.
Never trust peer self-reported score blindly.
118. Multi-Recipient Bundles
Prefer separate recipient-authorized payload references rather than exposing a recipient list to relays if privacy matters.
Group dissemination can use group-specific protocol.
119. Bundle Aggregation
Small related control bundles may be packed into one transfer batch.
But maintain individual BundleIds for deduplication/delivery tracking.
120. Batch Transfer
Encounter transfer can send:
BatchHeader
bundle count
bundle metadata
streamed payloads
This reduces handshake overhead.
121. Postcard Usage
Use Postcard for:
bundle headers
inventory requests
ack summaries
Stream large payload bytes separately.
122. Versioning
DTN extension:
dtn/1
Capabilities:
spray-and-wait
relay-ack
gateway-hint
blob-chunk
broadcast
Part 01 extension negotiation applies.
123. Capability Negotiation
Peer may support:
text bundles
blob chunk relay
public alerts
gateway mode
Routing chooses only common capabilities.
124. Device Identity Integration
Part 02 gives:
AccountId
DeviceId
device certificate
trust state
DTN uses these for:
origin authentication
destination resolution
trusted-relay policy
125. Transport/Routing Integration
Part 03 decides:
should this operation use DTN?
DTN then manages:
store
replicate
forward
If direct route later appears, Part 03 may bypass DTN and deliver immediately.
126. Event Log Integration
Part 04 records meaningful lifecycle:
BundleCreated
BundleForwarded
DestinationReached
BundleExpired
High-frequency encounter metrics stay out of semantic event log.
127. File/Blob Integration
Part 05 gives:
BlobId
ChunkId
manifest
encrypted chunks
DTN stores/forwards references or selected ciphertext chunks.
128. Crash Recovery
After process death:
load bundle store
↓
remove expired
↓
restore forwarding state
↓
resume encounter logic
No bundle accepted durably should vanish silently.
129. Atomic Bundle Acceptance
Transaction:
validate
reserve storage
write payload/ref
write bundle record
commit
Only after commit:
send RelayStored ACK
130. Staging
Large incoming relay payload may use staging.
After verification:
commit to relay blob store
Incomplete data remains resumable or disposable per policy.
131. Partial Relay Transfer
An encounter may end mid-bundle.
For chunked blob bundles:
resume later
For small inline bundle:
restart bounded transfer
132. Encounter Resumption
Stable:
BundleId
ChunkId
allows next encounter to continue without full restart.
133. Process Ownership
In daemon mode, DTN engine should live in background daemon/service.
On Android, foreground/background execution rules apply.
UI does not own forwarding lifecycle.
134. Android Background Restrictions
Kotlin/platform layer reports:
background allowed
foreground service active
Bluetooth scanning constraints
Wi-Fi constraints
Rust DTN policy adapts.
Do not hide OS restrictions with busy loops.
135. iOS Restrictions
iOS proximity/background behavior is more constrained.
DTN architecture must degrade gracefully:
foreground encounters
system-approved background opportunities
push-assisted Internet delivery
Do not assume Android-equivalent scanning.
136. Desktop DTN
Desktop can run:
continuous LAN discovery
Bluetooth if supported
Iroh gateway
large relay store
Useful as:
home relay
shelter node
community gateway
137. Headless DTN Node
A Linux/Raspberry Pi node can provide:
BLE
Wi-Fi
Ethernet
Iroh
large store
power supply
This becomes extremely useful in disaster deployments.
138. Emergency Relay Node
Recommended profile:
high relay quota
gateway preferred
critical reserve
authority alert support
continuous discovery
No messenger UI required.
139. Relay Node Identity
A relay can have:
service/device identity
without being conversation participant.
This supports accountability without content access.
140. Self-Hosted Relay/Gateway
Part 11 will expand Internet relay infrastructure.
DTN gateway can hand off to:
self-hosted Iroh relay
organization relay
public relay
according to policy.
141. Security Threats
Protect against:
bundle flooding
storage exhaustion
priority abuse
replay
routing loops
fake gateway claims
malformed bundle
expired spam
metadata tracking
malicious relay dropping bundles
DTN cannot guarantee a relay will forward honestly.
Use redundancy when required.
142. Routing Loop Prevention
Use:
BundleId dedup
hop limit
forward history
replication budget
Never rely on hop limit alone.
143. Forward History
Keep bounded:
which peer received bundle
when
result
Avoid sending same bundle back and forth endlessly.
144. Peer Bounce Prevention
If:
A gave bundle to B
then B should not immediately return same copy to A unless protocol explicitly requires reconciliation.
145. Malicious Drop
A relay can accept then drop.
No architecture can force untrusted relay cooperation.
Mitigations:
multiple copies
trusted gateways
delivery acknowledgements
reputation locally
146. Malicious Modification
End-to-end integrity detects payload/header tampering.
Receiver rejects.
147. Malicious Fabrication
Origin signatures/authenticated application payloads prevent forged private messages/authority alerts.
Bundle transport itself does not create application trust.
148. Rate Limiting
Per encounter:
max offers
max bytes
max critical claims
Per origin:
bundle count
storage use
149. Unknown-Origin Traffic
Unknown peers may be limited to:
small emergency reports
small relay bundles
depending on product policy.
150. Critical Traffic Abuse
Critical class should require:
local user action
trusted authority
or strict anonymous emergency quota
Do not expose unlimited unauthenticated Critical traffic.
151. Anti-Correlation Measures
Possible:
rotating discovery IDs
bundle batching
coarse timestamps
opaque destinations
But metadata privacy remains imperfect.
Document this honestly.
152. Storage Encryption
Relay store should persist ciphertext.
Local DTN metadata may also be encrypted at rest.
153. GC and Expiry
Periodic task:
remove expired
remove delivered after grace
remove cancelled
apply quota eviction
Must be crash-safe.
154. Tombstones
Delivery/cancel tombstones may be retained temporarily so stale peers do not reintroduce completed bundles immediately.
155. Tombstone TTL
Tombstone lifetime should exceed typical encounter delay horizon.
Not permanent by default.
156. Reintroduced Bundle
If old peer presents a delivered bundle while tombstone exists:
reject
send delivery summary if useful
157. Bundle Store Schema
Conceptual:
bundles
bundle_payload_refs
bundle_forward_history
bundle_tombstones
peer_encounters
peer_utility
dtn_quotas
158. Bundle Table
Fields:
bundle_id
state
priority
created_at
expires_at
hop_limit
copies_remaining
payload_type
payload_ref
origin
destination_token
size
159. Forward History Table
Fields:
bundle_id
peer_id
forwarded_at
result
Bound history length.
160. Encounter Table
Store coarse:
peer
last_seen
encounter_count
gateway_success
Avoid detailed long-term location history.
161. Performance
DTN is not a packet-forwarding hot path.
Prioritize:
correctness
bounded storage
efficient set reconciliation
small metadata
battery efficiency
162. Inventory Performance
For 100k bundles, do not send 100k IDs.
Use compact summaries.
Benchmark:
Bloom
IBLT later
Merkle later
163. Bundle Selection Complexity
Avoid O(all bundles × all peers) during every encounter.
Maintain indexes by:
priority
expiry
destination class
size
164. Encounter Time Budget
If contact lasts seconds:
selection must be fast
Precompute candidate queues where useful.
165. Metrics
Track:
bundles stored
bundles forwarded
bundles delivered
average relay count
expired count
evicted count
bytes relayed
gateway success
encounter success
Keep private identities out of exported telemetry.
166. Diagnostics
Useful:
DTN enabled
relay storage used
nearby peers
gateway seen
pending bundles
critical pending
last successful forward
Normal users should see simpler status.
167. UI State Mapping
Examples:
Stored locally
Waiting for nearby device
Carried by 2 relay devices
Reached gateway
Delivered
Expired
Do not show:
custody transfer complete
spray copy count 3
outside diagnostics.
168. Developer View
Advanced diagnostics may show:
BundleId
priority
copies remaining
hop limit
next candidates
last peer
gateway score
169. Testing Layers
Unit:
bundle validation
expiry
replication budget
dedup
eviction
Integration:
A → B → C
gateway handoff
ACK return
Fault:
peer disappears mid-transfer
duplicate bundle
crash
storage full
Security:
fake priority
tampered bundle
replay
oversized metadata
170. Multi-Hop Test
Topology:
A ↔ B ↔ C ↔ D
Only D has Internet.
Expected:
A creates bundle
B stores
C stores
D forwards via Internet
destination ACK
ACK eventually returns
171. Partition Test
Cluster 1: A-B-C
Cluster 2: D-E-F
Later C meets D.
Relevant bundles reconcile and continue.
172. Mobility Test
Random peers appear/disappear.
Assert:
bounded copies
no infinite loop
eventual delivery when encounter path exists
173. Duplicate Route Test
Same message arrives via:
Iroh
and DTN
Application records one logical message.
174. Expiry Test
Bundle expires while offline.
On next encounter:
not forwarded
and eventually removed.
175. Storage Pressure Test
Fill relay store.
Ensure:
bulk evicted before critical
critical reserve preserved
176. Battery Saver Test
Enable low-power mode.
Ensure:
reduced scan
critical still forwarded
bulk delayed
177. Crash Test
Crash after:
bundle persisted
before relay ACK
After restart:
bundle still present
duplicate resend handled idempotently
178. Fuzz Targets
Fuzz:
bundle header
inventory summary
ack summary
replication metadata
broadcast descriptor
All allocations bounded.
179. Property Tests
Invariants:
copies never exceed origin max budget
expired bundle never forwarded
same BundleId stored once
hop count never increases
delivered tombstone prevents immediate resurrection
180. Simulated Network
Build deterministic simulator:
nodes
encounters
transport capacities
battery states
gateway availability
This is critical for validating DTN algorithms.
181. Strategy Comparison Harness
Simulator can compare:
DirectOnly
SprayAndWait
GatewayPreferred
EmergencyLimitedFlood
Metrics:
delivery rate
delay
bytes transmitted
battery cost proxy
storage use
182. No ML Initially
Do not use ML for forwarding at first.
Deterministic algorithms are:
- explainable
- testable
- predictable
- safer
183. Public API
High-level:
#![allow(unused)] fn main() { let handle = dtn.enqueue( destination, payload_ref, DtnPolicy::default(), ).await?; }
Applications should not manage peer encounter tables directly.
184. Bundle Handle
#![allow(unused)] fn main() { pub struct BundleHandle { pub id: BundleId, } }
Operations:
status
cancel
priority
expiry
subject to policy.
185. DTN Events
#![allow(unused)] fn main() { pub enum DtnEvent { Stored(BundleId), Forwarded(BundleId, PeerId), RelayConfirmed(BundleId), GatewayReached(BundleId), DestinationReached(BundleId), Expired(BundleId), Evicted(BundleId), } }
186. Suggested Crate Structure
crates/comm-dtn/
├── src/
│ ├── lib.rs
│ ├── bundle.rs
│ ├── store.rs
│ ├── state.rs
│ ├── policy.rs
│ ├── scheduler.rs
│ ├── forwarding.rs
│ ├── strategy.rs
│ ├── encounter.rs
│ ├── inventory.rs
│ ├── ack.rs
│ ├── gateway.rs
│ ├── quota.rs
│ ├── gc.rs
│ ├── diagnostics.rs
│ └── error.rs
│
├── tests/
└── Cargo.toml
Protocol crate if separated:
comm-dtn-protocol/
187. Error Model
#![allow(unused)] fn main() { pub enum DtnError { StorageFull, QuotaExceeded, InvalidBundle, Expired, Unauthorized, Unsupported, Duplicate, Cancelled, Transport, Storage, } }
188. Initial Production Scope
Implement first:
durable bundle store
BundleId dedup
expiry
hop limit
replication budget
Spray-and-Wait
BLE/Wi-Fi/Iroh encounter transport abstraction
inventory summary
relay ACK
destination ACK
gateway handoff
quotas
eviction
critical reserve
crash recovery
Defer initially:
IBLT
social routing
predictive routing
complex custody transfer
large-scale epidemic mode
189. Implementation Phases
Phase 1 — Bundle model
BundleId
metadata
expiry
priority
policy
Phase 2 — Durable store
bundle table
payload refs
dedup
GC
Phase 3 — Encounter protocol
HELLO
inventory
request
transfer
relay ACK
Phase 4 — Forwarding strategy
DirectOnly
SprayAndWait
GatewayPreferred
Phase 5 — Routing integration
Part 03 handoff
DTN route plan
gateway path
Phase 6 — File/blob integration
manifest
thumbnail
chunk carriage
Phase 7 — Emergency priority
critical reserve
priority authorization
broadcast
Phase 8 — Hardening
simulation
fuzzing
crash injection
battery/storage tests
190. Definition of Done
Part 06 is complete when:
- a payload can be accepted with no end-to-end route
- accepted bundles are durably stored
- relays can carry ciphertext without content keys
- BundleId deduplicates multiple copies
- forwarding loops are bounded
- hop limit and replication budget are enforced
- expired bundles are never forwarded
- peer encounters reconcile inventories efficiently
- relay ACK is distinct from destination delivery
- destination ACK can propagate back asynchronously
- gateway nodes can bridge local transport to Internet/Iroh
- BLE/Wi-Fi/Iroh can all serve as encounter transports
- large files can use manifests/thumbnails/chunks rather than blind full replication
- storage quotas and critical reserve work
- emergency traffic can outrank bulk traffic
- unknown peers cannot exhaust storage without limits
- crash recovery preserves accepted relay bundles
- UI can distinguish carried vs delivered
- the subsystem works without Dioxus
- file-only/emergency/custom apps can reuse it
- simulation, fuzz, property, partition, and mobility tests exist
191. Relationship to Earlier Parts
Part 06 builds on:
01 — Protocol Extension System
02 — Multi-Device Identity
03 — Transport & Routing Policy Engine
04 — Offline Event Log
05 — Robust File / Blob Subsystem
It directly supports:
07 — Capability Negotiation Expansion
08 — Resource Limits & Backpressure
09 — Crash Recovery
10 — Protocol Fuzzing & Test Suite
11 — Relay / Self-Hosted Infrastructure
12 — Multipath Networking
13 — Battery-Aware Scheduling
14 — Proximity Abstraction
15 — QR / NFC Bootstrap Pairing
16 — Daemon & Headless Runtime
17 — Emergency Priority Architecture
18 — Network Diagnostics & Path Visualization
20 — Embedded Linux Node
23 — External Interoperability Suite
24 — Plugin / Module Ecosystem
192. Final Principle
The DTN subsystem should make this possible:
Alice sends an SOS
while completely offline.
Her phone stores it.
Later she meets Bob over BLE.
Bob carries it.
Bob later meets Carol over Wi-Fi Direct.
Carol carries it.
Carol reaches Internet.
The bundle is delivered through Iroh.
A destination acknowledgement travels back later.
Alice eventually sees:
Delivered.
The original application payload remains the same logical object throughout.
No continuous route was ever required.
That is the defining capability of a true resilient, disaster-capable communication platform.