[ttssh2-commit] [10959] Merge remote-tracking branch 'remotes/origin/scp_flowctrl'

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2023年 10月 8日 (日) 02:40:26 JST


Revision: 10959
          https://osdn.net/projects/ttssh2/scm/svn/commits/10959
Author:   zmatsuo
Date:     2023-10-08 02:40:26 +0900 (Sun, 08 Oct 2023)
Log Message:
-----------
Merge remote-tracking branch 'remotes/origin/scp_flowctrl'

- ビルドが通る程度に修正、テストはしていない

Modified Paths:
--------------
    trunk/ttssh2/ttxssh/pkt.c
    trunk/ttssh2/ttxssh/ssh.c
    trunk/ttssh2/ttxssh/ssh.h
    trunk/ttssh2/ttxssh/ttxssh.h

-------------- next part --------------
Modified: trunk/ttssh2/ttxssh/pkt.c
===================================================================
--- trunk/ttssh2/ttxssh/pkt.c	2023-10-07 17:40:16 UTC (rev 10958)
+++ trunk/ttssh2/ttxssh/pkt.c	2023-10-07 17:40:26 UTC (rev 10959)
@@ -318,6 +318,13 @@
 			// \x83p\x83P\x83b\x83g\x82̎\xF3\x90M
 			int amount_read;
 
+			// SCP\x83t\x83@\x83C\x83\x8B\x8E\xF3\x90M\x8F\x88\x97\x9D\x82\xF0\x88ꎞ\x92\xE2\x8E~\x92\x86\x82Ȃ\xE7\x82΁Arecv()\x82\xF0\x82\xB5\x82Ȃ\xA2\x81B
+			if (pvar->recv_suspended) {
+				// \x82\xBB\x82\xEA\x82܂łɎ\xF3\x90M\x82\xB5\x82\xBD\x83f\x81[\x83^\x83T\x83C\x83Y\x82\xF0Tera Term\x91\xA4\x82ɕԂ\xB7\x81B
+				return amount_in_buf;
+
+			}
+
 			amount_read = recv_data(pvar, READAMOUNT);
 
 			if (amount_read == SOCKET_ERROR) {

Modified: trunk/ttssh2/ttxssh/ssh.c
===================================================================
--- trunk/ttssh2/ttxssh/ssh.c	2023-10-07 17:40:16 UTC (rev 10958)
+++ trunk/ttssh2/ttxssh/ssh.c	2023-10-07 17:40:26 UTC (rev 10959)
@@ -148,12 +148,13 @@
 static void start_ssh_heartbeat_thread(PTInstVar pvar);
 void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c);
 static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, int local_channel_num, unsigned char *data, unsigned int buflen);
-static void ssh2_scp_get_packetlist(Channel_t *c, unsigned char **buf, unsigned int *buflen);
-static void ssh2_scp_free_packetlist(Channel_t *c);
+static void ssh2_scp_get_packetlist(PTInstVar pvar, Channel_t *c, unsigned char **buf, unsigned int *buflen);
+static void ssh2_scp_free_packetlist(PTInstVar pvar, Channel_t *c);
 static void get_window_pixel_size(PTInstVar pvar, int *x, int *y);
 static void do_SSH2_dispatch_setup_for_transfer(PTInstVar pvar);
 static void ssh2_prep_userauth(PTInstVar pvar);
 static void ssh2_send_newkeys(PTInstVar pvar);
+static void ssh2_scp_recv_unblocked(PTInstVar pvar);
 
 // \x83}\x83N\x83\x8D
 #define remained_payload(pvar) ((pvar)->ssh_state.payload + payload_current_offset(pvar))
