xmlstream: implement simple timeout logic
This allows to detect and handle dying streams without getting stuck forever. Timeouts are always wrong, though, so we put the burden of choosing the right values (mostly) on the creator of a stream.
This commit is contained in:
parent
960fd782bd
commit
4cfe4f8429
16 changed files with 469 additions and 76 deletions
|
|
@ -19,7 +19,9 @@ use crate::{
|
|||
client::bind::bind,
|
||||
connect::ServerConnector,
|
||||
error::{AuthError, Error, ProtocolError},
|
||||
xmlstream::{xmpp::XmppStreamElement, InitiatingStream, ReadError, StreamHeader, XmppStream},
|
||||
xmlstream::{
|
||||
xmpp::XmppStreamElement, InitiatingStream, ReadError, StreamHeader, Timeouts, XmppStream,
|
||||
},
|
||||
};
|
||||
|
||||
pub async fn auth<S: AsyncBufRead + AsyncWrite + Unpin>(
|
||||
|
|
@ -107,11 +109,12 @@ pub async fn client_login<C: ServerConnector>(
|
|||
server: C,
|
||||
jid: Jid,
|
||||
password: String,
|
||||
timeouts: Timeouts,
|
||||
) -> Result<(Option<FullJid>, StreamFeatures, XmppStream<C::Stream>), Error> {
|
||||
let username = jid.node().unwrap().as_str();
|
||||
let password = password;
|
||||
|
||||
let xmpp_stream = server.connect(&jid, ns::JABBER_CLIENT).await?;
|
||||
let xmpp_stream = server.connect(&jid, ns::JABBER_CLIENT, timeouts).await?;
|
||||
let (features, xmpp_stream) = xmpp_stream.recv_features().await?;
|
||||
|
||||
let channel_binding = C::channel_binding(xmpp_stream.get_stream())?;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use crate::{
|
|||
client::{login::client_login, stream::ClientState},
|
||||
connect::ServerConnector,
|
||||
error::Error,
|
||||
xmlstream::Timeouts,
|
||||
Stanza,
|
||||
};
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ pub struct Client<C: ServerConnector> {
|
|||
password: String,
|
||||
connector: C,
|
||||
state: ClientState<C::Stream>,
|
||||
timeouts: Timeouts,
|
||||
reconnect: bool,
|
||||
// TODO: tls_required=true
|
||||
}
|
||||
|
|
@ -95,6 +97,7 @@ impl Client<StartTlsServerConnector> {
|
|||
jid.clone(),
|
||||
password,
|
||||
DnsConfig::srv(&jid.domain().to_string(), "_xmpp-client._tcp", 5222),
|
||||
Timeouts::default(),
|
||||
);
|
||||
client.set_reconnect(true);
|
||||
client
|
||||
|
|
@ -105,8 +108,14 @@ impl Client<StartTlsServerConnector> {
|
|||
jid: J,
|
||||
password: P,
|
||||
dns_config: DnsConfig,
|
||||
timeouts: Timeouts,
|
||||
) -> Self {
|
||||
Self::new_with_connector(jid, password, StartTlsServerConnector::from(dns_config))
|
||||
Self::new_with_connector(
|
||||
jid,
|
||||
password,
|
||||
StartTlsServerConnector::from(dns_config),
|
||||
timeouts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,8 +126,14 @@ impl Client<TcpServerConnector> {
|
|||
jid: J,
|
||||
password: P,
|
||||
dns_config: DnsConfig,
|
||||
timeouts: Timeouts,
|
||||
) -> Self {
|
||||
Self::new_with_connector(jid, password, TcpServerConnector::from(dns_config))
|
||||
Self::new_with_connector(
|
||||
jid,
|
||||
password,
|
||||
TcpServerConnector::from(dns_config),
|
||||
timeouts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,6 +143,7 @@ impl<C: ServerConnector> Client<C> {
|
|||
jid: J,
|
||||
password: P,
|
||||
connector: C,
|
||||
timeouts: Timeouts,
|
||||
) -> Self {
|
||||
let jid = jid.into();
|
||||
let password = password.into();
|
||||
|
|
@ -136,6 +152,7 @@ impl<C: ServerConnector> Client<C> {
|
|||
connector.clone(),
|
||||
jid.clone(),
|
||||
password.clone(),
|
||||
timeouts,
|
||||
));
|
||||
let client = Client {
|
||||
jid,
|
||||
|
|
@ -143,6 +160,7 @@ impl<C: ServerConnector> Client<C> {
|
|||
connector,
|
||||
state: ClientState::Connecting(connect),
|
||||
reconnect: false,
|
||||
timeouts,
|
||||
};
|
||||
client
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ impl<C: ServerConnector> Stream for Client<C> {
|
|||
self.connector.clone(),
|
||||
self.jid.clone(),
|
||||
self.password.clone(),
|
||||
self.timeouts,
|
||||
));
|
||||
self.state = ClientState::Connecting(connect);
|
||||
self.poll_next(cx)
|
||||
|
|
|
|||
Loading…
Reference in a new issue