OSDN Git Service

Fix bugs of asyncronous socket control.
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Sat, 15 Oct 2011 17:11:32 +0000 (02:11 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Sat, 15 Oct 2011 17:11:32 +0000 (02:11 +0900)
Fix bugs of simultaneous connection.
Change to reuse SSL sessions.
This version may be nearly stable (not for 1.99 but for 1.98b).

FFFTP_Eng_Release/FFFTP.exe
Release/FFFTP.exe
common.h
connect.c
getput.c
socket.c
socketwrapper.c
socketwrapper.h

index c7125c4..091989f 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index 4a6ab28..8374b77 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
index b22bbe1..beea818 100644 (file)
--- a/common.h
+++ b/common.h
@@ -1028,8 +1028,6 @@ typedef struct transpacket {
        int Mode;                                               /* 転送モード (EXIST_xxx) */\r
        HWND hWndTrans;                                 /* 転送中ダイアログのウインドウハンドル */\r
        int Abort;                                              /* 転送中止フラグ (ABORT_xxx) */\r
-       // 暗号化通信対応\r
-       int CryptMode;                                  /* 暗号化通信モード (CRYPT_xxx) */\r
        // 同時接続対応\r
        int ThreadCount;\r
        struct transpacket *Next;\r
index d008b59..09fca6e 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -1304,7 +1304,7 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char
 //                                     ;\r
                                if(CryptMode == CRYPT_FTPIS)\r
                                {\r
-                                       if(AttachSSL(ContSock))\r
+                                       if(AttachSSL(ContSock, INVALID_SOCKET))\r
                                        {\r
                                                while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM)\r
                                                        ;\r
@@ -1419,7 +1419,7 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char
                                                                {\r
                                                                        if(IsOpenSSLLoaded() && (Sts = command(ContSock, Reply, &CancelFlg, "AUTH TLS")) == 234)\r
                                                                        {\r
-                                                                               if(AttachSSL(ContSock))\r
+                                                                               if(AttachSSL(ContSock, INVALID_SOCKET))\r
                                                                                {\r
                                                                                        if((Sts = command(ContSock, Reply, &CancelFlg, "PBSZ 0")) == 200)\r
                                                                                        {\r
index 8526053..17b5e23 100644 (file)
--- a/getput.c
+++ b/getput.c
@@ -107,6 +107,8 @@ static int IsSpecialDevice(char *Fname);
 static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt);\r
 static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
 static void SetErrorMsg(char *fmt, ...);\r
+// 同時接続対応\r
+static char* GetErrMsg();\r
 \r
 /*===== ローカルなワーク =====*/\r
 \r
@@ -141,7 +143,11 @@ static int KeepDlg = NO;   /* 転送中ダイアログを消さないかどうか
 static int MoveToForeground = NO;              /* ウインドウを前面に移動するかどうか (YES/NO) */\r
 \r
 static char CurDir[FMAX_PATH+1] = { "" };\r
-static char ErrMsg[ERR_MSG_LEN+7];\r
+// 同時接続対応\r
+//static char ErrMsg[ERR_MSG_LEN+7];\r
+static char ErrMsg[MAX_DATA_CONNECTION+1][ERR_MSG_LEN+7];\r
+static DWORD ErrMsgThreadId[MAX_DATA_CONNECTION+1];\r
+static HANDLE hErrMsgMutex;\r
 \r
 // 同時接続対応\r
 static int WaitForMainThread = NO;\r
@@ -175,6 +181,8 @@ int MakeTransferThread(void)
 \r
        hListAccMutex = CreateMutex( NULL, FALSE, NULL );\r
        hRunMutex = CreateMutex( NULL, TRUE, NULL );\r
+       // 同時接続対応\r
+       hErrMsgMutex = CreateMutex( NULL, FALSE, NULL );\r
 \r
        ClearAll = NO;\r
        ForceAbort = NO;\r
@@ -236,6 +244,8 @@ void CloseTransferThread(void)
 \r
        CloseHandle( hListAccMutex );\r
        CloseHandle( hRunMutex );\r
+       // 同時接続対応\r
+       CloseHandle( hErrMsgMutex );\r
        return;\r
 }\r
 \r
@@ -682,7 +692,8 @@ static ULONG WINAPI TransferThread(void *Dummy)
                        BackgrndMessageProc();\r
                        Sleep(1);\r
                }\r
-               memset(ErrMsg, NUL, ERR_MSG_LEN+7);\r
+//             memset(ErrMsg, NUL, ERR_MSG_LEN+7);\r
+               memset(GetErrMsg(), NUL, ERR_MSG_LEN+7);\r
 \r
 //             Canceled = NO;\r
                Canceled[ThreadCount] = NO;\r
@@ -1304,12 +1315,12 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
                                        ReleaseMutex(hListAccMutex);\r
                                        // FTPS対応\r
 //                                     iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
-                                       if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+                                       if(IsSSLAttached(Pkt->ctrl_skt))\r
                                        {\r
-                                               if(AttachSSL(data_socket))\r
+                                               if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
                                                        iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
                                                else\r
-                                                       iRetCode = FTP_ERROR;\r
+                                                       iRetCode = 500;\r
                                        }\r
                                        else\r
                                                iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
@@ -1380,12 +1391,12 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
                                                ReleaseMutex(hListAccMutex);\r
                                                // FTPS対応\r
 //                                             iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
-                                               if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+                                               if(IsSSLAttached(Pkt->ctrl_skt))\r
                                                {\r
-                                                       if(AttachSSL(data_socket))\r
+                                                       if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
                                                                iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
                                                        else\r
-                                                               iRetCode = FTP_ERROR;\r
+                                                               iRetCode = 500;\r
                                                }\r
                                                else\r
                                                        iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
@@ -2094,7 +2105,9 @@ static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wPara
        {\r
                case WM_INITDIALOG :\r
                        SendDlgItemMessage(hDlg, UPDOWN_ERR_FNAME, WM_SETTEXT, 0, (LPARAM)lParam);\r
-                       SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg);\r
+                       // 同時接続対応\r
+//                     SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg);\r
+                       SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)GetErrMsg());\r
                        return(TRUE);\r
 \r
                case WM_COMMAND :\r
@@ -2340,12 +2353,12 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
                                ReleaseMutex(hListAccMutex);\r
                                // FTPS対応\r
 //                             iRetCode = UpLoadFile(Pkt, data_socket);\r
-                               if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+                               if(IsSSLAttached(Pkt->ctrl_skt))\r
                                {\r
-                                       if(AttachSSL(data_socket))\r
+                                       if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
                                                iRetCode = UpLoadFile(Pkt, data_socket);\r
                                        else\r
-                                               iRetCode = FTP_ERROR;\r
+                                               iRetCode = 500;\r
                                }\r
                                else\r
                                        iRetCode = UpLoadFile(Pkt, data_socket);\r
@@ -2422,12 +2435,12 @@ static int UpLoadPassive(TRANSPACKET *Pkt)
                                        ReleaseMutex(hListAccMutex);\r
                                        // FTPS対応\r
 //                                     iRetCode = UpLoadFile(Pkt, data_socket);\r
-                                       if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+                                       if(IsSSLAttached(Pkt->ctrl_skt))\r
                                        {\r
-                                               if(AttachSSL(data_socket))\r
+                                               if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
                                                        iRetCode = UpLoadFile(Pkt, data_socket);\r
                                                else\r
-                                                       iRetCode = FTP_ERROR;\r
+                                                       iRetCode = 500;\r
                                        }\r
                                        else\r
                                                iRetCode = UpLoadFile(Pkt, data_socket);\r
@@ -3561,10 +3574,14 @@ static void SetErrorMsg(char *fmt, ...)
 {\r
        va_list Args;\r
 \r
-       if(strlen(ErrMsg) == 0)\r
+       // 同時接続対応\r
+//     if(strlen(ErrMsg) == 0)\r
+       if(strlen(GetErrMsg()) == 0)\r
        {\r
                va_start(Args, fmt);\r
-               wvsprintf(ErrMsg, fmt, Args);\r
+               // 同時接続対応\r
+//             wvsprintf(ErrMsg, fmt, Args);\r
+               wvsprintf(GetErrMsg(), fmt, Args);\r
                va_end(Args);\r
        }\r
        return;\r
@@ -3606,3 +3623,39 @@ int CheckPathViolation(TRANSPACKET *packet)
 }\r
 \r
 \r
+// 同時接続対応\r
+static char* GetErrMsg()\r
+{\r
+       char* r;\r
+       DWORD ThreadId;\r
+       int i;\r
+       r = NULL;\r
+       WaitForSingleObject(hErrMsgMutex, INFINITE);\r
+       ThreadId = GetCurrentThreadId();\r
+       i = 0;\r
+       while(i < MAX_DATA_CONNECTION + 1)\r
+       {\r
+               if(ErrMsgThreadId[i] == ThreadId)\r
+               {\r
+                       r = ErrMsg[i];\r
+                       break;\r
+               }\r
+               i++;\r
+       }\r
+       if(!r)\r
+       {\r
+               i = 0;\r
+               while(i < MAX_DATA_CONNECTION + 1)\r
+               {\r
+                       if(ErrMsgThreadId[i] == 0)\r
+                       {\r
+                               ErrMsgThreadId[i] = ThreadId;\r
+                               r = ErrMsg[i];\r
+                               break;\r
+                       }\r
+                       i++;\r
+               }\r
+       }\r
+       ReleaseMutex(hErrMsgMutex);\r
+       return r;\r
+}\r
index b3d4163..8773978 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -271,6 +271,8 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP
                        break;\r
 \r
                case WM_ASYNC_DBASE :\r
+                       // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり\r
+                       RegistAsyncTableDbase((HANDLE)wParam);\r
                        // スレッド衝突のバグ修正\r
                        WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
                        for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
@@ -291,31 +293,6 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP
                                        break;\r
                                }\r
                        }\r
