ConnectionInfo.SendTimeout — configurable socket send timeout to prevent indefinite hangs on TCP zero-window stalls
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 70/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- csharp
- Lĩnh vực
- networking
Hướng nghiên cứu
Bắt đầu với ConnectionInfo.cs để xem xét việc xác thực timeout hiện có, sau đó kiểm tra thiết lập socket trong cả Connect() và ConnectAsync() của Session.cs. Thêm hành vi send-timeout có thể cấu hình được mô tả trong issue, giữ nguyên giá trị mặc định vô hạn, và xác minh rằng một lần gửi bị treo sẽ hết thời gian chờ trong khi các kết nối hiện có vẫn giữ nguyên hành vi của chúng.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Problem
When uploading files over SFTP to a slow or unresponsive server, Session.SendPacket() can hang indefinitely with no way to recover.
The root cause is in SocketAbstraction.Send():
var bytesSent = socket.Send(data, offset + totalBytesSent, totalBytesToSend - totalBytesSent, SocketFlags.None);
socket.Send() is a blocking call and Socket.SendTimeout is never set, so it defaults to 0 (infinite). When the server's TCP receive window drops to zero (the server is alive but not consuming data), the OS
holds the call open indefinitely — no exception, no return. The standard TCP dead-peer timeout (several minutes) only applies when the server is completely unreachable, not in the zero-window scenario.
This is distinct from the channel-level window wait in Channel.cs, which already has a 30-second timeout via ConnectionInfo.Timeout. That protection only covers the SSH protocol layer; it never gets a chance
to fire because execution is stuck in socket.Send() first.
OperationTimeout (on SftpClient) similarly cannot help — it guards the wait for an SFTP protocol response after a packet has been sent, not the send itself.
Proposed fix
Add SendTimeout to ConnectionInfo (default Timeout.InfiniteTimeSpan to preserve existing behaviour) and apply it to the socket immediately after connection:
// ConnectionInfo.cs
private TimeSpan _sendTimeout = System.Threading.Timeout.InfiniteTimeSpan;
public TimeSpan SendTimeout
{
get => _sendTimeout;
set
{
value.EnsureValidTimeout(nameof(SendTimeout));
_sendTimeout = value;
}
}
// Session.cs — both Connect() and ConnectAsync() paths
_socket = _serviceFactory.CreateConnector(ConnectionInfo, _socketFactory)
.Connect(ConnectionInfo);
_socket.SendTimeout = ConnectionInfo.SendTimeout.AsTimeout();
When SendTimeout elapses, socket.Send() throws SocketException with SocketError.TimedOut, which propagates out of SendPacket() and terminates the session normally.
Notes
- Default is infinite — no behaviour change for existing users
- The timeout is a stall detector, not a total-transfer budget: it resets on every successful send call, so large files over slow-but-healthy connections are not affected
- Applies to all SSH traffic (not just SFTP), which is correct — a stalled send on any packet type means the session is broken
- Ngôn ngữ chính
- C#
- Star
- 4.4k
- Fork
- 990
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của sshnet/SSH.NET
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 55/100
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 45/100
-
ShellStream.Expect over-discards on undecodable bytes, driving ArrayBuffer.ActiveLength negativeĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 68/100
Tất cả issue của sshnet/SSH.NET
Issue tương tự
-
Python: Bug: split_plaintext_paragraph / split_markdown_paragraph can return a chunk larger than max_tokensCó thể đã có người làm @xThreeh đã nhận hôm nay. Đang mởpython triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
microsoft/semantic-kernel#14566 ·
Maintainer thường phản hồi trong vòng 4 ngày
-
triage
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 82/100
rjmurillo/moq.analyzers#1384 ·
-
Variables passed to Compensated are not set on the routing slipCó thể làm lại được Pull request cho issue này đã bị đóng mà không được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
MassTransit/MassTransit#6249 ·
-
security
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Sendspin/sendspin-dotnet#339 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
owasp-dep-scan/dosai#79 ·
Maintainer thường phản hồi trong vòng 1 ngày