fix: IP-based peer matching for inbound federation + room announcements
Some checks failed
Mirror to GitHub / mirror (push) Failing after 37s
Build Release Binaries / build-amd64 (push) Failing after 1m53s

- Inbound federation connections now matched by source IP against
  configured peer URLs (QUIC clients don't present TLS certs, so
  fingerprint matching fails for inbound direction).
- Added periodic room announcement task (1s poll) that sends
  FederationRoomJoin to peers when new rooms appear with local
  participants. Handles rooms created after federation link is up.
- Added find_peer_by_addr() to FederationManager.

Federation link topology: each relay pair has 2 connections (outbound
from each side). Outbound sends signals, peer's inbound receives them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-08 05:49:37 +04:00
parent 6be36e43c2
commit e50925e05a
2 changed files with 51 additions and 14 deletions

View File

@@ -501,16 +501,8 @@ async fn main() -> anyhow::Result<()> {
// Federation connections use SNI "_federation"
if room_name == "_federation" {
if let Some(ref fm) = federation_mgr {
// Check if we recognize this peer by TLS fingerprint
let peer_fp = wzp_transport::tls_fingerprint(
&transport.connection()
.peer_identity()
.and_then(|id| id.downcast::<Vec<rustls::pki_types::CertificateDer>>().ok())
.and_then(|certs| certs.first().cloned())
.map(|c| c.to_vec())
.unwrap_or_default()
);
if let Some(peer_config) = fm.find_peer_by_fingerprint(&peer_fp) {
// Match inbound peer by source IP (client connections don't present TLS certs)
if let Some(peer_config) = fm.find_peer_by_addr(addr) {
let peer_config = peer_config.clone();
let fm = fm.clone();
info!(%addr, label = ?peer_config.label, "inbound federation connection accepted");
@@ -520,12 +512,9 @@ async fn main() -> anyhow::Result<()> {
info!(" to accept, add to relay.toml:");
info!(" [[peers]]");
info!(" url = \"{addr}\"");
info!(" fingerprint = \"{peer_fp}\"");
transport.close().await.ok();
}
} else {
info!(%addr, "federation connection rejected (no peers configured)");
transport.close().await.ok();
}
return;
}