OSDN Git Service

Add routines for IPv6.
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Fri, 11 Nov 2011 15:40:56 +0000 (00:40 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Fri, 11 Nov 2011 15:40:56 +0000 (00:40 +0900)
Fix bugs of simultaneous connection.
Add support for reusing control connection.

16 files changed:
FFFTP_Eng_Release/FFFTP.exe
Release/FFFTP.exe
Resource/FFFTP.rc
Resource/resource.h
Resource_eng/FFFTP-eng.rc
Resource_eng/resource.h
common.h
connect.c
ftpproc.c
getput.c
history.c
hostman.c
main.c
registry.c
socket.c
socketwrapper.c

index 746d69d..1bc2af7 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index e51d6a4..94794db 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
index 397b715..e45b8e7 100644 (file)
@@ -1364,6 +1364,7 @@ BEGIN
     EDITTEXT        HSET_THREAD_COUNT,72,8,17,12,ES_AUTOHSCROLL | ES_NUMBER\r
     CONTROL         "Spin1",HSET_THREAD_COUNT_SPN,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,89,7,9,14\r
     LTEXT           "(1\81`4)",-1,102,10,31,8\r
+    CONTROL         "\83\81\83C\83\93\83E\83B\83\93\83h\83E\82Ì\83\\83P\83b\83g\82ð\8dÄ\97\98\97p",HSET_REUSE_SOCKET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,27,131,10\r
 END\r
 \r
 \r
index 73f48fe..86786ff 100644 (file)
 #define HSET_THREAD_COUNT               1204\r
 #define HSET_THREAD_COUNT_SPN           1205\r
 #define HSET_UTF8BOM_CNV                1206\r
+#define HSET_REUSE_SOCKET               1207\r
 #define MENU_END                        40001\r
 #define MENU_EXIT                       40001\r
 #define MENU_CONNECT                    40003\r
 #ifndef APSTUDIO_READONLY_SYMBOLS\r
 #define _APS_NEXT_RESOURCE_VALUE        191\r
 #define _APS_NEXT_COMMAND_VALUE         40176\r
-#define _APS_NEXT_CONTROL_VALUE         1207\r
+#define _APS_NEXT_CONTROL_VALUE         1208\r
 #define _APS_NEXT_SYMED_VALUE           101\r
 #endif\r
 #endif\r
index a00638b..6f68c86 100644 (file)
@@ -1390,6 +1390,7 @@ BEGIN
     EDITTEXT        HSET_THREAD_COUNT,72,8,17,12,ES_AUTOHSCROLL | ES_NUMBER\r
     CONTROL         "Spin1",HSET_THREAD_COUNT_SPN,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,89,7,9,14\r
     LTEXT           "(1 to 4 threads)",-1,102,10,53,8\r
+    CONTROL         "Reuse socket of the main window",HSET_REUSE_SOCKET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,27,131,10\r
 END\r
 \r
 \r
index 9bcbdd2..da46ed0 100644 (file)
 #define HSET_THREAD_COUNT               1204\r
 #define HSET_THREAD_COUNT_SPN           1205\r
 #define HSET_UTF8BOM_CNV                1206\r
+#define HSET_REUSE_SOCKET               1207\r
 #define MENU_END                        40001\r
 #define MENU_EXIT                       40001\r
 #define MENU_CONNECT                    40003\r
 #ifndef APSTUDIO_READONLY_SYMBOLS\r
 #define _APS_NEXT_RESOURCE_VALUE        191\r
 #define _APS_NEXT_COMMAND_VALUE         40176\r
-#define _APS_NEXT_CONTROL_VALUE         1207\r
+#define _APS_NEXT_CONTROL_VALUE         1208\r
 #define _APS_NEXT_SYMED_VALUE           101\r
 #endif\r
 #endif\r
index 20337b3..a6c3eaa 100644 (file)
--- a/common.h
+++ b/common.h
@@ -946,6 +946,7 @@ typedef struct {
        char PrivateKey[PRIVATE_KEY_LEN+1];     /* テキスト形式の秘密鍵 */\r
        // 同時接続対応\r
        int MaxThreadCount;                                     /* 同時接続数 */\r
+       int ReuseCmdSkt;                                        /* メインウィンドウのソケットを再利用する (YES/NO) */\r
        // FEAT対応\r
        int Feature;                                            /* 利用可能な機能のフラグ (FEATURE_xxx) */\r
        // MLSD対応\r
@@ -1006,6 +1007,7 @@ typedef struct historydata {
        char PrivateKey[PRIVATE_KEY_LEN+1];     /* テキスト形式の秘密鍵 */\r
        // 同時接続対応\r
        int MaxThreadCount;                                     /* 同時接続数 */\r
+       int ReuseCmdSkt;                                        /* メインウィンドウのソケットを再利用する (YES/NO) */\r
        // MLSD対応\r
        int UseMLSD;                                            /* "MLSD"コマンドを使用する */\r
        // IPv6対応\r
@@ -1428,6 +1430,7 @@ int AskUseSFTP(void);
 char *AskPrivateKey(void);\r
 // 同時接続対応\r
 int AskMaxThreadCount(void);\r
+int AskReuseCmdSkt(void);\r
 // FEAT対応\r
 int AskHostFeature(void);\r
 // MLSD対応\r
index 947b19a..fe01e66 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -990,9 +990,7 @@ int ReConnectCmdSkt(void)
        int Sts;\r
 \r
 \r
-       // 同時接続対応\r
-//     if(CmdCtrlSocket != TrnCtrlSocket)\r
-       if(CmdCtrlSocket != TrnCtrlSocket && TrnCtrlSocket != INVALID_SOCKET)\r
+       if(CmdCtrlSocket != TrnCtrlSocket)\r
                do_closesocket(TrnCtrlSocket);\r
        TrnCtrlSocket = INVALID_SOCKET;\r
 \r
@@ -1150,10 +1148,13 @@ void SktShareProh(void)
 //SetTaskMsg("############### SktShareProh");\r
 \r
                // 同時接続対応\r
-               // 転送スレッドがソケットを各自で用意\r
-               // TrnCtrlSocketはメインスレッド以外から使用されない\r
 //             CmdCtrlSocket = INVALID_SOCKET;\r
 //             ReConnectSkt(&CmdCtrlSocket);\r
+               if(CurHost.ReuseCmdSkt == YES)\r
+               {\r
+                       CmdCtrlSocket = INVALID_SOCKET;\r
+                       ReConnectSkt(&CmdCtrlSocket);\r
+               }\r
        }\r
        return;\r
 }\r
@@ -1174,8 +1175,10 @@ int AskShareProh(void)
        int Sts;\r
 \r
        Sts = YES;\r
+       // 同時接続対応\r
 //     if(CmdCtrlSocket == TrnCtrlSocket)\r
-//             Sts = NO;\r
+       if(CmdCtrlSocket == TrnCtrlSocket || TrnCtrlSocket == INVALID_SOCKET)\r
+               Sts = NO;\r
 \r
        return(Sts);\r
 }\r