-                       // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり\r
-                       if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
-                       {\r
-                               for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
-                               {\r
-                                       if(SignalDbase[Pos].Async == 0)\r
-                                       {\r
-                                               SignalDbase[Pos].Async = (HANDLE)wParam;\r
-                                               SignalDbase[Pos].Done = 0;\r
-                                               SignalDbase[Pos].ErrorDb = 0;\r
-                                               if(HIWORD(lParam) != 0)\r
-                                               {\r
-                                                       SignalDbase[Pos].ErrorDb = 1;\r
-#if DBG_MSG\r
-                                                       DoPrintf("##### SignalDatabase: error");\r
-#endif\r
-                                               }\r
-                                               SignalDbase[Pos].Done = 1;\r
-#if DBG_MSG\r
-                                               DoPrintf("##### SignalDatabase: Done");\r
-#endif\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
                        // スレッド衝突のバグ修正\r
                        ReleaseMutex(hAsyncTblAccMutex);\r
                        break;\r
@@ -738,6 +715,9 @@ int do_closesocket(SOCKET s)
 #endif\r
        CancelCheckWork = NO;\r
 \r
+       // スレッド衝突のバグ修正\r
+       WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
+       UnRegistAsyncTable(s);\r
        // FTPS対応\r
 //     Ret = closesocket(s);\r
        Ret = closesocketS(s);\r
@@ -755,10 +735,12 @@ int do_closesocket(SOCKET s)
                        Ret = 0;\r
        }\r
 \r
-       WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
+       // スレッド衝突のバグ修正\r
+//     WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
        if(BackgrndMessageProc() == YES)\r
                CancelCheckWork = YES;\r
-       UnRegistAsyncTable(s);\r
+       // スレッド衝突のバグ修正\r
+//     UnRegistAsyncTable(s);\r
 \r
 #if DBG_MSG\r
        DoPrintf("# Exit close");\r
index 48ebfcf..acf23c3 100644 (file)
@@ -30,6 +30,8 @@ typedef int (__cdecl* _SSL_read)(SSL*, void*, int);
 typedef int (__cdecl* _SSL_get_error)(SSL*, int);\r
 typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*);\r
 typedef long (__cdecl* _SSL_get_verify_result)(const SSL*);\r
+typedef SSL_SESSION* (__cdecl* _SSL_get_session)(SSL*);\r
+typedef int (__cdecl* _SSL_set_session)(SSL*, SSL_SESSION*);\r
 typedef BIO_METHOD* (__cdecl* _BIO_s_mem)();\r
 typedef BIO* (__cdecl* _BIO_new)(BIO_METHOD*);\r
 typedef int (__cdecl* _BIO_free)(BIO*);\r
@@ -37,7 +39,6 @@ typedef long (__cdecl* _BIO_ctrl)(BIO*, int, long, void*);
 typedef void (__cdecl* _X509_free)(X509*);\r
 typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long);\r
 typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*);\r
