[Ttssh2-commit] [7764] WSAAsyncSelect()でメッセージ通知を抑止する方法を止めて、bufchainの上限と下限を見て、

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2019年 6月 12日 (水) 21:07:34 JST


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\x82΁A\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\x82΁A\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))


Ttssh2-commit メーリングリストの案内
Back to archive index