@@ -326,6 +327,7 @@
 {
 	bufchain_t *ch, *ptr;
 	enum scp_state prev_state;
+	PTInstVar pvar;
 
 	ch = c->bufchain;
 	while (ch) {
@@ -373,6 +375,8 @@
 			ssh2_scp_free_packetlist(c);
 
 		g_scp_sending = FALSE;
+		pvar = c->scp.pvar;
+		ssh2_scp_free_packetlist(pvar, c);
 	}
 	if (c->type == TYPE_AGENT) {
 		buffer_free(c->agent_msg);
@@ -8100,6 +8104,10 @@
 			{
 			scp_dlg_parm_t *parm = (scp_dlg_parm_t *)wp;
 
+			// SCP\x82̎\xF3\x90M\x8F\x88\x97\x9D\x82𒆒f\x82\xB5\x82\xBD\x8Fꍇ\x82ɂ\xE0\x81Arecv()\x82̃u\x83\x8D\x83b\x83N\x82\xF0\x89\xF0\x8F\x9C\x82\xB7\x82\xE9\x81B
+			// \x82\xB1\x82\xEA\x82\xF0\x82\xE2\x82\xE7\x82Ȃ\xA2\x82ƁATera Term\x82\xAA\x8Cł܂\xC1\x82\xBD\x82܂܂ɂȂ\xC1\x82Ă\xB5\x82܂\xA4\x81B
+			ssh2_scp_recv_unblocked(parm->pvar);
+
 			ssh2_channel_send_close(parm->pvar, parm->c);
 			}
 			return TRUE;
@@ -8405,7 +8413,7 @@
 		if (is_canceled_window(hWnd))
 			goto cancel_abort;
 
-		ssh2_scp_get_packetlist(c, &data, &buflen);
+		ssh2_scp_get_packetlist(pvar, c, &data, &buflen);
 		if (data && buflen) {
 			msg.message = WM_RECEIVING_FILE;
 
@@ -8487,8 +8495,22 @@
 	return 0;
 }
 
-static void ssh2_scp_add_packetlist(Channel_t *c, unsigned char *buf, unsigned int buflen)
+// SCP\x83t\x83@\x83C\x83\x8B\x8E\xF3\x90M\x8F\x88\x97\x9D\x92\x86\x82\xC9 recv \x82\xF0\x83u\x83\x8D\x83b\x83N\x82\xB5\x82Ă\xA2\x82\xE9\x8Fꍇ\x82́A\x83u\x83\x8D\x83b\x83N\x82\xF0\x89\xF0\x8F\x9C\x82\xB7\x82\xE9\x81B
+static void ssh2_scp_recv_unblocked(PTInstVar pvar)
 {
+	// \x83u\x83\x8D\x83b\x83N\x82\xB5\x82Ă\xA2\x82\xE9\x8Fꍇ
+	if (pvar->recv_suspended) {
+		// recv()\x82̃u\x83\x8D\x83b\x83N\x82\xF0\x89\xF0\x8F\x9C\x82\xB7\x82\xE9\x81B
+		pvar->recv_suspended = FALSE;
+		// FD_READ\x83\x81\x83b\x83Z\x81[\x83W\x82𓊂\xB0\x82\xC4 recv() \x82̍ĊJ\x82𑣂\xB7\x81B
+		PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY, pvar->socket, MAKELPARAM(FD_READ, 0));
+	}
+}
+
+// SSH\x83T\x81[\x83o\x82\xA9\x82瑗\x82\xE7\x82\xEA\x82Ă\xAB\x82\xBD\x83t\x83@\x83C\x83\x8B\x82̃f\x81[\x83^\x82\xF0\x83\x8A\x83X\x83g\x82ɂ‚Ȃ\xAE\x81B
+// \x83\x8A\x83X\x83g\x82̎\xE6\x82\xE8\x8Fo\x82\xB5\x82\xCD ssh_scp_receive_thread \x83X\x83\x8C\x83b\x83h\x82ōs\x82\xA4\x81B
+static void ssh2_scp_add_packetlist(PTInstVar pvar, Channel_t *c, unsigned char *buf, unsigned int buflen)
+{
 	PacketList_t *p, *old;
 
 	EnterCriticalSection(&g_ssh_scp_lock);
@@ -8511,11 +8533,31 @@
 		c->scp.pktlist_tail = p;
 	}
 
+	// \x83L\x83\x85\x81[\x82ɋl\x82񂾃f\x81[\x83^\x82̑\x8D\x83T\x83C\x83Y\x82\xF0\x89\xC1\x8EZ\x82\xB7\x82\xE9\x81B
+	c->scp.pktlist_cursize += buflen;
+
+	// \x83L\x83\x85\x81[\x82ɋl\x82񂾃f\x81[\x83^\x82̑\x8D\x83T\x83C\x83Y\x82\xAA\x8F\xE3\x8C\xC0臒l\x82𒴂\xA6\x82\xBD\x8Fꍇ\x81A
+	// SSH\x83T\x81[\x83o\x82\xA9\x82\xE7\x82̎\xF3\x90M\x82\xF0\x92\xE2\x8E~\x82\xB7\x82\xE9\x82悤\x82Ɏw\x8E\xA6\x82\xF0\x8Fo\x82\xB7\x81B
+	// \x82\xB1\x82\xEA\x82ɂ\xE6\x82胊\x83X\x83g\x83G\x83\x93\x83g\x83\x8A\x82\xAA\x91\x9D\x82\xA6\x91\xB1\x82\xAF\x81A\x8F\xC1\x94\x83\x82\x83\x8A\x82̔\xEC\x91剻\x82\xF0
+	// \x89\xF1\x94\xF0\x82ł\xAB\x82\xE9\x81B
+	if (c->scp.pktlist_cursize >= SCPRCV_HIGH_WATER_MARK) {
+		// \x82\xB1\x82̃t\x83\x89\x83O\x82𗧂Ă\xBD\x8Fꍇ\x81ASSH\x92ʐM\x91S\x91̂\xCCrecv()\x82\xF0\x83u\x83\x8D\x83b\x83N\x82\xB7\x82邽\x82߁A
+		// SCP\x8F\x88\x97\x9D\x82\xAA\x8A\xAE\x97\xB9 or \x92\x86\x92f\x82\xB3\x82ꂽ\x8Fꍇ\x82́A\x82\xA9\x82Ȃ炸\x83t\x83\x89\x83O\x82𗎂Ƃ\xB5\x82Ă\xA8\x82\xAD
+		// \x95K\x97v\x82\xAA\x82\xA0\x82\xE9\x81B
+		pvar->recv_suspended = TRUE;
+	}
+
+	logprintf(LOG_LEVEL_NOTICE,
+		"%s: channel=#%d SCP recv %lu(bytes) and enqueued.(%s)",
+		__FUNCTION__, c->local_num, c->scp.pktlist_cursize,
+		pvar->recv_suspended ? "recv suspended" : "recv resumed"
+		);
+
 error:;
 	LeaveCriticalSection(&g_ssh_scp_lock);
 }
 