-typedef X509_NAME* (__cdecl* _X509_get_issuer_name)(X509*);\r
 typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long);\r
 \r
 _SSL_load_error_strings p_SSL_load_error_strings;\r
@@ -58,6 +59,8 @@ _SSL_read p_SSL_read;
 _SSL_get_error p_SSL_get_error;\r
 _SSL_get_peer_certificate p_SSL_get_peer_certificate;\r
 _SSL_get_verify_result p_SSL_get_verify_result;\r
+_SSL_get_session p_SSL_get_session;\r
+_SSL_set_session p_SSL_set_session;\r
 _BIO_s_mem p_BIO_s_mem;\r
 _BIO_new p_BIO_new;\r
 _BIO_free p_BIO_free;\r
@@ -65,7 +68,6 @@ _BIO_ctrl p_BIO_ctrl;
 _X509_free p_X509_free;\r
 _X509_print_ex p_X509_print_ex;\r
 _X509_get_subject_name p_X509_get_subject_name;\r
-_X509_get_issuer_name p_X509_get_issuer_name;\r
 _X509_NAME_print_ex p_X509_NAME_print_ex;\r
 \r
 #define MAX_SSL_SOCKET 64\r
@@ -124,7 +126,9 @@ BOOL LoadOpenSSL()
                || !(p_SSL_read = (_SSL_read)GetProcAddress(g_hOpenSSL, "SSL_read"))\r
                || !(p_SSL_get_error = (_SSL_get_error)GetProcAddress(g_hOpenSSL, "SSL_get_error"))\r
                || !(p_SSL_get_peer_certificate = (_SSL_get_peer_certificate)GetProcAddress(g_hOpenSSL, "SSL_get_peer_certificate"))\r
