| 323 |
// |
// |
| 324 |
// SSH heartbeat mutex |
// SSH heartbeat mutex |
| 325 |
// |
// |
| 326 |
|
// TTSSHは thread-safe ではないため、マルチスレッドからのパケット送信はできない。 |
| 327 |
|
// シングルスレッドではコンテキストスイッチが発生することはないため、 |
| 328 |
|
// ロックを取る必要もないため、削除する。(2007.12.26 yutaka) |
| 329 |
|
// |
| 330 |
static CRITICAL_SECTION g_ssh_heartbeat_lock; /* 送受信用ロック */ |
static CRITICAL_SECTION g_ssh_heartbeat_lock; /* 送受信用ロック */ |
|
static CRITICAL_SECTION g_ssh_blocking_send_lock; /* send_packet_blocking()用ロック */ |
|
| 331 |
|
|
| 332 |
void ssh_heartbeat_lock_initialize(void) |
void ssh_heartbeat_lock_initialize(void) |
| 333 |
{ |
{ |
| 334 |
InitializeCriticalSection(&g_ssh_heartbeat_lock); |
//InitializeCriticalSection(&g_ssh_heartbeat_lock); |
|
InitializeCriticalSection(&g_ssh_blocking_send_lock); |
|
| 335 |
} |
} |
| 336 |
|
|
| 337 |
void ssh_heartbeat_lock_finalize(void) |
void ssh_heartbeat_lock_finalize(void) |
| 338 |
{ |
{ |
| 339 |
DeleteCriticalSection(&g_ssh_heartbeat_lock); |
//DeleteCriticalSection(&g_ssh_heartbeat_lock); |
|
DeleteCriticalSection(&g_ssh_blocking_send_lock); |
|
| 340 |
} |
} |
| 341 |
|
|
| 342 |
void ssh_heartbeat_lock(void) |
void ssh_heartbeat_lock(void) |
| 349 |
//LeaveCriticalSection(&g_ssh_heartbeat_lock); |
//LeaveCriticalSection(&g_ssh_heartbeat_lock); |
| 350 |
} |
} |
| 351 |
|
|
|
static void ssh_blocking_send_lock(void) |
|
|
{ |
|
|
//EnterCriticalSection(&g_ssh_blocking_send_lock); |
|
|
} |
|
|
|
|
|
static void ssh_blocking_send_unlock(void) |
|
|
{ |
|
|
//LeaveCriticalSection(&g_ssh_blocking_send_lock); |
|
|
} |
|
|
|
|
| 352 |
|
|
| 353 |
// |
// |
| 354 |
// SSH memory dump (for debug) |
// SSH memory dump (for debug) |
| 874 |
// パケット送信後にバッファを使いまわすため、ブロッキングで送信してしまう必要がある。 |
// パケット送信後にバッファを使いまわすため、ブロッキングで送信してしまう必要がある。 |
| 875 |
// ノンブロッキングで送信してWSAEWOULDBLOCKが返ってきた場合、そのバッファは送信完了する |
// ノンブロッキングで送信してWSAEWOULDBLOCKが返ってきた場合、そのバッファは送信完了する |
| 876 |
// まで保持しておかなくてはならない。(2007.10.30 yutaka) |
// まで保持しておかなくてはならない。(2007.10.30 yutaka) |
|
// 以下の処理は thread-safe ではないため、失敗することがある。ゆえに、全体をロックする |
|
|
// 必要がある。(2007.12.24 yutaka) |
|
| 877 |
u_long do_block = 0; |
u_long do_block = 0; |
| 878 |
int code = 0; |
int code = 0; |
| 879 |
char *kind = NULL, buf[256]; |
char *kind = NULL, buf[256]; |
| 896 |
return TRUE; |
return TRUE; |
| 897 |
} |
} |
| 898 |
#else |
#else |
|
ssh_blocking_send_lock(); |
|
|
|
|
| 899 |
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
| 900 |
0, 0) == SOCKET_ERROR) { |
0, 0) == SOCKET_ERROR) { |
| 901 |
code = WSAGetLastError(); |
code = WSAGetLastError(); |
| 920 |
kind = "WSAAsyncSelect2"; |
kind = "WSAAsyncSelect2"; |
| 921 |
goto error; |
goto error; |
| 922 |
} |
} |
|
ssh_blocking_send_unlock(); |
|
|
|
|
| 923 |
return TRUE; |
return TRUE; |
| 924 |
|
|
| 925 |
error: |
error: |
|
ssh_blocking_send_unlock(); |
|
|
|
|
| 926 |
UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar, |
| 927 |
"A communications error occurred while sending an SSH packet.\n" |
"A communications error occurred while sending an SSH packet.\n" |
| 928 |
"The connection will close. (%s:%d)"); |
"The connection will close. (%s:%d)"); |
| 6344 |
// 切れてしまうことがある。定期的に、クライアントからダミーパケットを |
// 切れてしまうことがある。定期的に、クライアントからダミーパケットを |
| 6345 |
// 送信することで対処する。(2004.12.10 yutaka) |
// 送信することで対処する。(2004.12.10 yutaka) |
| 6346 |
// |
// |
| 6347 |
static unsigned __stdcall ssh_heartbeat_thread(void FAR * p) |
// モードレスダイアログからパケット送信するように変更。(2007.12.26 yutaka) |
| 6348 |
{ |
// |
| 6349 |
static int instance = 0; |
#define WM_SEND_HEARTBEAT (WM_USER + 1) |
|
PTInstVar pvar = (PTInstVar)p; |
|
|
time_t tick; |
|
| 6350 |
|
|
| 6351 |
// すでに実行中なら何もせずに返る。 |
static LRESULT CALLBACK ssh_heartbeat_dlg_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) |
| 6352 |
if (instance > 0) |
{ |
|
return 0; |
|
|
instance++; |
|
| 6353 |
|
|
| 6354 |
for (;;) { |
switch (msg) { |
| 6355 |
// ソケットがクローズされたらスレッドを終わる |
case WM_INITDIALOG: |
| 6356 |
if (pvar->socket == INVALID_SOCKET) |
return FALSE; |
|
break; |
|
| 6357 |
|
|
| 6358 |
// 一定時間無通信であれば、サーバへダミーパケットを送る |
case WM_SEND_HEARTBEAT: |
| 6359 |
// 閾値が0であれば何もしない。 |
{ |
| 6360 |
tick = time(NULL) - pvar->ssh_heartbeat_tick; |
PTInstVar pvar = (PTInstVar)wp; |
|
if (pvar->session_settings.ssh_heartbeat_overtime > 0 && |
|
|
tick > pvar->session_settings.ssh_heartbeat_overtime) { |
|
| 6361 |
buffer_t *msg; |
buffer_t *msg; |
| 6362 |
char *s; |
char *s; |
| 6363 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 6364 |
int len; |
int len; |
| 6365 |
|
|
|
// 別コンテキストで、SSHのシーケンスへ割り込まないようにロックを取る。 |
|
|
ssh_heartbeat_lock(); |
|
|
|
|
| 6366 |
msg = buffer_init(); |
msg = buffer_init(); |
| 6367 |
if (msg == NULL) { |
if (msg == NULL) { |
| 6368 |
// TODO: error check |
// TODO: error check |
| 6369 |
continue; |
return FALSE; |
| 6370 |
} |
} |
| 6371 |
s = "ssh-heartbeat"; |
s = "ssh-heartbeat"; |
| 6372 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 6379 |
memcpy(outmsg, buffer_ptr(msg), len); |
memcpy(outmsg, buffer_ptr(msg), len); |
| 6380 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 6381 |
buffer_free(msg); |
buffer_free(msg); |
| 6382 |
|
} |
| 6383 |
|
return TRUE; |
| 6384 |
|
break; |
| 6385 |
|
|
| 6386 |
ssh_heartbeat_unlock(); |
case WM_COMMAND: |
| 6387 |
|
switch (wp) { |
| 6388 |
|
} |
| 6389 |
|
|
| 6390 |
|
switch (LOWORD(wp)) { |
| 6391 |
|
case IDOK: |
| 6392 |
|
{ |
| 6393 |
|
return TRUE; |
| 6394 |
|
} |
| 6395 |
|
|
| 6396 |
|
case IDCANCEL: |
| 6397 |
|
EndDialog(hWnd, 0); |
| 6398 |
|
return TRUE; |
| 6399 |
|
default: |
| 6400 |
|
return FALSE; |
| 6401 |
|
} |
| 6402 |
|
break; |
| 6403 |
|
|
| 6404 |
|
case WM_CLOSE: |
| 6405 |
|
// closeボタンが押下されても window が閉じないようにする。 |
| 6406 |
|
return TRUE; |
| 6407 |
|
|
| 6408 |
|
case WM_DESTROY: |
| 6409 |
|
return TRUE; |
| 6410 |
|
|
| 6411 |
|
default: |
| 6412 |
|
return FALSE; |
| 6413 |
|
} |
| 6414 |
|
return TRUE; |
| 6415 |
|
} |
| 6416 |
|
|
| 6417 |
|
|
| 6418 |
|
static unsigned __stdcall ssh_heartbeat_thread(void FAR * p) |
| 6419 |
|
{ |
| 6420 |
|
static int instance = 0; |
| 6421 |
|
PTInstVar pvar = (PTInstVar)p; |
| 6422 |
|
time_t tick; |
| 6423 |
|
|
| 6424 |
|
// すでに実行中なら何もせずに返る。 |
| 6425 |
|
if (instance > 0) |
| 6426 |
|
return 0; |
| 6427 |
|
instance++; |
| 6428 |
|
|
| 6429 |
|
for (;;) { |
| 6430 |
|
// ソケットがクローズされたらスレッドを終わる |
| 6431 |
|
if (pvar->socket == INVALID_SOCKET) |
| 6432 |
|
break; |
| 6433 |
|
|
| 6434 |
|
// 一定時間無通信であれば、サーバへダミーパケットを送る |
| 6435 |
|
// 閾値が0であれば何もしない。 |
| 6436 |
|
tick = time(NULL) - pvar->ssh_heartbeat_tick; |
| 6437 |
|
if (pvar->session_settings.ssh_heartbeat_overtime > 0 && |
| 6438 |
|
tick > pvar->session_settings.ssh_heartbeat_overtime) { |
| 6439 |
|
|
| 6440 |
|
SendMessage(pvar->ssh_hearbeat_dialog, WM_SEND_HEARTBEAT, (WPARAM)pvar, 0); |
| 6441 |
} |
} |
| 6442 |
|
|
| 6443 |
Sleep(100); // yield |
Sleep(100); // yield |
| 6451 |
static void start_ssh_heartbeat_thread(PTInstVar pvar) |
static void start_ssh_heartbeat_thread(PTInstVar pvar) |
| 6452 |
{ |
{ |
| 6453 |
HANDLE thread = (HANDLE)-1; |
HANDLE thread = (HANDLE)-1; |
| 6454 |
//unsigned tid; |
unsigned tid; |
| 6455 |
|
HWND hDlgWnd; |
| 6456 |
|
|
| 6457 |
// TTSSHは thread-safe ではないのでスレッドは禁止 (yutaka) |
// モードレスダイアログを作成。ハートビート用なのでダイアログは非表示のままと |
| 6458 |
#if 0 |
// するので、リソースIDはなんでもよい。 |
| 6459 |
|
hDlgWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SSHSCP_PROGRESS), |
| 6460 |
|
pvar->cv->HWin, (DLGPROC)ssh_heartbeat_dlg_proc); |
| 6461 |
|
pvar->ssh_hearbeat_dialog = hDlgWnd; |
| 6462 |
|
|
| 6463 |
|
// TTSSHは thread-safe ではないのでスレッド内からのパケット送信は不可。(2007.12.26 yutaka) |
| 6464 |
thread = (HANDLE)_beginthreadex(NULL, 0, ssh_heartbeat_thread, pvar, 0, &tid); |
thread = (HANDLE)_beginthreadex(NULL, 0, ssh_heartbeat_thread, pvar, 0, &tid); |
|
#endif |
|
| 6465 |
if (thread == (HANDLE)-1) { |
if (thread == (HANDLE)-1) { |
| 6466 |
// TODO: |
// TODO: |
| 6467 |
} |
} |
| 6475 |
WaitForSingleObject(pvar->ssh_heartbeat_thread, INFINITE); |
WaitForSingleObject(pvar->ssh_heartbeat_thread, INFINITE); |
| 6476 |
CloseHandle(pvar->ssh_heartbeat_thread); |
CloseHandle(pvar->ssh_heartbeat_thread); |
| 6477 |
pvar->ssh_heartbeat_thread = (HANDLE)-1L; |
pvar->ssh_heartbeat_thread = (HANDLE)-1L; |
| 6478 |
|
|
| 6479 |
|
DestroyWindow(pvar->ssh_hearbeat_dialog); |
| 6480 |
} |
} |
| 6481 |
} |
} |
| 6482 |
|
|