-static void ssh2_scp_get_packetlist(Channel_t *c, unsigned char **buf, unsigned int *buflen)
+static void ssh2_scp_get_packetlist(PTInstVar pvar, Channel_t *c, unsigned char **buf, unsigned int *buflen)
 {
 	PacketList_t *p;
 
@@ -8538,18 +8580,36 @@
 
 	free(p);
 
+	// \x83L\x83\x85\x81[\x82ɋl\x82񂾃f\x81[\x83^\x82̑\x8D\x83T\x83C\x83Y\x82\xF0\x8C\xB8\x8EZ\x82\xB7\x82\xE9\x81B
+	c->scp.pktlist_cursize -= *buflen;
+
+	// \x83L\x83\x85\x81[\x82ɋl\x82񂾃f\x81[\x83^\x82̑\x8D\x83T\x83C\x83Y\x82\xAA\x89\xBA\x8C\xC0臒l\x82\xF0\x89\xBA\x89\xF1\x82\xC1\x82\xBD\x8Fꍇ\x81A
+	// SSH\x83T\x81[\x83o\x82\xA9\x82\xE7\x82̎\xF3\x90M\x82\xF0\x8DĊJ\x82\xB7\x82\xE9\x82悤\x82Ɏw\x8E\xA6\x82\xF0\x8Fo\x82\xB7\x81B
+	if (c->scp.pktlist_cursize <= SCPRCV_LOW_WATER_MARK) {
+		// recv()\x82̃u\x83\x8D\x83b\x83N\x82\xF0\x89\xF0\x8F\x9C\x82\xB7\x82\xE9\x81B
+		ssh2_scp_recv_unblocked(pvar);
+	}
+
+	logprintf(LOG_LEVEL_NOTICE,
+		"%s: channel=#%d SCP recv %lu(bytes) and dequeued.(%s)",
+		__FUNCTION__, c->local_num, c->scp.pktlist_cursize,
+		pvar->recv_suspended ? "recv suspended" : "recv resumed"
+	);
+
 end:;
 	LeaveCriticalSection(&g_ssh_scp_lock);
 }
 
-static void ssh2_scp_alloc_packetlist(Channel_t *c)
+static void ssh2_scp_alloc_packetlist(PTInstVar pvar, Channel_t *c)
 {
 	c->scp.pktlist_head = NULL;
 	c->scp.pktlist_tail = NULL;
 	InitializeCriticalSection(&g_ssh_scp_lock);
+	c->scp.pktlist_cursize = 0;
+	pvar->recv_suspended = FALSE;
 }
 
