This commit is contained in:
dignifiedquire
2024-12-16 22:29:10 +01:00
parent 34439085fd
commit a908f376a2
5 changed files with 702 additions and 790 deletions

1427
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -57,15 +57,14 @@ fd-lock = "4"
futures-lite = { workspace = true } futures-lite = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
hex = "0.4.0" hex = "0.4.0"
hickory-resolver = "=0.25.0-alpha.2" hickory-resolver = "=0.25.0-alpha.4"
http-body-util = "0.1.2" http-body-util = "0.1.2"
humansize = "2" humansize = "2"
hyper = "1" hyper = "1"
hyper-util = "0.1.10" hyper-util = "0.1.10"
image = { version = "0.25.5", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] } image = { version = "0.25.5", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] }
iroh-gossip = { version = "0.29", default-features = false, features = ["net"] } iroh-gossip = { git = "https://github.com/n0-computer/iroh-gossip", branch = "iroh-v0-30-0", version = "0.29", default-features = false, features = ["net"] }
iroh = { version = "0.29", default-features = false } iroh = { version = "0.30", default-features = false }
iroh-base = { version = "0.29", features = ["base32"] }
kamadak-exif = "0.6.1" kamadak-exif = "0.6.1"
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" } lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" }
libc = { workspace = true } libc = { workspace = true }
@@ -111,6 +110,7 @@ toml = "0.8"
url = "2" url = "2"
uuid = { version = "1", features = ["serde", "v4"] } uuid = { version = "1", features = ["serde", "v4"] }
webpki-roots = "0.26.7" webpki-roots = "0.26.7"
data-encoding = "2.6.0"
[dev-dependencies] [dev-dependencies]
anyhow = { workspace = true, features = ["backtrace"] } # Enable `backtrace` feature in tests. anyhow = { workspace = true, features = ["backtrace"] } # Enable `backtrace` feature in tests.

View File

