feat: DM epoch fix, federation relay, and mDNS mesh discovery

- schema: createChannel returns wasNew :Bool to elect the MLS initiator
  unambiguously; prevents duplicate group creation on concurrent /dm calls
- core: group helpers for epoch tracking and key-package lifecycle
- server: federation subsystem — mTLS QUIC server-to-server relay with
  Cap'n Proto RPC; enqueue/batchEnqueue relay unknown recipients to their
  home domain via FederationClient
- server: mDNS _quicproquo._udp.local. service announcement on startup
- server: storage + sql_store — identity_exists, peek/ack, federation
  home-server lookup helpers
- client: /mesh peers REPL command (mDNS discovery, feature = "mesh")
- client: MeshDiscovery — background mDNS browse with ServiceDaemon
- client: was_new=false path in cmd_dm waits for peer Welcome instead of
  creating a duplicate initiator group
- p2p: fix ALPN from quicnprotochat/p2p/1 → quicproquo/p2p/1
- workspace: re-include quicproquo-p2p in members
This commit is contained in:
2026-03-03 14:41:56 +01:00
parent e24497bf90
commit c8398d6cb7
27 changed files with 3375 additions and 303 deletions

View File

@@ -2,6 +2,8 @@
//!
//! A bare `username` (no `@`) is treated as local.
#![allow(dead_code)] // federation not yet wired up
/// A parsed federated address.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FederatedAddress {

View File

@@ -2,15 +2,16 @@
//!
//! Uses a lazy connection pool (DashMap) to reuse QUIC connections to known peers.
#![allow(dead_code)] // federation not yet wired up
use std::collections::HashMap;
use std::net::SocketAddr;
use std::sync::Arc;
use anyhow::Context;
use dashmap::DashMap;
use quinn::Endpoint;
use crate::config::{EffectiveFederationConfig, FederationPeerConfig};
use crate::config::EffectiveFederationConfig;
/// Outbound federation client for relaying to peer servers.
pub struct FederationClient {

View File

@@ -11,6 +11,4 @@ pub mod routing;
pub mod service;
pub mod tls;
pub use address::FederatedAddress;
pub use client::FederationClient;
pub use routing::Destination;

View File

@@ -46,7 +46,7 @@ pub fn build_federation_server_config(
let mut tls = rustls::ServerConfig::builder_with_protocol_versions(&[&TLS13])
.with_client_cert_verifier(client_verifier)
.with_single_cert(cert_chain, key)?;
tls.alpn_protocols = vec![b"qnpc-fed".to_vec()];
tls.alpn_protocols = vec![b"quicproquo/federation/1".to_vec()];
let crypto = QuicServerConfig::try_from(tls)
.map_err(|e| anyhow::anyhow!("invalid federation server TLS config: {e}"))?;