-static void ssh2_scp_free_packetlist(Channel_t *c)
+static void ssh2_scp_free_packetlist(PTInstVar pvar, Channel_t *c)
 {
 	PacketList_t *p, *old;
 
@@ -8565,6 +8625,8 @@
 	c->scp.pktlist_head = NULL;
 	c->scp.pktlist_tail = NULL;
 	DeleteCriticalSection(&g_ssh_scp_lock);
+	c->scp.pktlist_cursize = 0;
+	pvar->recv_suspended = FALSE;
 }
 
 static BOOL SSH2_scp_fromremote(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen)
@@ -8627,7 +8689,7 @@
 				ShowWindow(hDlgWnd, SW_SHOW);
 			}
 
-			ssh2_scp_alloc_packetlist(c);
+			ssh2_scp_alloc_packetlist(pvar, c);
 			thread = (HANDLE)_beginthreadex(NULL, 0, ssh_scp_receive_thread, c, 0, &tid);
 			if (thread == 0) {
 				// TODO:
@@ -8660,7 +8722,7 @@
 			// \x8E\xA9\x91̂\xAA\x83X\x83g\x81[\x83\x8B\x82\xB5\x82Ă\xB5\x82܂\xA4\x81B\x82\xB1\x82̖\xE2\x91\xE8\x82\xF0\x89\xF1\x94\xF0\x82\xB7\x82邽\x82߁A\x83X\x83\x8C\x83b\x83h\x82̃\x81\x83b\x83Z\x81[\x83W\x83L\x83\x85\x81[\x82\xF0
 			// \x8Eg\x82\xA4\x82̂\xF0\x82\xE2\x82߂āA\x83\x8A\x83\x93\x83N\x83h\x83\x8A\x83X\x83g\x95\xFB\x8E\xAE\x82ɐ؂\xE8\x91ւ\xA6\x82\xE9\x81B
 			// (2016.11.3 yutaka)
-			ssh2_scp_add_packetlist(c, newdata, buflen);
+			ssh2_scp_add_packetlist(pvar, c, newdata, buflen);
 		}
 
 	} else if (c->scp.state == SCP_CLOSING) {  // EOF\x82̎\xF3\x90M

Modified: trunk/ttssh2/ttxssh/ssh.h
===================================================================
--- trunk/ttssh2/ttxssh/ssh.h	2023-10-07 17:40:16 UTC (rev 10958)
+++ trunk/ttssh2/ttxssh/ssh.h	2023-10-07 17:40:26 UTC (rev 10959)
@@ -527,6 +527,11 @@
 	struct PacketList *next;
 } PacketList_t;
 
+// SCP\x8E\xF3\x90M\x8F\x88\x97\x9D\x82ɂ\xA8\x82\xAF\x82\xE9\x83t\x83\x8D\x81[\x90\xA7\x8C\xE4\x82\xCC臒l
+// \x93K\x97p\x90\xE6 scp_t.filercvsize
+#define SCPRCV_HIGH_WATER_MARK (1 * 1024 * 1024)  // 16MB
+#define SCPRCV_LOW_WATER_MARK (0)  // 0MB
+
 typedef struct scp {
 	enum scp_dir dir;              // transfer direction
 	enum scp_state state;          // SCP state
@@ -546,6 +551,7 @@
 	DWORD fileatime;
 	PacketList_t *pktlist_head;
 	PacketList_t *pktlist_tail;
+	unsigned long pktlist_cursize;
 } scp_t;
 
 enum sftp_state {

Modified: trunk/ttssh2/ttxssh/ttxssh.h
===================================================================
--- trunk/ttssh2/ttxssh/ttxssh.h	2023-10-07 17:40:16 UTC (rev 10958)
+++ trunk/ttssh2/ttxssh/ttxssh.h	2023-10-07 17:40:26 UTC (rev 10959)
@@ -358,6 +358,8 @@
 	char *server_sig_algs;
 
 	char UIMsg[MAX_UIMSG];
+	BOOL recv_suspended;  // SCP\x8E\xF3\x90M\x82̃t\x83\x8D\x81[\x90\xA7\x8C\xE4\x97p
+
 } TInstVar;
 
 // \x83o\x81[\x83W\x83\x87\x83\x93\x82ɍ\x87\x82킹\x82Ď\xA9\x93\xAE\x95ύX\x82\xB3\x82\xEA\x82\xE9\x81B \x97\xE1: TTSSH_2-81_TS_data


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