Skip to content

Commit 7b41425

Browse files
committed
fix: save peer address for LoggingStream early
Socket may lose peer address when it is disconnected from the server side. In this case debug_assert! failed for me when running the core in debug mode on desktop. To avoid the case of peer_addr not being available, we now store it when LoggingStream is created.
1 parent 2c7d51f commit 7b41425

2 files changed

Lines changed: 21 additions & 20 deletions

File tree

src/imap/client.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ impl Client {
209209
let tcp_stream = connect_tcp_inner(addr).await?;
210210
let account_id = context.get_id();
211211
let events = context.events.clone();
212-
let logging_stream = LoggingStream::new(tcp_stream, account_id, events);
212+
let logging_stream = LoggingStream::new(tcp_stream, account_id, events)?;
213213
let tls_stream = wrap_tls(strict_tls, hostname, alpn(addr.port()), logging_stream).await?;
214214
let buffered_stream = BufWriter::new(tls_stream);
215215
let session_stream: Box<dyn SessionStream> = Box::new(buffered_stream);
@@ -225,7 +225,7 @@ impl Client {
225225
let tcp_stream = connect_tcp_inner(addr).await?;
226226
let account_id = context.get_id();
227227
let events = context.events.clone();
228-
let logging_stream = LoggingStream::new(tcp_stream, account_id, events);
228+
let logging_stream = LoggingStream::new(tcp_stream, account_id, events)?;
229229
let buffered_stream = BufWriter::new(logging_stream);
230230
let session_stream: Box<dyn SessionStream> = Box::new(buffered_stream);
231231
let mut client = Client::new(session_stream);
@@ -246,7 +246,7 @@ impl Client {
246246

247247
let account_id = context.get_id();
248248
let events = context.events.clone();
249-
let tcp_stream = LoggingStream::new(tcp_stream, account_id, events);
249+
let tcp_stream = LoggingStream::new(tcp_stream, account_id, events)?;
250250

251251
// Run STARTTLS command and convert the client back into a stream.
252252
let buffered_tcp_stream = BufWriter::new(tcp_stream);

src/log/stream.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::pin::Pin;
1010
use std::task::{Context, Poll};
1111
use std::time::Duration;
1212

13-
use anyhow::Result;
13+
use anyhow::{Context as _, Result};
1414
use pin_project::pin_project;
1515

1616
use crate::events::{Event, EventType, Events};
@@ -51,16 +51,26 @@ pub(crate) struct LoggingStream<S: SessionStream> {
5151

5252
/// Metrics for this stream.
5353
metrics: Metrics,
54+
55+
/// Peer address at the time of creation.
56+
///
57+
/// Socket may become disconnected later,
58+
/// so we save it when `LoggingStream` is created.
59+
peer_addr: SocketAddr,
5460
}
5561

5662
impl<S: SessionStream> LoggingStream<S> {
57-
pub fn new(inner: S, account_id: u32, events: Events) -> Self {
58-
Self {
63+
pub fn new(inner: S, account_id: u32, events: Events) -> Result<Self> {
64+
let peer_addr: SocketAddr = inner
65+
.peer_addr()
66+
.context("Attempt to create LoggingStream over an unconnected stream")?;
67+
Ok(Self {
5968
inner,
6069
account_id,
6170
events,
6271
metrics: Metrics::new(),
63-
}
72+
peer_addr,
73+
})
6474
}
6575
}
6676

@@ -71,25 +81,16 @@ impl<S: SessionStream> AsyncRead for LoggingStream<S> {
7181
buf: &mut ReadBuf<'_>,
7282
) -> Poll<std::io::Result<()>> {
7383
let this = self.project();
74-
let peer_addr = this.inner.peer_addr();
7584
let old_remaining = buf.remaining();
7685

7786
let res = this.inner.poll_read(cx, buf);
7887

7988
if let Poll::Ready(Err(ref err)) = res {
80-
debug_assert!(
81-
peer_addr.is_ok(),
82-
"Logging stream should be created over a bound socket"
89+
let peer_addr = this.peer_addr;
90+
let log_message = format!(
91+
"Read error on stream {peer_addr:?} after reading {} and writing {} bytes: {err}.",
92+
this.metrics.total_read, this.metrics.total_written
8393
);
84-
let log_message = match peer_addr {
85-
Ok(peer_addr) => format!(
86-
"Read error on stream {peer_addr:?} after reading {} and writing {} bytes: {err}.",
87-
this.metrics.total_read, this.metrics.total_written
88-
),
89-
Err(_) => {
90-
format!("Read error on a stream that does not have a peer address: {err}.")
91-
}
92-
};
9394
this.events.emit(Event {
9495
id: *this.account_id,
9596
typ: EventType::Warning(log_message),

0 commit comments

Comments
 (0)