tokio-xmpp: Send the initial stream:stream in a single packet
Prosody would let the stream opening timeout if it receives it in more than one TCP packet, which seems like a bug. The behaviour was highly non-deterministic, a release build would almost always (but not always) succeed to connect to a localhost Prosody, a debug build would almost always (but not always) fail, and RUST_LOG=trace would make any build fail to connect, as would strace. My theory is that successful runs rely on the kernel merging all five TCP packets in a single one, and any tracing would add sufficient delay in-between to let it send every packet on its own.
This commit is contained in:
parent
393feb8d5e
commit
24cb246809
2 changed files with 28 additions and 36 deletions
|
|
@ -16,6 +16,8 @@ Version NEXT:
|
||||||
`tokio_xmpp::connect::DnsConfig`
|
`tokio_xmpp::connect::DnsConfig`
|
||||||
* Fixed:
|
* Fixed:
|
||||||
- Ignore missing "version" stream attribute for 0114 components.
|
- Ignore missing "version" stream attribute for 0114 components.
|
||||||
|
- Always send the stream:stream opening in one TCP packet, to workaround
|
||||||
|
issue #1995 in Prosody. (!680)
|
||||||
- Gate `AsRawFd` behind `ktls` feature to make Windows build work again.
|
- Gate `AsRawFd` behind `ktls` feature to make Windows build work again.
|
||||||
- Implicitly use the `Client`'s bound JID on empty `from` and `to` in
|
- Implicitly use the `Client`'s bound JID on empty `from` and `to` in
|
||||||
tokio-xmpp's `IqResponseTracker`.
|
tokio-xmpp's `IqResponseTracker`.
|
||||||
|
|
|
||||||
|
|
@ -803,48 +803,38 @@ impl StreamHeader<'_> {
|
||||||
mut stream: Pin<&mut RawXmlStream<Io>>,
|
mut stream: Pin<&mut RawXmlStream<Io>>,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
stream
|
stream
|
||||||
.send(Item::XmlDeclaration(rxml::XmlVersion::V1_0))
|
.as_mut()
|
||||||
.await?;
|
.start_send(Item::XmlDeclaration(rxml::XmlVersion::V1_0))?;
|
||||||
stream
|
stream.as_mut().start_send(Item::ElementHeadStart(
|
||||||
.send(Item::ElementHeadStart(
|
Namespace::from(XML_STREAM_NS),
|
||||||
Namespace::from(XML_STREAM_NS),
|
Cow::Borrowed(xml_ncname!("stream")),
|
||||||
Cow::Borrowed(xml_ncname!("stream")),
|
))?;
|
||||||
))
|
|
||||||
.await?;
|
|
||||||
if let Some(from) = self.from {
|
if let Some(from) = self.from {
|
||||||
stream
|
stream.as_mut().start_send(Item::Attribute(
|
||||||
.send(Item::Attribute(
|
Namespace::NONE,
|
||||||
Namespace::NONE,
|
Cow::Borrowed(xml_ncname!("from")),
|
||||||
Cow::Borrowed(xml_ncname!("from")),
|
from,
|
||||||
from,
|
))?;
|
||||||
))
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
if let Some(to) = self.to {
|
if let Some(to) = self.to {
|
||||||
stream
|
stream.as_mut().start_send(Item::Attribute(
|
||||||
.send(Item::Attribute(
|
Namespace::NONE,
|
||||||
Namespace::NONE,
|
Cow::Borrowed(xml_ncname!("to")),
|
||||||
Cow::Borrowed(xml_ncname!("to")),
|
to,
|
||||||
to,
|
))?;
|
||||||
))
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
if let Some(id) = self.id {
|
if let Some(id) = self.id {
|
||||||
stream
|
stream.as_mut().start_send(Item::Attribute(
|
||||||
.send(Item::Attribute(
|
|
||||||
Namespace::NONE,
|
|
||||||
Cow::Borrowed(xml_ncname!("id")),
|
|
||||||
id,
|
|
||||||
))
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
stream
|
|
||||||
.send(Item::Attribute(
|
|
||||||
Namespace::NONE,
|
Namespace::NONE,
|
||||||
Cow::Borrowed(xml_ncname!("version")),
|
Cow::Borrowed(xml_ncname!("id")),
|
||||||
Cow::Borrowed("1.0"),
|
id,
|
||||||
))
|
))?;
|
||||||
.await?;
|
}
|
||||||
|
stream.as_mut().start_send(Item::Attribute(
|
||||||
|
Namespace::NONE,
|
||||||
|
Cow::Borrowed(xml_ncname!("version")),
|
||||||
|
Cow::Borrowed("1.0"),
|
||||||
|
))?;
|
||||||
stream.send(Item::ElementHeadEnd).await?;
|
stream.send(Item::ElementHeadEnd).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue