From f7931e95b6e9c96a894278753e9e236dab20e02e Mon Sep 17 00:00:00 2001 From: famfo Date: Tue, 27 Jan 2026 15:04:37 +0100 Subject: [PATCH] tokio-xmpp: implicitly add bound_jid to IQs --- tokio-xmpp/ChangeLog | 2 ++ tokio-xmpp/src/client/iq.rs | 18 +++++++++++++++++- tokio-xmpp/src/client/stream.rs | 4 ++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tokio-xmpp/ChangeLog b/tokio-xmpp/ChangeLog index c4ed9cb0..507d4065 100644 --- a/tokio-xmpp/ChangeLog +++ b/tokio-xmpp/ChangeLog @@ -3,6 +3,8 @@ Version NEXT: * Fixed: - Ignore missing "version" stream attribute for 0114 components. - Gate `AsRawFd` behind `ktls` feature to make Windows build work again. + - Implicitly use the `Client`'s bound JID on empty `to` in tokio-xmpp's + `IqResponseTracker`. Version 5.0.0: 2025-10-28 pep diff --git a/tokio-xmpp/src/client/iq.rs b/tokio-xmpp/src/client/iq.rs index a5c7599d..0227b175 100644 --- a/tokio-xmpp/src/client/iq.rs +++ b/tokio-xmpp/src/client/iq.rs @@ -14,6 +14,7 @@ use core::pin::Pin; use core::task::{ready, Context, Poll}; use std::io; use std::sync::Mutex; +use xmpp_parsers::jid::BareJid; use futures::Stream; use tokio::sync::oneshot; @@ -254,6 +255,7 @@ impl IqResponseSink { #[derive(Debug)] pub struct IqResponseTracker { map: Arc>, + account_jid: Arc>>, } impl IqResponseTracker { @@ -261,9 +263,16 @@ impl IqResponseTracker { pub fn new() -> Self { Self { map: Arc::new(Mutex::new(IqMap::new())), + account_jid: Arc::new(Mutex::new(None)), } } + /// Set the local JID the `IqResponseTracker` is handling IQs on behalf of. + pub fn set_account_jid(&self, jid: BareJid) { + let mut guard = self.account_jid.lock().unwrap(); + *guard = Some(jid); + } + /// Attempt to handle an IQ stanza as IQ response. /// /// Returns the IQ stanza unharmed if it is not an IQ response matching @@ -305,9 +314,16 @@ impl IqResponseTracker { pub fn allocate_iq_handle( &self, from: Option, - to: Option, + mut to: Option, req: IqRequest, ) -> (Iq, IqResponseToken) { + if to.is_none() { + // Implicitly setting None to the JID the tracker is active for, which the server + // should do as well. This ensures that the IQ can be matched in the map again. + let account_jid = self.account_jid.lock().unwrap(); + to = account_jid.clone().map(Jid::from); + } + let key = (to, make_id()); let mut map = self.map.lock().unwrap(); let (tx, rx) = oneshot::channel(); diff --git a/tokio-xmpp/src/client/stream.rs b/tokio-xmpp/src/client/stream.rs index 84858686..6057ecef 100644 --- a/tokio-xmpp/src/client/stream.rs +++ b/tokio-xmpp/src/client/stream.rs @@ -48,6 +48,10 @@ impl Stream for Client { })) => { self.features = Some(features); self.bound_jid = Some(bound_jid.clone()); + + self.iq_response_tracker + .set_account_jid(bound_jid.to_bare()); + Some(Event::Online { bound_jid, resumed: false,