@@ -24,16 +24,15 @@
//! and `joinRealtimeChannel().send()` just like the other peers. //! and `joinRealtimeChannel().send()` just like the other peers.
use anyhow::{anyhow, bail, Context as _, Result}; use anyhow::{anyhow, bail, Context as _, Result};
use data_encoding::BASE32_NOPAD;
use email::Header; use email::Header;
use futures_lite::StreamExt; use futures_lite::StreamExt;
use iroh::key::{PublicKey, SecretKey}; use iroh::{Endpoint, NodeAddr, NodeId, PublicKey, RelayMap, RelayMode, RelayUrl, SecretKey};
use iroh::{Endpoint, NodeAddr, NodeId, RelayMap, RelayMode, RelayUrl};
use iroh_gossip::net::{Event, Gossip, GossipEvent, JoinOptions, GOSSIP_ALPN}; use iroh_gossip::net::{Event, Gossip, GossipEvent, JoinOptions, GOSSIP_ALPN};
use iroh_gossip::proto::TopicId; use iroh_gossip::proto::TopicId;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::collections::{BTreeSet, HashMap}; use std::collections::{BTreeSet, HashMap};
use std::env; use std::env;
use std::sync::Arc;
use tokio::sync::{oneshot, RwLock}; use tokio::sync::{oneshot, RwLock};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use url::Url; use url::Url;
@@ -57,7 +56,7 @@ pub struct Iroh {
pub(crate) router: iroh::protocol::Router, pub(crate) router: iroh::protocol::Router,
/// [Gossip] needed for iroh peer channels. /// [Gossip] needed for iroh peer channels.
pub(crate) gossip: Arc<Gossip>, pub(crate) gossip: Gossip,
/// Sequence numbers for gossip channels. /// Sequence numbers for gossip channels.
pub(crate) sequence_numbers: Mutex<HashMap<TopicId, i32>>, pub(crate) sequence_numbers: Mutex<HashMap<TopicId, i32>>,
@@ -116,7 +115,7 @@ impl Iroh {
// Inform iroh of potentially new node addresses // Inform iroh of potentially new node addresses
for node_addr in &peers { for node_addr in &peers {
if !node_addr.info.is_empty() { if !node_addr.is_empty() {
self.router.endpoint().add_node_addr(node_addr.clone())?; self.router.endpoint().add_node_addr(node_addr.clone())?;
} }
} }
@@ -125,7 +124,7 @@ impl Iroh {
let (gossip_sender, gossip_receiver) = self let (gossip_sender, gossip_receiver) = self
.gossip .gossip
.join_with_opts(topic, JoinOptions::with_bootstrap(node_ids)) .subscribe_with_opts(topic, JoinOptions::with_bootstrap(node_ids))
.split(); .split();
let ctx = ctx.clone(); let ctx = ctx.clone();
@@ -147,7 +146,7 @@ impl Iroh {
self.router.endpoint().add_node_addr(peer.clone())?; self.router.endpoint().add_node_addr(peer.clone())?;
} }
self.gossip.join_with_opts( self.gossip.subscribe_with_opts(
topic, topic,
JoinOptions::with_bootstrap(peers.into_iter().map(|peer| peer.node_id)), JoinOptions::with_bootstrap(peers.into_iter().map(|peer| peer.node_id)),
); );
@@ -195,7 +194,7 @@ impl Iroh {
/// Get the iroh [NodeAddr] without direct IP addresses. /// Get the iroh [NodeAddr] without direct IP addresses.
pub(crate) async fn get_node_addr(&self) -> Result<NodeAddr> { pub(crate) async fn get_node_addr(&self) -> Result<NodeAddr> {
let mut addr = self.router.endpoint().node_addr().await?; let mut addr = self.router.endpoint().node_addr().await?;
addr.info.direct_addresses = BTreeSet::new(); addr.direct_addresses = BTreeSet::new();
Ok(addr) Ok(addr)
} }
@@ -238,7 +237,7 @@ impl Context {
/// Create iroh endpoint and gossip. /// Create iroh endpoint and gossip.
async fn init_peer_channels(&self) -> Result<Iroh> { async fn init_peer_channels(&self) -> Result<Iroh> {
info!(self, "Initializing peer channels."); info!(self, "Initializing peer channels.");
let secret_key = SecretKey::generate(); let secret_key = SecretKey::generate(rand::rngs::OsRng);
let public_key = secret_key.public(); let public_key = secret_key.public();
let relay_mode = if let Some(relay_url) = self let relay_mode = if let Some(relay_url) = self
@@ -263,19 +262,14 @@ impl Context {
.await?; .await?;
// create gossip // create gossip
let my_addr = endpoint.node_addr().await?; // Allow messages up to 128 KB in size.
let gossip_config = iroh_gossip::proto::topic::Config { // We set the limit to 128 KiB to account for internal overhead,
// Allow messages up to 128 KB in size. // but only guarantee 128 KB of payload to WebXDC developers.
// We set the limit to 128 KiB to account for internal overhead,
// but only guarantee 128 KB of payload to WebXDC developers. let gossip = Gossip::builder()
max_message_size: 128 * 1024, .max_message_size(128 * 1024)
..Default::default() .spawn(endpoint.clone())
}; .await?;
let gossip = Arc::new(Gossip::from_endpoint(
endpoint.clone(),
gossip_config,
&my_addr.info,
));
let router = iroh::protocol::Router::builder(endpoint) let router = iroh::protocol::Router::builder(endpoint)
.accept(GOSSIP_ALPN, gossip.clone()) .accept(GOSSIP_ALPN, gossip.clone())
@@ -506,7 +500,7 @@ fn create_random_topic() -> TopicId {
pub(crate) async fn create_iroh_header(ctx: &Context, msg_id: MsgId) -> Result<Header> { pub(crate) async fn create_iroh_header(ctx: &Context, msg_id: MsgId) -> Result<Header> {
let topic = create_random_topic(); let topic = create_random_topic();
insert_topic_stub(ctx, msg_id, topic).await?; insert_topic_stub(ctx, msg_id, topic).await?;
let topic_string = iroh_base::base32::fmt(topic.as_bytes()); let topic_string = BASE32_NOPAD.encode(topic.as_bytes()).to_ascii_lowercase();
Ok(Header::new( Ok(Header::new(
HeaderDef::IrohGossipTopic.get_headername().to_string(), HeaderDef::IrohGossipTopic.get_headername().to_string(),
topic_string, topic_string,

View File

@@ -4,7 +4,7 @@ pub(crate) mod data;
use anyhow::Result; use anyhow::Result;
use deltachat_contact_tools::EmailAddress; use deltachat_contact_tools::EmailAddress;
use hickory_resolver::{config, AsyncResolver, TokioAsyncResolver}; use hickory_resolver::{config, Resolver, TokioResolver};
use crate::config::Config; use crate::config::Config;
use crate::context::Context; use crate::context::Context;
@@ -165,11 +165,11 @@ impl ProviderOptions {
/// We first try to read the system's resolver from `/etc/resolv.conf`. /// We first try to read the system's resolver from `/etc/resolv.conf`.
/// This does not work at least on some Androids, therefore we fallback /// This does not work at least on some Androids, therefore we fallback
/// to the default `ResolverConfig` which uses eg. to google's `8.8.8.8` or `8.8.4.4`. /// to the default `ResolverConfig` which uses eg. to google's `8.8.8.8` or `8.8.4.4`.
fn get_resolver() -> Result<TokioAsyncResolver> { fn get_resolver() -> Result<TokioResolver> {
if let Ok(resolver) = AsyncResolver::tokio_from_system_conf() { if let Ok(resolver) = Resolver::tokio_from_system_conf() {
return Ok(resolver); return Ok(resolver);
} }
let resolver = AsyncResolver::tokio( let resolver = Resolver::tokio(
config::ResolverConfig::default(), config::ResolverConfig::default(),
config::ResolverOpts::default(), config::ResolverOpts::default(),
); );

View File

@@ -3,6 +3,7 @@
use std::collections::HashSet; use std::collections::HashSet;
use anyhow::{Context as _, Result}; use anyhow::{Context as _, Result};
use data_encoding::BASE32_NOPAD;
use deltachat_contact_tools::{addr_cmp, may_be_valid_addr, sanitize_single_line, ContactAddress}; use deltachat_contact_tools::{addr_cmp, may_be_valid_addr, sanitize_single_line, ContactAddress};
use iroh_gossip::proto::TopicId; use iroh_gossip::proto::TopicId;
use mailparse::SingleInfo; use mailparse::SingleInfo;
@@ -1652,8 +1653,12 @@ RETURNING id
if part.typ == Viewtype::Webxdc { if part.typ == Viewtype::Webxdc {
if let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic) { if let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic) {
// default encoding of topic ids is `hex`. // default encoding of topic ids is `hex`.
let topic_raw: [u8; 32] = let mut topic_raw = [0u8; 32];
iroh_base::base32::parse_array(topic).context("wrong gossip topic header")?; BASE32_NOPAD
.decode_mut(topic.to_ascii_uppercase().as_bytes(), &mut topic_raw)
.map_err(|e| e.error)
.context("wrong gossip topic header")?;
let topic = TopicId::from_bytes(topic_raw); let topic = TopicId::from_bytes(topic_raw);
insert_topic_stub(context, *msg_id, topic).await?; insert_topic_stub(context, *msg_id, topic).await?;
} else { } else {