SSH2 ダイナミックポートフォワーディングを使うと落ちる
r7771 から発生
ポート転送がどう動いているのか調べました。
Channel_t channels ... ssh.c にあるほう・SSH2 のやつ pvar->fwd_state.channels ... SSH1 からあるやつ・転送専用? pvar->fwd_state.requests 1. SSH 接続 ssh2_channel_new(-1) channels[0] self_id: 0 local_num: -1 type: SHELL 2. 転送ポート listen request = pvar->fwd_state.requests + request_num request->listening_sockets socket() bind() WSAAsyncSelect() listen() 3-1. FWD_LOCAL_TO_REMOTE accept_wnd_proc() ... WM_SOCK_ACCEPT request_num = find_request_num((SOCKET)wParam) listening_socket_num = find_listening_socket_num(request_num, (SOCKET)wParam) accept_local_connection(request_num, listening_socket_num) channel_num = alloc_channel(request_num) ... channel_num は pvar->fwd_state.channels のほう pvar->fwd_state.channels に追加 SSH_open_channel(channel_num) ssh2_channel_new(local_channel_num) channels[found]->local_num = local_channel_num ... 空きチャネルを見つけて使う accept_wnd_proc() ... FD_READ channel_num = find_channel_num((SOCKET) wParam) read_local_connection(channel_num) /* r7771 追加 */ c = ssh2_local_channel_lookup(channel_num) c が受信にストップをかけているか確認する /* r7771 追加ここまで */ recv() SSH_channel_send(channel_num) 3-2. FWD_LOCAL_DYNAMIC accept_wnd_proc() ... WM_SOCK_ACCEPT request_num = find_request_num((SOCKET)wParam) listening_socket_num = find_listening_socket_num(request_num, (SOCKET)wParam) accept_local_connection(request_num, listening_socket_num) channel_num = alloc_channel(request_num) ... channel_num は pvar->fwd_state.channels のほう pvar->fwd_state.channels に追加 // SSH_open_channel() を呼ばない accept_wnd_proc() ... FD_READ channel_num = find_channel_num((SOCKET) wParam) read_local_connection(channel_num) /* r7771 追加 */ c = ssh2_local_channel_lookup(channel_num) // channel_num が保存されていないので見つけられない c が受信ストップ中か確認する /* r7771 追加ここまで */ recv() SSH_channel_send(channel_num) channel->filter(channel->filter_closure) SOCKS_filter(closure) ... FWD_FILTER_FROM_CLIENT parse_client_request(closure) parse_socks5_init_request(closure) SSH_open_channel(closure->channel_num) ssh2_channel_new(local_channel_num) channels[found]->local_num = local_channel_num ... 空きチャネルを見つけて使う
修正ありがとうございます。
ソースは追えていませんが、trunk/4-stable どちらもうまく動いているようです。
4-stable, trunk ともに現象の再現を確認。4.x, 5.x 両方で対応が必要
4.104 (r7771) から発生
fwd.c
static void read_local_connection(PTInstVar pvar, int channel_num) の
問題についての言及を観測した地点
再現手順