Revision: 7947 https://osdn.net/projects/ttssh2/scm/svn/commits/7947 Author: yutakapon Date: 2019-08-13 20:58:42 +0900 (Tue, 13 Aug 2019) Log Message: ----------- SCPファイルをサーバから受信中、受信データをリストにつなげる処理にフロー制御のしかけを追加した。 #34056 Ticket Links: ------------ https://osdn.net/projects/ttssh2/tracker/detail/34056 Modified Paths: -------------- branches/scp_flowctrl/ttssh2/ttxssh/ssh.c branches/scp_flowctrl/ttssh2/ttxssh/ssh.h branches/scp_flowctrl/ttssh2/ttxssh/ttxssh.h -------------- next part -------------- Modified: branches/scp_flowctrl/ttssh2/ttxssh/ssh.c =================================================================== --- branches/scp_flowctrl/ttssh2/ttxssh/ssh.c 2019-08-13 11:24:45 UTC (rev 7946) +++ branches/scp_flowctrl/ttssh2/ttxssh/ssh.c 2019-08-13 11:58:42 UTC (rev 7947) @@ -136,8 +136,8 @@ 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); // \x83}\x83N\x83\x8D @@ -222,6 +222,7 @@ c->scp.localfp = NULL; c->scp.filemtime = 0; c->scp.fileatime = 0; + c->scp.pvar = NULL; } if (type == TYPE_AGENT) { c->agent_msg = buffer_init(); @@ -310,6 +311,7 @@ { bufchain_t *ch, *ptr; enum scp_state prev_state; + PTInstVar pvar; ch = c->bufchain; while (ch) { @@ -351,7 +353,8 @@ c->scp.thread = INVALID_HANDLE_VALUE; } - ssh2_scp_free_packetlist(c); + pvar = c->scp.pvar; + ssh2_scp_free_packetlist(pvar, c); } if (c->type == TYPE_AGENT) { buffer_free(c->agent_msg); @@ -2876,6 +2879,7 @@ pvar->agentfwd_enable = FALSE; pvar->use_subsystem = FALSE; pvar->nosession = FALSE; + pvar->recv_suspended = FALSE; } @@ -8482,7 +8486,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; @@ -8564,7 +8568,9 @@ return 0; } -static void ssh2_scp_add_packetlist(Channel_t *c, unsigned char *buf, unsigned int buflen) +// 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; @@ -8588,11 +8594,31 @@ c->scp.pktlist_tail = p; } + // \x83L\x83\x85\x81[\x82ɋl\x82f\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\x82f\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; @@ -8615,18 +8641,35 @@ free(p); + // \x83L\x83\x85\x81[\x82ɋl\x82f\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\x82f\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) { + pvar->recv_suspended = FALSE; + } + + 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; @@ -8642,6 +8685,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) @@ -8697,7 +8742,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: @@ -8728,7 +8773,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: branches/scp_flowctrl/ttssh2/ttxssh/ssh.h =================================================================== --- branches/scp_flowctrl/ttssh2/ttxssh/ssh.h 2019-08-13 11:24:45 UTC (rev 7946) +++ branches/scp_flowctrl/ttssh2/ttxssh/ssh.h 2019-08-13 11:58:42 UTC (rev 7947) @@ -826,6 +826,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 (16 * 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 @@ -845,6 +850,7 @@ DWORD fileatime; PacketList_t *pktlist_head; PacketList_t *pktlist_tail; + unsigned long pktlist_cursize; } scp_t; enum sftp_state { Modified: branches/scp_flowctrl/ttssh2/ttxssh/ttxssh.h =================================================================== --- branches/scp_flowctrl/ttssh2/ttxssh/ttxssh.h 2019-08-13 11:24:45 UTC (rev 7946) +++ branches/scp_flowctrl/ttssh2/ttxssh/ttxssh.h 2019-08-13 11:58:42 UTC (rev 7947) @@ -342,6 +342,8 @@ // dialog resource HFONT hFontFixed; // hosts.c\x93\xE0\x82̃_\x83C\x83A\x83\x8D\x83O\x97p + 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