Window adjustment during channel read operation
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 5/5
- 預估耗時
- 一週以上
- 新手友好度
- 25/100
- Issue 類型
- 功能
- 描述清晰度
- 需要釐清
- 活躍度
- 停滯
- 技術堆疊
- c
- 領域
- api, networking
研究方向
Start by reading the mentioned _libssh2_channel_read and libssh2_channel_read_ex paths, focusing on when window adjustment returns LIBSSH2_ERROR_EAGAIN. The issue presents several possible solutions but does not choose one, so first determine the intended behavior and its effect on callers. Done means the behavior or API is decided, documented, and covered by tests for the relevant read and window-adjustment cases.
由索引模型根據 Issue 內容生成。
描述
Hello,
I am not exactly sure that this is a bug report, a misuse on my part, or a design flaw.
I use libssh2 with an async networking stack, and I have to emulate the behavior of send/recv that libssh2 relies on for it to work (for those interested, it is Apple's Network stack, and the NWConnection API). This works almost all of the time, but I have found that in some very odd circumstances, one of my packets never arrives to the other end, and the problem is a combination of my emulation, but also on libssh2 design.
Since libssh2 does not provide a mechanism to know when there is data available (the poll API while present, is flagged as deprecated and having corner cases) I resort to "poking" all my active channels when new data comes from the network in the form of calling libssh2_channel_read_ex on both the standard output and the auxiliary output. These APIs, rather than returning "Hey no data was available" when no data is available, return LIBSSH2_ERROR_EAGAIN.
In general, my stack deals with LIBSSH2_ERROR_EAGAIN by retrying those operations, but in this case, you really should just move on, because no more data might be coming at all. The remote end might genuinely not have anything to return.
The challenge is that libssh2_channel_read_ex might decide internally that the SSH read window is not big enough, and send a packet to adjust the window size (it is actually _libssh2_channel_read that does this, an internal function). And it will return dutifully a LIBSSH2_ERROR_EAGAIN, which will be propagated back to the user - but as a user of libssh2_channel_read_ex I really have no way of knowing if this return code means "Please retry, I am negotiating a larger window", or "No more data is available, carry on".
The side effect of not retrying the operation is that my emulation for send/recv on top of an async stack will reply to the next call from the networking stack that tries to write with the results from the previously queued operation, rather than queuing the next operation - and this is where I experience the packet loss. Without retrying the original libssh2_channel_read_ex that would trigger the window adjustment to match the retry, I end up with a broken state.
I think there are a range of possible solutions here:
(a) Perhaps I do not understand what good window and buffer sizes are. I have tried 2 megs, 1 meg, 8 meg windows, but they seem to all be adjusted dynamically. I have tried 1k to 32k buffer sizes. They all lead to scenarios where the window is still renegotiated in the middle of a read.
(b) Perhaps window changes are not necessary - I am not an expert on the protocol, but perhaps the window size negotiation is a nice-to-have, rather than a must-have, and I could just comment out the code that does the window negotiation inside libssh2_channel_read_ex
(c) If window adjustment is mandatory, perhaps libssh2 should surface an API that could be probed for both he heuristic used, and the new size set: libssh2_channel_window_get_heuristic (int buflen) and libssh2_channel_set_acceptable_window_size (int buflen). The current implemented heuristic is remote.window_size < (remote.window_size_initial / 4 * 3 + bufSize), and the adjusted version is remote.window_size_initial + buflen - remote.window_size. I suggest exposing those APIs for the sake of exposing the policy, so applications could react to this.
(d) Perhaps libssh2_channel_read_ex should return a specific code to signal that there is no data available, rather than LIBSSH2_ERROR_EAGAIN
- 主要語言
- C
- 星號
- 1.6k
- 分支
- 646
- PR 合併指標
- 30 天內沒有已合併 PR
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 沒有貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
libssh2/libssh2 的其他 Issue
-
難度 2/5 1-3 小時 新手友好度 74/100
libssh2/libssh2#2676 · 1 則留言 ·
維護者通常 1 天內回覆
-
AEAD ciphers (chacha20-poly1305, AES-GCM) leak 16 bytes of uninitialized memory per outgoing encrypted packet可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉memory-leak
難度 2/5 1-3 小時 新手友好度 85/100
libssh2/libssh2#2023 · 5 則留言 ·
維護者通常 1 天內回覆
-
documentation
難度 4/5 3-5 天 新手友好度 48/100
libssh2/libssh2#2597 · 2 則留言 ·
維護者通常 1 天內回覆
-
Q&A
難度 4/5 3-5 天 新手友好度 45/100
維護者通常 1 天內回覆
-
難度 4/5 3-5 天 新手友好度 35/100
libssh2/libssh2#1925 · 13 則留言 · 32 個 reaction ·
維護者通常 1 天內回覆
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 76/100
polhenarejos/pico-fido#302 ·
-
難度 2/5 1-3 小時 新手友好度 67/100
espressif/esp-vision#16 · 1 則留言 ·
-
難度 2/5 1-3 小時 新手友好度 74/100
libsdl-org/SDL#16577 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 66/100
維護者通常 1 天內回覆
-
halt_error adds a trailing newline for non-string input, contrary to the manual可能已有人在做 @Huang-404-Q 今天認領。 未關閉
難度 1/5 1-3 小時 新手友好度 88/100
維護者通常 2 天內回覆