Replies: 3 comments
-
|
It is hard to investigate without the This is the result from my machine; however, it is relatively slower. |
Beta Was this translation helpful? Give feedback.
-
|
It seems I can't reproduce the issue anymore. Yesterday, I attempted a packet capture and found that packets suddenly stopped being sent. Capturing packets on the iperf3 server side also suggested that the server itself was the one that stopped sending traffic. However, I haven't been able to reproduce it today. |
Beta Was this translation helpful? Give feedback.
-
|
I think I've pinpointed the issue. It stems from this piece of code: releasing the lock immediately after retrieving the state. The main loop thread might concurrently receive an ACK and issue a notification/signal (wake-up call), causing both sides to enter a waiting state. The write operation needs the main loop to wake it up, while this side needs to receive the ACK, but is currently unable to send data. let (state, send_window, is_full) = {
let tcb = self.tcb.lock().unwrap();
let state = tcb.get_state();
(state, tcb.get_send_window(), tcb.is_send_buffer_full())
};
if state == TcpState::Closed {
self.shutdown.lock().unwrap().ready();
self.read_notify.lock().unwrap().take().map(|w| w.wake_by_ref()).unwrap_or(());
return Poll::Ready(Err(std::io::Error::new(BrokenPipe, "TCP connection closed")));
}
if send_window == 0 || is_full {
self.write_notify.lock().unwrap().replace(cx.waker().clone());
let info = format!("current send window: {send_window}, send buffer full: {is_full}");
log::trace!("{nt} {state:?}: [poll_write] {info}, waiting for the other side to send ACK...");
return Poll::Pending;
}I added a log. When the problem occurred, inflight was 0, but the subsequent trigger sent buffer is full. self.inflight_packets.retain(|_, p| ack < p.seq + p.payload.len() as u32);
log::info!("Updated inflight packets after ACK: {}", self.inflight_packets.len());
...
self.write_notify.lock().unwrap().replace(cx.waker().clone());
let info = format!("current send window: {send_window}, send buffer full: {is_full}");
log::trace!("{nt} {state:?}: [poll_write] {info}, waiting for the other side to send ACK...");
// 添加日志:明确Pending原因
log::warn!("{nt} {state:?}: [poll_write] buffer full, returning Pending - potential deadlock if no ACK received");
return Poll::Pending; |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm migrating my project's networking layer from
smoltcptoipstackbecause its API is a better fit for my application's design.I am currently testing my implementation, which is based on the examples/tun code. However, I've run into an intermittent issue. During large data transfers, the connection sometimes stalls; the speed will suddenly drop to 0 KB/s and never recover. This doesn't happen on every run and may take several attempts to reproduce.
I am quite new to low-level TCP/IP stack development, so I'm not entirely sure how to best debug this. Using Wireshark to analyze the traffic, what specific packets should I look for that might point to the root cause? For example:
Packets indicating TCP Zero Window issues?
A high number of TCP Retransmissions before the stall?
Any advice on what to focus on in the packet capture would be greatly appreciated.
Beta Was this translation helpful? Give feedback.
All reactions