Disable Pinger until after MOTD

Some servers ignore PING commands until after login, so clients would
otherwise always time out, as mentioned in #207, #214, and #218.

With this change I am able to reliably connect to ircu servers.
This commit is contained in:
Thomas Hurst 2020-11-17 05:04:37 +00:00
parent 7377247c05
commit 4c27a9513d

View file

@ -20,12 +20,14 @@ use tokio_util::codec::Framed;
use crate::{ use crate::{
client::data::Config, client::data::Config,
error, error,
proto::{Command, IrcCodec, Message}, proto::{Command, Response, IrcCodec, Message},
}; };
/// Pinger-based futures helper. /// Pinger-based futures helper.
struct Pinger { struct Pinger {
tx: UnboundedSender<Message>, tx: UnboundedSender<Message>,
// Whether this pinger pings.
enabled: bool,
/// The amount of time to wait before timing out from no ping response. /// The amount of time to wait before timing out from no ping response.
ping_timeout: Duration, ping_timeout: Duration,
/// The instant that the last ping was sent to the server. /// The instant that the last ping was sent to the server.
@ -42,6 +44,7 @@ impl Pinger {
Self { Self {
tx, tx,
enabled: false,
ping_timeout, ping_timeout,
ping_deadline: None, ping_deadline: None,
ping_interval: time::interval(ping_time), ping_interval: time::interval(ping_time),
@ -51,6 +54,10 @@ impl Pinger {
/// Handle an incoming message. /// Handle an incoming message.
fn handle_message(&mut self, message: &Message) -> error::Result<()> { fn handle_message(&mut self, message: &Message) -> error::Result<()> {
match message.command { match message.command {
Command::Response(Response::RPL_ENDOFMOTD, _)
| Command::Response(Response::ERR_NOMOTD, _) => {
self.enabled = true;
}
// On receiving a `PING` message from the server, we automatically respond with // On receiving a `PING` message from the server, we automatically respond with
// the appropriate `PONG` message to keep the connection alive for transport. // the appropriate `PONG` message to keep the connection alive for transport.
Command::PING(ref data, _) => { Command::PING(ref data, _) => {
@ -109,9 +116,11 @@ impl Future for Pinger {
} }
if let Poll::Ready(_) = Pin::new(&mut self.as_mut().ping_interval).poll_next(cx) { if let Poll::Ready(_) = Pin::new(&mut self.as_mut().ping_interval).poll_next(cx) {
if self.enabled {
self.as_mut().send_ping()?; self.as_mut().send_ping()?;
self.as_mut().set_deadline(); self.as_mut().set_deadline();
} }
}
Poll::Pending Poll::Pending
} }