Revision: 7764 https://osdn.net/projects/ttssh2/scm/svn/commits/7764 Author: yutakapon Date: 2019-06-12 21:07:34 +0900 (Wed, 12 Jun 2019) Log Message: ----------- WSAAsyncSelect()でメッセージ通知を抑止する方法を止めて、bufchainの上限と下限を見て、 recv()の一時停止および再開をするようにした。 チケット #39297 Ticket Links: ------------ https://osdn.net/projects/ttssh2/tracker/detail/39297 Modified Paths: -------------- branches/portfwd_memleak/ttssh2/ttxssh/fwd.c branches/portfwd_memleak/ttssh2/ttxssh/fwd.h branches/portfwd_memleak/ttssh2/ttxssh/ssh.c branches/portfwd_memleak/ttssh2/ttxssh/ssh.h -------------- next part -------------- Modified: branches/portfwd_memleak/ttssh2/ttxssh/fwd.c =================================================================== --- branches/portfwd_memleak/ttssh2/ttxssh/fwd.c 2019-06-12 11:07:19 UTC (rev 7763) +++ branches/portfwd_memleak/ttssh2/ttxssh/fwd.c 2019-06-12 12:07:34 UTC (rev 7764) @@ -679,9 +679,21 @@ while (channel->local_socket != INVALID_SOCKET) { char buf[CHANNEL_READ_BUF_SIZE]; - int amount = recv(channel->local_socket, buf, sizeof(buf), 0); + int amount; int err; + // recv\x82̈ꎞ\x92\xE2\x8E~\x92\x86\x82Ȃ\xE7\x82A\x89\xBD\x82\xE0\x82\xB9\x82\xB8\x82ɖ߂\xE9\x81B + if (SSHv2(pvar)) { + Channel_t* c = ssh2_local_channel_lookup(channel_num); + if (c->bufchain_recv_suspended) { + logprintf(LOG_LEVEL_NOTICE, "%s: channel=%d recv was skipped for flow control", + __FUNCTION__, channel_num); + return; + } + } + + amount = recv(channel->local_socket, buf, sizeof(buf), 0); + // X\x83T\x81[\x83o\x82\xA9\x82\xE7\x82̃f\x81[\x83^\x8E\xF3\x90M\x82\xAA\x82\xA0\x82\xEA\x82A\x83m\x83\x93\x83u\x83\x8D\x83b\x83L\x83\x93\x83O\x83\x82\x81[\x83h\x82Ń\\x83P\x83b\x83g\x8E\xF3\x90M\x82\xF0\x8Ds\x82\xA2\x81A // SSH\x83T\x81[\x83o\x82\xCCX\x83A\x83v\x83\x8A\x83P\x81[\x83V\x83\x87\x83\x93\x82֑\x97\x90M\x82\xB7\x82\xE9\x81B //OutputDebugPrintf("%s: recv %d\n", __FUNCTION__, amount); @@ -740,10 +752,10 @@ } } -// local connection(WinSock)\x82\xA9\x82\xE7\x82̃\x81\x83b\x83Z\x81[\x83W\x92ʒm\x82\xF0\x90\xE8\x91ւ\xA6\x82\xE9 +// local connection\x82̎\xF3\x90M\x82̒\xE2\x8E~\x82\xA8\x82\xE6\x82эĊJ\x82̔\xBB\x92f\x82\xF0\x8Ds\x82\xA4 // -// notify: TRUE \x83\x81\x83b\x83Z\x81[\x83W\x82\xF0\x92ʒm\x82\xB7\x82\xE9 -// FALSE \x83\x81\x83b\x83Z\x81[\x83W\x82\xF0\x92ʒm\x82\xB5\x82Ȃ\xA2 +// notify: TRUE recv\x82\xF0\x8DĊJ\x82\xB7\x82\xE9 +// FALSE recv\x82\xF0\x92\xE2\x8E~\x82\xB7\x82\xE9 // // [\x96ړI] // remote_window\x82ɋ\xAA\x82Ȃ\xA2\x8Fꍇ\x82͒ʒm\x83I\x83t\x82Ƃ\xB5\x81A\x8B\xAA\x82ł\xAB\x82\xBD\x8Fꍇ\x82\xCD @@ -757,49 +769,43 @@ { int channel_num; FWDChannel* channel; - int ret; + int changed = 0; channel_num = c->local_num; channel = pvar->fwd_state.channels + channel_num; if (notify) { - // \x83\x81\x83b\x83Z\x81[\x83W\x92ʒm\x82\xF0\x97L\x8C\xF8\x82ɂ\xB7\x82\xE9 - ret = WSAAsyncSelect( - channel->local_socket, - make_accept_wnd(pvar), WM_SOCK_IO, - FD_CONNECT | FD_READ | FD_CLOSE | FD_WRITE - ); - } else { - /* \x83\x81\x83b\x83Z\x81[\x83W\x92ʒm\x82\xF8\x82ɂ\xB7\x82\xE9\x81B - \x96\xB3\x8C\xF8\x8C\xE3\x81A\x83L\x83\x85\x81[\x82ɗ\xAD\x82܂\xC1\x82Ă\xA2\x82郁\x83b\x83Z\x81[\x83W\x82\xAA\x91\x97\x82\xE7\x82\xEA\x82Ă\xAD\x82邱\x82Ƃ\xAA\x82\xA0\x82\xE9\x82̂Œ\x8D\x88ӁB - - https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsaasyncselect - To cancel all notification indicating that Windows Sockets should send no further - messages related to network events on the socket, lEvent is set to zero. + // recv\x82\xF0\x8DĊJ\x82\xB7\x82邩\x94\xBB\x92f\x82\xB7\x82\xE9 + if (c->bufchain_amount <= FWD_LOW_WATER_MARK) { + // \x89\xBA\x8C\xC0\x82\xF0\x89\xBA\x89\xF1\x82\xC1\x82\xBD\x82̂ōĊJ + c->bufchain_recv_suspended = FALSE; - Although WSAAsyncSelect immediately disables event message posting for the socket - in this instance, it is possible that messages could be waiting in the application - message queue. Therefore, the application must be prepared to receive network - event messages even after cancellation. - */ - ret = WSAAsyncSelect( - channel->local_socket, - make_accept_wnd(pvar), - 0, 0); - } + // \x82\xB1\x82\xB1\x82ōĊJ\x82̃\x81\x83b\x83Z\x81[\x83W\x82\xF0\x94\xF2\x82\xB7 + PostMessage(pvar->fwd_state.accept_wnd, WM_SOCK_IO, + (WPARAM)channel->local_socket, + MAKEWPARAM(FD_READ, 0) + ); - if (ret != 0) { - logprintf(LOG_LEVEL_ERROR, "%s: Can not change local channel(%d) WinSock notification(%d).", - __FUNCTION__, channel_num, notify); + changed = 1; + } + + } else { + // recv\x82\xF0\x92\xE2\x8E~\x82\xB7\x82邩\x94\xBB\x92f\x82\xB7\x82\xE9 + if (c->bufchain_amount >= FWD_HIGH_WATER_MARK) { + // \x8F\xE3\x8C\xC0\x82\xA6\x82\xBD\x82̂Œ\xE2\x8E~ + c->bufchain_recv_suspended = TRUE; + changed = 1; + } } - else { - logprintf(LOG_LEVEL_NOTICE, - "%s: Local channel#%d WinSock notification has been `%s' for flow control(buffer size %lu).", - __FUNCTION__, channel_num, - notify ? "enabled" : "disabled", - c->bufchain_amount); - } + logprintf(LOG_LEVEL_NOTICE, + "%s: Local channel#%d recv has been `%s' for flow control(buffer size %lu, recv %s).", + __FUNCTION__, channel_num, + c->bufchain_recv_suspended ? "disabled" : "enabled", + c->bufchain_amount, + changed ? "changed" : "" + ); + } Modified: branches/portfwd_memleak/ttssh2/ttxssh/fwd.h =================================================================== --- branches/portfwd_memleak/ttssh2/ttxssh/fwd.h 2019-06-12 11:07:19 UTC (rev 7763) +++ branches/portfwd_memleak/ttssh2/ttxssh/fwd.h 2019-06-12 12:07:34 UTC (rev 7764) @@ -35,6 +35,11 @@ #ifndef __FWD_H #define __FWD_H +// \x83|\x81[\x83g\x93]\x91\x97\x82ɂ\xA8\x82\xAF\x82\xE9\x83t\x83\x8D\x81[\x90\xA7\x8C\xE4\x82\xCC臒l +// \x93K\x97p\x90\xE6 Channel_t.bufchain_amount +#define FWD_HIGH_WATER_MARK (1 * 1024 * 1024) // 1MB +#define FWD_LOW_WATER_MARK (0) // 0MB + #define FWD_REMOTE_CONNECTED 0x01 #define FWD_LOCAL_CONNECTED 0x02 #define FWD_BOTH_CONNECTED (FWD_REMOTE_CONNECTED | FWD_LOCAL_CONNECTED) Modified: branches/portfwd_memleak/ttssh2/ttxssh/ssh.c =================================================================== --- branches/portfwd_memleak/ttssh2/ttxssh/ssh.c 2019-06-12 11:07:19 UTC (rev 7763) +++ branches/portfwd_memleak/ttssh2/ttxssh/ssh.c 2019-06-12 12:07:34 UTC (rev 7764) @@ -213,6 +213,8 @@ c->type = type; c->local_num = local_num; // alloc_channel()\x82̕Ԓl\x82\xF0\x95ۑ\xB6\x82\xB5\x82Ă\xA8\x82\xAD c->bufchain = NULL; + c->bufchain_amount = 0; + c->bufchain_recv_suspended = FALSE; if (type == TYPE_SCP) { c->scp.state = SCP_INIT; c->scp.progress_window = NULL; @@ -390,7 +392,7 @@ // SSH1\x82ŊǗ\x9D\x82\xB5\x82Ă\xA2\x82\xE9channel\x8D\\x91\xA2\x91̂\xA9\x82\xE7\x81ASSH2\x8C\xFC\x82\xAF\x82\xCCChannel_t\x82֕ϊ\xB7\x82\xB7\x82\xE9\x81B // TODO: \x8F\xAB\x97\x88\x93I\x82ɂ̓`\x83\x83\x83l\x83\x8B\x8D\\x91\xA2\x91̂\xCD1\x82ɓ\x9D\x8D\x87\x82\xB7\x82\xE9\x81B // (2005.6.12 yutaka) -static Channel_t *ssh2_local_channel_lookup(int local_num) +Channel_t *ssh2_local_channel_lookup(int local_num) { int i; Channel_t *c; Modified: branches/portfwd_memleak/ttssh2/ttxssh/ssh.h =================================================================== --- branches/portfwd_memleak/ttssh2/ttxssh/ssh.h 2019-06-12 11:07:19 UTC (rev 7763) +++ branches/portfwd_memleak/ttssh2/ttxssh/ssh.h 2019-06-12 12:07:34 UTC (rev 7764) @@ -882,6 +882,7 @@ int local_num; bufchain_t *bufchain; unsigned long bufchain_amount; + BOOL bufchain_recv_suspended; scp_t scp; buffer_t *agent_msg; int agent_request_len; @@ -893,6 +894,7 @@ unsigned char *begin_send_packet(PTInstVar pvar, int type, int len); void finish_send_packet_special(PTInstVar pvar, int skip_compress); void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char *buf, unsigned int buflen, int retry); +Channel_t* ssh2_local_channel_lookup(int local_num); #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0) #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))