@@ -2475,6 +2478,11 @@ int AskMaxThreadCount(void)
        return(CurHost.MaxThreadCount);\r
 }\r
 \r
+int AskReuseCmdSkt(void)\r
+{\r
+       return(CurHost.ReuseCmdSkt);\r
+}\r
+\r
 // FEAT対応\r
 int AskHostFeature(void)\r
 {\r
index 08bcc52..e610ad3 100644 (file)
--- a/ftpproc.c
+++ b/ftpproc.c
@@ -129,9 +129,6 @@ void DownLoadProc(int ChName, int ForceFile, int All)
        {\r
                DisableUserOpe();\r
 \r
-               // 同時接続対応\r
-               SktShareProh();\r
-\r
                ExistNotify = YES;\r
 //             KeepTransferDialog(YES);\r
 \r
@@ -263,9 +260,6 @@ void DirectDownLoadProc(char *Fname)
        {\r
                DisableUserOpe();\r
 \r
-               // 同時接続対応\r
-               SktShareProh();\r
-\r
                ExistNotify = YES;\r
 //             KeepTransferDialog(YES);\r
 \r
@@ -405,9 +399,6 @@ void MirrorDownloadProc(int Notify)
        {\r
                DisableUserOpe();\r
 \r
-               // 同時接続対応\r
-               SktShareProh();\r
-\r
                Base = NULL;\r
 \r
                if(Notify == YES)\r
@@ -879,9 +870,6 @@ void UpLoadListProc(int ChName, int All)
        {\r
                DisableUserOpe();\r
 \r
-               // 同時接続対応\r
-               SktShareProh();\r
-\r
                // ローカル側で選ばれているファイルをFileListBaseに登録\r
                FileListBase = NULL;\r
                MakeSelectedFileList(WIN_LOCAL, YES, All, &FileListBase, &CancelFlg);\r
@@ -1050,9 +1038,6 @@ void UpLoadDragProc(WPARAM wParam)
        {\r
                DisableUserOpe();\r
 \r
-               // 同時接続対応\r
-               SktShareProh();\r
-\r
                // ローカル側で選ばれているファイルをFileListBaseに登録\r
                FileListBase = NULL;\r
                MakeDroppedFileList(wParam, Cur, &FileListBase);\r
@@ -1212,9 +1197,6 @@ void MirrorUploadProc(int Notify)
        {\r
                DisableUserOpe();\r
 \r
-               // 同時接続対応\r
-               SktShareProh();\r
-\r
                Base = NULL;\r
 \r
                if(Notify == YES)\r
index 0eada3d..48f0d63 100644 (file)
--- a/getput.c
+++ b/getput.c
@@ -41,7 +41,9 @@
 #include <string.h>\r
 #include <mbstring.h>\r
 #include <time.h>\r
-#include <winsock.h>\r
+// IPv6対応\r
+//#include <winsock.h>\r
+#include <winsock2.h>\r
 #include <windowsx.h>\r
 #include <commctrl.h>\r
 #include <process.h>\r
@@ -711,44 +713,53 @@ static ULONG WINAPI TransferThread(void *Dummy)
                        free(Pos);\r
                }\r
                NewCmdSkt = AskCmdCtrlSkt();\r
-               if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount())\r
+               if(AskReuseCmdSkt() == YES && ThreadCount == 0)\r
                {\r
-                       if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt)\r
+                       if(TransPacketBase && ThreadCount < AskMaxThreadCount())\r
+                               TrnSkt = AskTrnCtrlSkt();\r
+               }\r
+               else\r
+               {\r
+                       if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount())\r
                        {\r
-                               ReleaseMutex(hListAccMutex);\r
-                               ReConnectTrnSkt(&TrnSkt, &Canceled[ThreadCount]);\r
-                               // 同時ログイン数制限に引っかかった可能性あり\r
-                               // 負荷を下げるためにしばらく待機\r
-                               if(TrnSkt == INVALID_SOCKET)\r
+                               if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt)\r
                                {\r
-                                       i = 10000;\r
-                                       while(NewCmdSkt != CmdSkt && i > 0)\r
+                                       ReleaseMutex(hListAccMutex);\r
+                                       ReConnectTrnSkt(&TrnSkt, &Canceled[ThreadCount]);\r
+                                       // 同時ログイン数制限に引っかかった可能性あり\r
+                                       // 負荷を下げるためにしばらく待機\r
+                                       if(TrnSkt == INVALID_SOCKET)\r
+                                       {\r
+                                               i = 10000;\r
+                                               while(NewCmdSkt != CmdSkt && i > 0)\r
+                                               {\r
+                                                       BackgrndMessageProc();\r
+                                                       Sleep(1);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+//                                     WaitForSingleObject(hListAccMutex, INFINITE);\r
+                                       while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
                                        {\r
                                                BackgrndMessageProc();\r
                                                Sleep(1);\r
-                                               i--;\r
                                        }\r
                                }\r
-//                             WaitForSingleObject(hListAccMutex, INFINITE);\r
-                               while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
-                               {\r
-                                       BackgrndMessageProc();\r
-                                       Sleep(1);\r
-                               }\r
                        }\r
-               }\r
-               else\r
-               {\r
-                       if(TrnSkt != INVALID_SOCKET)\r
+                       else\r
                        {\r
-                               ReleaseMutex(hListAccMutex);\r
-                               DoClose(TrnSkt);\r
-                               TrnSkt = INVALID_SOCKET;\r
-//                             WaitForSingleObject(hListAccMutex, INFINITE);\r
-                               while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+                               if(TrnSkt != INVALID_SOCKET)\r
                                {\r
-                                       BackgrndMessageProc();\r
-                                       Sleep(1);\r
+                                       ReleaseMutex(hListAccMutex);\r
+                                       SendData(TrnSkt, "QUIT\r\n", 6, 0, &Canceled[ThreadCount]);\r
+                                       DoClose(TrnSkt);\r
+                                       TrnSkt = INVALID_SOCKET;\r
+//                                     WaitForSingleObject(hListAccMutex, INFINITE);\r
+                                       while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+                                       {\r
+                                               BackgrndMessageProc();\r
+                                               Sleep(1);\r
+                                       }\r
                                }\r
                        }\r
                }\r
@@ -1017,7 +1028,8 @@ static ULONG WINAPI TransferThread(void *Dummy)
 //                     else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0)\r
                        else if(strcmp(Pos->Cmd, "SETCUR") == 0)\r
                        {\r
-                               if(AskShareProh() == YES)\r
+//                             if(AskShareProh() == YES)\r
+                               if(AskReuseCmdSkt() == NO || AskShareProh() == YES)\r
                                {\r
 //                                     if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
                                        if(strcmp(CurDir[Pos->ThreadCount], Pos->RemoteFile) != 0)\r
@@ -1038,7 +1050,8 @@ static ULONG WINAPI TransferThread(void *Dummy)
 //                     else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0)\r
                        else if(strcmp(Pos->Cmd, "BACKCUR") == 0)\r
                        {\r
-                               if(AskShareProh() == NO)\r
+//                             if(AskShareProh() == NO)\r
+                               if(AskReuseCmdSkt() == YES && AskShareProh() == NO)\r
                                {\r
 //                                     if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
 //                                             CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile);\r
@@ -1172,8 +1185,14 @@ static ULONG WINAPI TransferThread(void *Dummy)
                                Sleep(100);\r
                }\r
        }\r
-       if(TrnSkt != INVALID_SOCKET)\r
-               DoClose(TrnSkt);\r
+       if(AskReuseCmdSkt() == NO || ThreadCount > 0)\r
+       {\r
+               if(TrnSkt != INVALID_SOCKET)\r
+               {\r
+                       SendData(TrnSkt, "QUIT\r\n", 6, 0, &Canceled[ThreadCount]);\r
+                       DoClose(TrnSkt);\r
+               }\r
+       }\r
        return 0;\r
 }\r
 \r
@@ -3722,6 +3741,59 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max)
 }\r
 \r
 \r
+// IPv6対応\r
+static int GetAdrsAndPortIPv6(char *Str, char *Adrs, int *Port, int Max, short *Family)\r
+{\r
+       char *Pos;\r
+       char *Btm;\r
+       int Sts;\r
+\r
+       Sts = FFFTP_FAIL;\r
+\r
+       Pos = strchr(Str, '|');\r
+       if(Pos != NULL)\r
+       {\r
+               Pos++;\r
+               Btm = strchr(Pos, '|');\r
+               if(Btm != NULL)\r
+               {\r
+                       switch(atoi(Pos))\r
+                       {\r
+                       case 1:\r
+                               *Family = AF_INET;\r
+                               break;\r
+                       case 2:\r
+                               *Family = AF_INET6;\r
+                               break;\r
+                       }\r
+                       Pos = Btm + 1;\r
+                       Btm = strchr(Pos, '|');\r
+                       if(Btm != NULL)\r
+                       {\r
+                               if((Btm - Pos) <= Max)\r
+                               {\r
+                                       if((Btm - Pos) > 0)\r
+                                       {\r
+                                               strncpy(Adrs, Pos, Btm - Pos);\r
+                                               *(Adrs + (Btm - Pos)) = NUL;\r
+                                       }\r
+\r
+                                       Pos = Btm + 1;\r
+                                       Btm = strchr(Pos, '|');\r
+                                       if(Btm != NULL)\r
+                                       {\r
+                                               Btm++;\r
+                                               *Port = atoi(Pos);\r
+                                               Sts = FFFTP_SUCCESS;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       return(Sts);\r
+}\r
+\r
+\r
 /*----- Windowsのスペシャルデバイスかどうかを返す -----------------------------\r
 *\r
 *      Parameter\r
index 3f535df..0dde682 100644 (file)
--- a/history.c
+++ b/history.c
@@ -231,6 +231,7 @@ static void CopyHostToHistory(HOSTDATA *Host, HISTORYDATA *New)
        strcpy(New->PrivateKey, Host->PrivateKey);\r
        // 同時接続対応\r
        New->MaxThreadCount = Host->MaxThreadCount;\r
+       New->ReuseCmdSkt = Host->ReuseCmdSkt;\r
        // MLSD対応\r
        New->UseMLSD = Host->UseMLSD;\r
        // IPv6対応\r
@@ -292,6 +293,7 @@ void CopyHistoryToHost(HISTORYDATA *Hist, HOSTDATA *Host)
        strcpy(Host->PrivateKey, Hist->PrivateKey);\r
        // 同時接続対応\r
        Host->MaxThreadCount = Hist->MaxThreadCount;\r
+       Host->ReuseCmdSkt = Hist->ReuseCmdSkt;\r
        // MLSD対応\r
        Host->UseMLSD = Hist->UseMLSD;\r
        // IPv6対応\r
index 83f6b3a..d648a30 100644 (file)
--- a/hostman.c
+++ b/hostman.c
@@ -1036,6 +1036,7 @@ int CopyHostFromListInConnect(int Num, HOSTDATA *Set)
                Set->UseSFTP = Pos->Set.UseSFTP;\r
                // 同時接続対応\r
                Set->MaxThreadCount = Pos->Set.MaxThreadCount;\r
+               Set->ReuseCmdSkt = Pos->Set.ReuseCmdSkt;\r
                // MLSD対応\r
                Set->UseMLSD = Pos->Set.UseMLSD;\r
                // IPv6対応\r
@@ -1322,6 +1323,7 @@ void CopyDefaultHost(HOSTDATA *Set)
        strcpy(Set->PrivateKey, "");\r
        // 同時接続対応\r
        Set->MaxThreadCount = 1;\r
+       Set->ReuseCmdSkt = NO;\r
        // MLSD対応\r
        Set->Feature = 0;\r
        Set->UseMLSD = YES;\r
@@ -2213,6 +2215,7 @@ static BOOL CALLBACK Adv3SettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LP
                        SendDlgItemMessage(hDlg, HSET_THREAD_COUNT, EM_LIMITTEXT, (WPARAM)1, 0);\r
                        SetDecimalText(hDlg, HSET_THREAD_COUNT, TmpHost.MaxThreadCount);\r
                        SendDlgItemMessage(hDlg, HSET_THREAD_COUNT_SPN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(MAX_DATA_CONNECTION, 1));\r
+                       SendDlgItemMessage(hDlg, HSET_REUSE_SOCKET, BM_SETCHECK, TmpHost.ReuseCmdSkt, 0);\r
                        return(TRUE);\r
 \r
                case WM_NOTIFY:\r
@@ -2222,6 +2225,7 @@ static BOOL CALLBACK Adv3SettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LP
                                case PSN_APPLY :\r
                                        TmpHost.MaxThreadCount = GetDecimalText(hDlg, HSET_THREAD_COUNT);\r
                                        CheckRange2(&TmpHost.MaxThreadCount, MAX_DATA_CONNECTION, 1);\r
+                                       TmpHost.ReuseCmdSkt = SendDlgItemMessage(hDlg, HSET_REUSE_SOCKET, BM_GETCHECK, 0, 0);\r
                                        Apply = YES;\r
                                        break;\r
 \r
diff --git a/main.c b/main.c
index 25b623a..79d3709 100644 (file)
--- a/main.c
+++ b/main.c
@@ -218,8 +218,6 @@ int MirUpDelNotify = YES;
 int MirDownDelNotify = YES; \r
 int FolderAttr = NO;\r
 int FolderAttrNum = 777;\r
-// 同時接続対応\r
-int MaxThreadCount = 1;\r
 // 暗号化通信対応\r
 BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];\r
 \r
index 7226885..e85ce74 100644 (file)
@@ -479,6 +479,7 @@ void SaveRegistory(void)
                                                        SaveStr(hKey5, "PKey", Str, DefaultHist.PrivateKey);\r
                                                        // 同時接続対応\r
                                                        SaveIntNum(hKey5, "ThreadCount", Hist.MaxThreadCount, DefaultHist.MaxThreadCount);\r
+                                                       SaveIntNum(hKey5, "ReuseCmdSkt", Hist.ReuseCmdSkt, DefaultHist.ReuseCmdSkt);\r
                                                        // MLSD対応\r
                                                        SaveIntNum(hKey5, "MLSD", Hist.UseMLSD, DefaultHist.UseMLSD);\r
                                                        // IPv6対応\r
@@ -560,6 +561,7 @@ void SaveRegistory(void)
                                                        SaveStr(hKey5, "PKey", Str, DefaultHost.PrivateKey);\r
                                                        // 同時接続対応\r
                                                        SaveIntNum(hKey5, "ThreadCount", Host.MaxThreadCount, DefaultHost.MaxThreadCount);\r
+                                                       SaveIntNum(hKey5, "ReuseCmdSkt", Host.ReuseCmdSkt, DefaultHost.ReuseCmdSkt);\r
                                                        // MLSD対応\r
                                                        SaveIntNum(hKey5, "MLSD", Host.UseMLSD, DefaultHost.UseMLSD);\r
                                                        // IPv6対応\r
@@ -832,6 +834,7 @@ int LoadRegistory(void)
                                        DecodePassword(Str, Hist.PrivateKey);\r
                                        // 同時接続対応\r
                                        ReadIntValueFromReg(hKey5, "ThreadCount", &Hist.MaxThreadCount);\r
+                                       ReadIntValueFromReg(hKey5, "ReuseCmdSkt", &Hist.ReuseCmdSkt);\r
                                        // MLSD対応\r
                                        ReadIntValueFromReg(hKey5, "MLSD", &Hist.UseMLSD);\r
                                        // IPv6対応\r
@@ -922,6 +925,7 @@ int LoadRegistory(void)
                                        DecodePassword(Str, Host.PrivateKey);\r
                                        // 同時接続対応\r
                                        ReadIntValueFromReg(hKey5, "ThreadCount", &Host.MaxThreadCount);\r
+                                       ReadIntValueFromReg(hKey5, "ReuseCmdSkt", &Host.ReuseCmdSkt);\r
                                        // MLSD対応\r
                                        ReadIntValueFromReg(hKey5, "MLSD", &Host.UseMLSD);\r
                                        // IPv6対応\r
index 49055b1..f999f77 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -28,6 +28,8 @@
 /============================================================================*/\r
 \r
 #define        STRICT\r
+// IPv6対応\r
+#include <ws2tcpip.h>\r
 #include <windows.h>\r
 #include <stdio.h>\r
 #include <stdlib.h>\r
 \r
 \r
 \r
-#define FD_CONNECT_BIT         0x0001\r
-#define FD_CLOSE_BIT           0x0002\r
-#define FD_ACCEPT_BIT          0x0004\r
-#define FD_READ_BIT                    0x0008\r
-#define FD_WRITE_BIT           0x0010\r
+// Winsock2で定義される定数と名前が重複し値が異なるため使用不可\r
+//#define FD_CONNECT_BIT               0x0001\r
+//#define FD_CLOSE_BIT         0x0002\r
+//#define FD_ACCEPT_BIT                0x0004\r
+//#define FD_READ_BIT                  0x0008\r
+//#define FD_WRITE_BIT         0x0010\r
 \r
 \r
 \r
@@ -79,8 +82,8 @@ typedef struct {
 // 念のためテーブルを増量\r
 //#define MAX_SIGNAL_ENTRY             10\r
 //#define MAX_SIGNAL_ENTRY_DBASE       5\r
-#define MAX_SIGNAL_ENTRY               100\r
-#define MAX_SIGNAL_ENTRY_DBASE 50\r
+#define MAX_SIGNAL_ENTRY               16\r
+#define MAX_SIGNAL_ENTRY_DBASE 16\r
 \r
 \r
 \r
@@ -96,6 +99,8 @@ static int UnRegistAsyncTable(SOCKET s);
 static int UnRegistAsyncTableDbase(HANDLE Async);\r
 // UTF-8対応\r
 static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen);\r
+// IPv6対応\r
+static HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family);\r
 \r
 \r
 /*===== 外部参照 =====*/\r
@@ -335,22 +340,22 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask)
                        *Error = Signal[Pos].Error;\r
                        if(Signal[Pos].Error != 0)\r
                                Sts = YES;\r
-                       if((Mask & FD_CONNECT_BIT) && (Signal[Pos].FdConnect != 0))\r
+                       if((Mask & FD_CONNECT) && (Signal[Pos].FdConnect != 0))\r
                        {\r
                                Sts = YES;\r
 #if DBG_MSG\r
                                DoPrintf("### Ask: connect (Sts=%d, Error=%d)", Sts, *Error);\r
 #endif\r
                        }\r
-                       if((Mask & FD_CLOSE_BIT) && (Signal[Pos].FdClose != 0))\r
-//                     if(Mask & FD_CLOSE_BIT)\r
+                       if((Mask & FD_CLOSE) && (Signal[Pos].FdClose != 0))\r
+//                     if(Mask & FD_CLOSE)\r
                        {\r
                                Sts = YES;\r
 #if DBG_MSG\r
                                DoPrintf("### Ask: close (Sts=%d, Error=%d)", Sts, *Error);\r
 #endif\r
                        }\r
-                       if((Mask & FD_ACCEPT_BIT) && (Signal[Pos].FdAccept != 0))\r
+                       if((Mask & FD_ACCEPT) && (Signal[Pos].FdAccept != 0))\r
                        {\r
                                Signal[Pos].FdAccept = 0;\r
                                Sts = YES;\r
@@ -358,7 +363,7 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask)
                                DoPrintf("### Ask: accept (Sts=%d, Error=%d)", Sts, *Error);\r
 #endif\r
                        }\r
-                       if((Mask & FD_READ_BIT) && (Signal[Pos].FdRead != 0))\r
+                       if((Mask & FD_READ) && (Signal[Pos].FdRead != 0))\r
                        {\r
                                Signal[Pos].FdRead = 0;\r
                                Sts = YES;\r
@@ -366,7 +371,7 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask)
                                DoPrintf("### Ask: read (Sts=%d, Error=%d)", Sts, *Error);\r
 #endif\r
                        }\r
-                       if((Mask & FD_WRITE_BIT) && (Signal[Pos].FdWrite != 0))\r
+                       if((Mask & FD_WRITE) && (Signal[Pos].FdWrite != 0))\r
                        {\r
                                Signal[Pos].FdWrite = 0;\r
                                Sts = YES;\r
@@ -382,7 +387,7 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask)
 \r
        if(Pos == MAX_SIGNAL_ENTRY)\r
        {\r
-               if(Mask & FD_CLOSE_BIT)\r
+               if(Mask & FD_CLOSE)\r
                {\r
                                Sts = YES;\r
                }\r
@@ -662,7 +667,9 @@ struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *Canc
 \r
        // UTF-8対応\r
 //     hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
-       hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+       // IPv6対応\r
+//     hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+       hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET);\r
        if(hAsync != NULL)\r
        {\r
                RegistAsyncTableDbase(hAsync);\r
@@ -731,7 +738,7 @@ int do_closesocket(SOCKET s)
        if(Ret == SOCKET_ERROR)\r
        {\r
                Error = 0;\r
-               while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE_BIT) != YES))\r
+               while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE) != YES))\r
                {\r
                        Sleep(1);\r
                        if(BackgrndMessageProc() == YES)\r
@@ -778,7 +785,9 @@ int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCh
 #if DBG_MSG\r
        DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
 #endif\r
-       Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+       // 高速化のためFD_READとFD_WRITEを使用しない\r
+//     Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+       Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT);\r
        if(Ret != SOCKET_ERROR)\r
        {\r
                Ret = connect(s, name, namelen);\r
@@ -787,7 +796,7 @@ int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCh
                        do\r
                        {\r
                                Error = 0;\r
-                               while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT_BIT) != YES))\r
+                               while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT) != YES))\r
                                {\r
                                        Sleep(1);\r
                                        if(BackgrndMessageProc() == YES)\r
@@ -859,9 +868,9 @@ SOCKET do_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
        Ret2 = INVALID_SOCKET;\r
        Error = 0;\r
 \r
-       while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT_BIT) != YES))\r
+       while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT) != YES))\r
        {\r
-               if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
+               if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
                {\r
                        Error = 1;\r
                        break;\r
@@ -947,29 +956,30 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *Cance
 \r
        // FTPS対応\r
        // OpenSSLでは受信確認はFD_READが複数回受信される可能性がある\r
-//     while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))\r
-       while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))\r
-       {\r
-               if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
-               {\r
-                       Ret = 0;\r
-                       break;\r
-               }\r
-               Sleep(1);\r
-               if(BackgrndMessageProc() == YES)\r
-                       *CancelCheckWork = YES;\r
-               else if(TimeOut != 0)\r
-               {\r
-                       time(&ElapseTime);\r
-                       ElapseTime -= StartTime;\r
-                       if(ElapseTime >= TimeOut)\r
-                       {\r
-                               DoPrintf("do_recv timed out");\r
-                               *TimeOutErr = YES;\r
-                               *CancelCheckWork = YES;\r
-                       }\r
-               }\r
-       }\r
+//     while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES))\r
+       // 短時間にFD_READが2回以上通知される対策\r
+//     while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES))\r
+//     {\r
+//             if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
+//             {\r
+//                     Ret = 0;\r
+//                     break;\r
+//             }\r
+//             Sleep(1);\r
+//             if(BackgrndMessageProc() == YES)\r
+//                     *CancelCheckWork = YES;\r
+//             else if(TimeOut != 0)\r
+//             {\r
+//                     time(&ElapseTime);\r
+//                     ElapseTime -= StartTime;\r
+//                     if(ElapseTime >= TimeOut)\r
+//                     {\r
+//                             DoPrintf("do_recv timed out");\r
+//                             *TimeOutErr = YES;\r
+//                             *CancelCheckWork = YES;\r
+//                     }\r
+//             }\r
+//     }\r
 \r
        if(/*(Ret != 0) && */(Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))\r
        {\r
@@ -1055,11 +1065,11 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int
 \r
        // FTPS対応\r
        // 送信バッファの空き確認には影響しないが念のため\r
-//     while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
+//     while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES))\r
        // Windows 2000でFD_WRITEが通知されないことがあるバグ修正\r
-//     while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
+//     while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES))\r
 //     {\r
-//             if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
+//             if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
 //             {\r
 //                     Error = 1;\r
 //                     break;\r
@@ -1145,7 +1155,7 @@ void RemoveReceivedData(SOCKET s)
        int Error;\r
        while((len = recvS(s, buf, sizeof(buf), MSG_PEEK)) >= 0)\r
        {\r
-               AskAsyncDone(s, &Error, FD_READ_BIT);\r
+               AskAsyncDone(s, &Error, FD_READ);\r
                recvS(s, buf, len, 0);\r
        }\r
 }\r
