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
-
category:port-update
难度 2/5 1-3 小时 新手友好度 66/100
维护者通常 2 天内回复
-
emerge failure MARK mark-unstable media-kit
难度 2/5 1-3 小时 新手友好度 82/100
macaroni-os/mark-issues#834 ·
-
难度 2/5 1-3 小时 新手友好度 76/100
-
难度 1/5 1 小时以内 新手友好度 93/100
webarkit/WebARKitLib#107 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复