| 213 |
c->type = type; |
c->type = type; |
| 214 |
c->local_num = local_num; // alloc_channel()の返値を保存しておく |
c->local_num = local_num; // alloc_channel()の返値を保存しておく |
| 215 |
c->bufchain = NULL; |
c->bufchain = NULL; |
| 216 |
|
c->bufchain_amount = 0; |
| 217 |
|
c->bufchain_recv_suspended = FALSE; |
| 218 |
if (type == TYPE_SCP) { |
if (type == TYPE_SCP) { |
| 219 |
c->scp.state = SCP_INIT; |
c->scp.state = SCP_INIT; |
| 220 |
c->scp.progress_window = NULL; |
c->scp.progress_window = NULL; |
| 233 |
} |
} |
| 234 |
|
|
| 235 |
// remote_windowの空きがない場合に、送れなかったバッファをリスト(入力順)へつないでおく。 |
// remote_windowの空きがない場合に、送れなかったバッファをリスト(入力順)へつないでおく。 |
| 236 |
static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen) |
// ここで確保したメモリは ssh2_channel_retry_send_bufchain() で解放する。 |
| 237 |
|
static void ssh2_channel_add_bufchain(PTInstVar pvar, Channel_t *c, unsigned char *buf, unsigned int buflen) |
| 238 |
{ |
{ |
| 239 |
bufchain_t *p, *old; |
bufchain_t *p, *old; |
| 240 |
|
|
| 258 |
old = old->next; |
old = old->next; |
| 259 |
old->next = p; |
old->next = p; |
| 260 |
} |
} |
| 261 |
|
|
| 262 |
|
// バッファサイズの合計を更新する(記録用) |
| 263 |
|
c->bufchain_amount += buflen; |
| 264 |
|
|
| 265 |
|
// remote_windowの空きがないので、local connectionからのパケット受信の |
| 266 |
|
// 停止指示を出す。すぐに通知が止まるわけではない。 |
| 267 |
|
FWD_suspend_resume_local_connection(pvar, c, FALSE); |
| 268 |
} |
} |
| 269 |
|
|
| 270 |
|
// remote_windowの空きができたら、リストに残っているデータを順番に送る。 |
| 271 |
|
// 送信ができたらメモリを解放する。 |
| 272 |
static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c) |
static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c) |
| 273 |
{ |
{ |
| 274 |
bufchain_t *ch; |
bufchain_t *ch; |
| 275 |
unsigned int size; |
unsigned int size; |
| 276 |
|
bufchain_t* ch_origin = c->bufchain; |
| 277 |
|
|
| 278 |
while (c->bufchain) { |
while (c->bufchain) { |
| 279 |
// 先頭から先に送る |
// 先頭から先に送る |
| 292 |
|
|
| 293 |
buffer_free(ch->msg); |
buffer_free(ch->msg); |
| 294 |
free(ch); |
free(ch); |
| 295 |
|
|
| 296 |
|
// バッファサイズの合計を更新する(記録用) |
| 297 |
|
c->bufchain_amount -= size; |
| 298 |
|
} |
| 299 |
|
|
| 300 |
|
// 元々あったリストが空になったら、 |
| 301 |
|
// local connectionからのパケット通知を再開する。 |
| 302 |
|
if (ch_origin && c->bufchain == NULL) { |
| 303 |
|
FWD_suspend_resume_local_connection(pvar, c, TRUE); |
| 304 |
} |
} |
| 305 |
} |
} |
| 306 |
|
|
| 392 |
// SSH1で管理しているchannel構造体から、SSH2向けのChannel_tへ変換する。 |
// SSH1で管理しているchannel構造体から、SSH2向けのChannel_tへ変換する。 |
| 393 |
// TODO: 将来的にはチャネル構造体は1つに統合する。 |
// TODO: 将来的にはチャネル構造体は1つに統合する。 |
| 394 |
// (2005.6.12 yutaka) |
// (2005.6.12 yutaka) |
| 395 |
static Channel_t *ssh2_local_channel_lookup(int local_num) |
Channel_t *ssh2_local_channel_lookup(int local_num) |
| 396 |
{ |
{ |
| 397 |
int i; |
int i; |
| 398 |
Channel_t *c; |
Channel_t *c; |
| 3463 |
// これによりパケットが壊れたように見える現象が改善される。 |
// これによりパケットが壊れたように見える現象が改善される。 |
| 3464 |
// (2012.10.14 yutaka) |
// (2012.10.14 yutaka) |
| 3465 |
if (retry == 0 && c->bufchain) { |
if (retry == 0 && c->bufchain) { |
| 3466 |
ssh2_channel_add_bufchain(c, buf, buflen); |
ssh2_channel_add_bufchain(pvar, c, buf, buflen); |
| 3467 |
return; |
return; |
| 3468 |
} |
} |
| 3469 |
|
|
| 3470 |
if ((unsigned int)buflen > c->remote_window) { |
if ((unsigned int)buflen > c->remote_window) { |
| 3471 |
unsigned int offset = 0; |
unsigned int offset = 0; |
| 3472 |
// 送れないデータはいったん保存しておく |
// 送れないデータはいったん保存しておく |
| 3473 |
ssh2_channel_add_bufchain(c, buf + offset, buflen - offset); |
ssh2_channel_add_bufchain(pvar, c, buf + offset, buflen - offset); |
| 3474 |
buflen = offset; |
buflen = offset; |
| 3475 |
return; |
return; |
| 3476 |
} |
} |