-               || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result")))\r
+               || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result"))\r
+               || !(p_SSL_get_session = (_SSL_get_session)GetProcAddress(g_hOpenSSL, "SSL_get_session"))\r
+               || !(p_SSL_set_session = (_SSL_set_session)GetProcAddress(g_hOpenSSL, "SSL_set_session")))\r
        {\r
                if(g_hOpenSSL)\r
                        FreeLibrary(g_hOpenSSL);\r
@@ -140,7 +144,6 @@ BOOL LoadOpenSSL()
                || !(p_X509_free = (_X509_free)GetProcAddress(g_hOpenSSLCommon, "X509_free"))\r
                || !(p_X509_print_ex = (_X509_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_print_ex"))\r
                || !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name"))\r
-               || !(p_X509_get_issuer_name = (_X509_get_issuer_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_issuer_name"))\r
                || !(p_X509_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex")))\r
        {\r
                if(g_hOpenSSL)\r
@@ -330,11 +333,13 @@ BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName)
        return bResult;\r
 }\r
 \r
-BOOL AttachSSL(SOCKET s)\r
+BOOL AttachSSL(SOCKET s, SOCKET parent)\r
 {\r
        BOOL r;\r
        DWORD Time;\r
        SSL** ppSSL;\r
+       SSL** ppSSLParent;\r
+       SSL_SESSION* pSession;\r
        if(!g_bOpenSSLLoaded)\r
                return FALSE;\r
        r = FALSE;\r
@@ -350,8 +355,20 @@ BOOL AttachSSL(SOCKET s)
                        {\r
                                if(p_SSL_set_fd(*ppSSL, s) != 0)\r
                                {\r
-                                       r = TRUE;\r
+                                       if(parent != INVALID_SOCKET)\r
+                                       {\r
+                                               if(ppSSLParent = FindSSLPointerFromSocket(parent))\r
+                                               {\r
+                                                       if(pSession = p_SSL_get_session(*ppSSLParent))\r
+                                                       {\r
+                                                               if(p_SSL_set_session(*ppSSL, pSession) == 1)\r
+                                                               {\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
                                        // SSLのネゴシエーションには時間がかかる場合がある\r
+                                       r = TRUE;\r
                                        while(p_SSL_connect(*ppSSL) != 1)\r
                                        {\r
                                                LeaveCriticalSection(&g_OpenSSLLock);\r
@@ -364,6 +381,14 @@ BOOL AttachSSL(SOCKET s)
                                                }\r
                                                EnterCriticalSection(&g_OpenSSLLock);\r
                                        }\r
+                                       if(ConfirmSSLCertificate(*ppSSL))\r
+                                       {\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               DetachSSL(s);\r
+                                               r = FALSE;\r
+                                       }\r
                                }\r
                                else\r
                                {\r
@@ -371,14 +396,6 @@ BOOL AttachSSL(SOCKET s)
                                        DetachSSL(s);\r
                                        EnterCriticalSection(&g_OpenSSLLock);\r
                                }\r
-                               if(ConfirmSSLCertificate(*ppSSL))\r
-                               {\r
-                               }\r
-                               else\r
-                               {\r
-                                       DetachSSL(s);\r
-                                       r = FALSE;\r
-                               }\r
                        }\r
                }\r
        }\r
@@ -437,7 +454,7 @@ SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen)
 {\r
        SOCKET r;\r
        r = accept(s, addr, addrlen);\r
-       if(!AttachSSL(r))\r
+       if(!AttachSSL(r, INVALID_SOCKET))\r
        {\r
                closesocket(r);\r
                return INVALID_SOCKET;\r
@@ -449,7 +466,7 @@ int connectS(SOCKET s, const struct sockaddr *name, int namelen)
 {\r
        int r;\r
        r = connect(s, name, namelen);\r
-       if(!AttachSSL(r))\r
+       if(!AttachSSL(r, INVALID_SOCKET))\r
                return SOCKET_ERROR;\r
        return r;\r
 }\r
index 7556d10..574d915 100644 (file)
@@ -16,7 +16,7 @@ BOOL IsOpenSSLLoaded();
 void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback);\r
 void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback);\r
 BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName);\r
-BOOL AttachSSL(SOCKET s);\r
+BOOL AttachSSL(SOCKET s, SOCKET parent);\r
 BOOL DetachSSL(SOCKET s);\r
 BOOL IsSSLAttached(SOCKET s);\r
 SOCKET socketS(int af, int type, int protocol);\r