@@ -1168,7 +1178,7 @@ int CheckClosedAndReconnect(void)
 //SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");\r
 \r
        Sts = FFFTP_SUCCESS;\r
-       if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE_BIT) == YES)\r
+       if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE) == YES)\r
        {\r
                Sts = ReConnectCmdSkt();\r
        }\r
@@ -1177,6 +1187,138 @@ int CheckClosedAndReconnect(void)
 \r
 \r
 \r
+// IPv6対応\r
+\r
+typedef struct\r
+{\r
+       HANDLE h;\r
+       HWND hWnd;\r
+       u_int wMsg;\r
+       char * name;\r
+       char * buf;\r
+       int buflen;\r
+       short Family;\r
+} GETHOSTBYNAMEDATA;\r
+\r
+static DWORD WINAPI WSAAsyncGetHostByNameIPv6ThreadProc(LPVOID lpParameter)\r
+{\r
+       GETHOSTBYNAMEDATA* pData;\r
+       struct hostent* pHost;\r
+       struct addrinfo* pAddr;\r
+       struct addrinfo* p;\r
+       pHost = NULL;\r
+       pData = (GETHOSTBYNAMEDATA*)lpParameter;\r
+       if(getaddrinfo(pData->name, NULL, NULL, &pAddr) == 0)\r
+       {\r
+               p = pAddr;\r
+               while(p)\r
+               {\r
+                       if(p->ai_family == pData->Family)\r
+                       {\r
+                               switch(p->ai_family)\r
+                               {\r
+                               case AF_INET:\r
+                                       pHost = (struct hostent*)pData->buf;\r
+                                       if((size_t)pData->buflen >= sizeof(struct hostent) + sizeof(char*) * 2 + sizeof(struct in_addr)\r
+                                               && p->ai_addrlen >= sizeof(struct sockaddr_in))\r
+                                       {\r
+                                               pHost->h_name = NULL;\r
+                                               pHost->h_aliases = NULL;\r
+                                               pHost->h_addrtype = p->ai_family;\r
+                                               pHost->h_length = sizeof(struct in_addr);\r
+                                               pHost->h_addr_list = (char**)(&pHost[1]);\r
+                                               pHost->h_addr_list[0] = (char*)(&pHost->h_addr_list[2]);\r
+                                               pHost->h_addr_list[1] = NULL;\r
+                                               memcpy(pHost->h_addr_list[0], &((struct sockaddr_in*)p->ai_addr)->sin_addr, sizeof(struct in_addr));\r
+                                               PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + p->ai_addrlen));\r
+                                       }\r
+                                       else\r
+                                               PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(WSAENOBUFS << 16));\r
+                                       break;\r
+                               case AF_INET6:\r
+                                       pHost = (struct hostent*)pData->buf;\r
+                                       if((size_t)pData->buflen >= sizeof(struct hostent) + sizeof(char*) * 2 + sizeof(struct in6_addr)\r
+                                               && p->ai_addrlen >= sizeof(struct sockaddr_in6))\r
+                                       {\r
+                                               pHost->h_name = NULL;\r
+                                               pHost->h_aliases = NULL;\r
+                                               pHost->h_addrtype = p->ai_family;\r
+                                               pHost->h_length = sizeof(struct in6_addr);\r
+                                               pHost->h_addr_list = (char**)(&pHost[1]);\r
+                                               pHost->h_addr_list[0] = (char*)(&pHost->h_addr_list[2]);\r
+                                               pHost->h_addr_list[1] = NULL;\r
+                                               memcpy(pHost->h_addr_list[0], &((struct sockaddr_in6*)p->ai_addr)->sin6_addr, sizeof(struct in6_addr));\r
+                                               PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + p->ai_addrlen));\r
+                                       }\r
+                                       else\r
+                                               PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(WSAENOBUFS << 16));\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if(pHost)\r
+                               break;\r
+                       p = p->ai_next;\r
+               }\r
+               if(!p)\r
+                       PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(ERROR_INVALID_FUNCTION << 16));\r
+               freeaddrinfo(pAddr);\r
+       }\r
+       else\r
+               PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(ERROR_INVALID_FUNCTION << 16));\r
+       free(pData->name);\r
+       free(pData);\r
+       // CreateThreadが返すハンドルが重複するのを回避\r
+       Sleep(10000);\r
+       return 0;\r
+}\r
+\r
+// IPv6対応のWSAAsyncGetHostByName相当の関数\r
+// FamilyにはAF_INETまたはAF_INET6を指定可能\r
+// ただしANSI用\r
+static HANDLE WSAAsyncGetHostByNameIPv6(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family)\r
+{\r
+       HANDLE hResult;\r
+       GETHOSTBYNAMEDATA* pData;\r
+       hResult = NULL;\r
+       if(pData = malloc(sizeof(GETHOSTBYNAMEDATA)))\r
+       {\r
+               pData->hWnd = hWnd;\r
+               pData->wMsg = wMsg;\r
+               if(pData->name = malloc(sizeof(char) * (strlen(name) + 1)))\r
+               {\r
+                       strcpy(pData->name, name);\r
+                       pData->buf = buf;\r
+                       pData->buflen = buflen;\r
+                       pData->Family = Family;\r
+                       if(pData->h = CreateThread(NULL, 0, WSAAsyncGetHostByNameIPv6ThreadProc, pData, CREATE_SUSPENDED, NULL))\r
+                       {\r
+                               ResumeThread(pData->h);\r
+                               hResult = pData->h;\r
+                       }\r
+               }\r
+       }\r
+       if(!hResult)\r
+       {\r
+               if(pData)\r
+               {\r
+                       if(pData->name)\r
+                               free(pData->name);\r
+                       free(pData);\r
+               }\r
+       }\r
+       return hResult;\r
+}\r
+\r
+// WSAAsyncGetHostByNameIPv6用のWSACancelAsyncRequest相当の関数\r
+int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle)\r
+{\r
+       int Result;\r
+       Result = SOCKET_ERROR;\r
+       if(TerminateThread(hAsyncTaskHandle, 0))\r
+               Result = 0;\r
+       return Result;\r
+}\r
+\r
 // UTF-8対応\r
 \r
 static BOOL ConvertStringToPunycode(LPSTR Output, DWORD Count, LPCSTR Input)\r
@@ -1279,3 +1421,16 @@ static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, c
        return r;\r
 }\r
 \r
+static HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family)\r
+{\r
+       HANDLE r = NULL;\r
+       char* pa0 = NULL;\r
+       if(pa0 = AllocateStringA(strlen(name) * 4))\r
+       {\r
+               if(ConvertNameToPunycode(pa0, name))\r
+                       r = WSAAsyncGetHostByNameIPv6(hWnd, wMsg, pa0, buf, buflen, Family);\r
+       }\r
+       FreeDuplicatedString(pa0);\r
+       return r;\r
+}\r
+\r
index 79529a4..d5a3d10 100644 (file)
@@ -70,7 +70,7 @@ _X509_print_ex p_X509_print_ex;
 _X509_get_subject_name p_X509_get_subject_name;\r
 _X509_NAME_print_ex p_X509_NAME_print_ex;\r
 \r
-#define MAX_SSL_SOCKET 64\r
+#define MAX_SSL_SOCKET 16\r
 \r
 BOOL g_bOpenSSLLoaded;\r
 HMODULE g_hOpenSSL;\r