Browse Source

Issue 2244 – Do not use directory listing to keep FTP session alive by default

https://winscp.net/tracker/2244

Source commit: 61d8886b91c8375f597a8b8b9b0975e40b9003a6
Martin Prikryl 1 year ago
parent
commit
0e0c2f2006

+ 2 - 2
source/core/FtpFileSystem.cpp

@@ -817,7 +817,7 @@ void __fastcall TFTPFileSystem::Idle()
     PoolForFatalNonCommandReply();
     PoolForFatalNonCommandReply();
 
 
     // Keep session alive
     // Keep session alive
-    if ((FTerminal->SessionData->FtpPingType != ptOff) &&
+    if ((FTerminal->SessionData->FtpPingType == fptDirectoryListing) &&
         (double(Now() - FLastDataSent) > double(FTerminal->SessionData->FtpPingIntervalDT) * 4))
         (double(Now() - FLastDataSent) > double(FTerminal->SessionData->FtpPingIntervalDT) * 4))
     {
     {
       FTerminal->LogEvent(L"Dummy directory read to keep session alive.");
       FTerminal->LogEvent(L"Dummy directory read to keep session alive.");
@@ -2804,7 +2804,7 @@ int __fastcall TFTPFileSystem::GetOptionVal(int OptionID) const
       break;
       break;
 
 
     case OPTION_KEEPALIVE:
     case OPTION_KEEPALIVE:
-      Result = ((Data->FtpPingType != ptOff) ? TRUE : FALSE);
+      Result = ((Data->FtpPingType != fptOff) ? TRUE : FALSE);
       break;
       break;
 
 
     case OPTION_INTERVALLOW:
     case OPTION_INTERVALLOW:

+ 4 - 3
source/core/SessionData.cpp

@@ -29,6 +29,7 @@
   SET_SESSION_PROPERTY_FROM(PROPERTY, value)
   SET_SESSION_PROPERTY_FROM(PROPERTY, value)
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 const wchar_t * PingTypeNames = L"Off;Null;Dummy";
 const wchar_t * PingTypeNames = L"Off;Null;Dummy";
+const wchar_t * FtpPingTypeNames = L"Off;Dummy;Dummy;List";
 const wchar_t * ProxyMethodNames = L"None;SOCKS4;SOCKS5;HTTP;Telnet;Cmd";
 const wchar_t * ProxyMethodNames = L"None;SOCKS4;SOCKS5;HTTP;Telnet;Cmd";
 TIntMapping ProxyMethodMapping = CreateIntMappingFromEnumNames(LowerCase(ProxyMethodNames));
 TIntMapping ProxyMethodMapping = CreateIntMappingFromEnumNames(LowerCase(ProxyMethodNames));
 const wchar_t * DefaultName = L"Default Settings";
 const wchar_t * DefaultName = L"Default Settings";
@@ -330,7 +331,7 @@ void __fastcall TSessionData::DefaultSettings()
   FtpUseMlsd = asAuto;
   FtpUseMlsd = asAuto;
   FtpAccount = L"";
   FtpAccount = L"";
   FtpPingInterval = 30;
   FtpPingInterval = 30;
-  FtpPingType = ptDummyCommand;
+  FtpPingType = fptDummyCommand;
   FtpTransferActiveImmediately = asAuto;
   FtpTransferActiveImmediately = asAuto;
   Ftps = ftpsNone;
   Ftps = ftpsNone;
   MinTlsVersion = tlsDefaultMin;
   MinTlsVersion = tlsDefaultMin;
@@ -912,7 +913,7 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
   FtpUseMlsd = Storage->ReadEnum(L"FtpUseMlsd", FtpUseMlsd, AutoSwitchMapping);
   FtpUseMlsd = Storage->ReadEnum(L"FtpUseMlsd", FtpUseMlsd, AutoSwitchMapping);
   FtpAccount = Storage->ReadString(L"FtpAccount", FtpAccount);
   FtpAccount = Storage->ReadString(L"FtpAccount", FtpAccount);
   FtpPingInterval = Storage->ReadInteger(L"FtpPingInterval", FtpPingInterval);
   FtpPingInterval = Storage->ReadInteger(L"FtpPingInterval", FtpPingInterval);
-  FtpPingType = static_cast<TPingType>(Storage->ReadInteger(L"FtpPingType", FtpPingType));
+  FtpPingType = static_cast<TFtpPingType>(Storage->ReadInteger(L"FtpPingType", FtpPingType));
   FtpTransferActiveImmediately = Storage->ReadEnum(L"FtpTransferActiveImmediately2", FtpTransferActiveImmediately, AutoSwitchMapping);
   FtpTransferActiveImmediately = Storage->ReadEnum(L"FtpTransferActiveImmediately2", FtpTransferActiveImmediately, AutoSwitchMapping);
   Ftps = static_cast<TFtps>(Storage->ReadInteger(L"Ftps", Ftps));
   Ftps = static_cast<TFtps>(Storage->ReadInteger(L"Ftps", Ftps));
   FtpListAll = Storage->ReadEnum(L"FtpListAll", FtpListAll, AutoSwitchMapping);
   FtpListAll = Storage->ReadEnum(L"FtpListAll", FtpListAll, AutoSwitchMapping);
@@ -4466,7 +4467,7 @@ TDateTime __fastcall TSessionData::GetFtpPingIntervalDT()
   return SecToDateTime(FtpPingInterval);
   return SecToDateTime(FtpPingInterval);
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-void __fastcall TSessionData::SetFtpPingType(TPingType value)
+void __fastcall TSessionData::SetFtpPingType(TFtpPingType value)
 {
 {
   SET_SESSION_PROPERTY(FtpPingType);
   SET_SESSION_PROPERTY(FtpPingType);
 }
 }

+ 5 - 3
source/core/SessionData.h

@@ -31,6 +31,8 @@ enum TSftpBug { sbSymlink, sbSignedTS };
 #define SFTP_BUG_COUNT (sbSignedTS+1)
 #define SFTP_BUG_COUNT (sbSignedTS+1)
 extern const wchar_t * PingTypeNames;
 extern const wchar_t * PingTypeNames;
 enum TPingType { ptOff, ptNullPacket, ptDummyCommand };
 enum TPingType { ptOff, ptNullPacket, ptDummyCommand };
+extern const wchar_t * FtpPingTypeNames;
+enum TFtpPingType { fptOff, fptDummyCommand0, fptDummyCommand, fptDirectoryListing };
 enum TAddressFamily { afAuto, afIPv4, afIPv6 };
 enum TAddressFamily { afAuto, afIPv4, afIPv6 };
 enum TFtps { ftpsNone, ftpsImplicit, ftpsExplicitSsl, ftpsExplicitTls };
 enum TFtps { ftpsNone, ftpsImplicit, ftpsExplicitSsl, ftpsExplicitTls };
 // ssl2 and ssh3 are equivalent of tls10 now
 // ssl2 and ssh3 are equivalent of tls10 now
@@ -221,7 +223,7 @@ private:
   TAutoSwitch FFtpUseMlsd;
   TAutoSwitch FFtpUseMlsd;
   UnicodeString FFtpAccount;
   UnicodeString FFtpAccount;
   int FFtpPingInterval;
   int FFtpPingInterval;
-  TPingType FFtpPingType;
+  TFtpPingType FFtpPingType;
   TAutoSwitch FFtpTransferActiveImmediately;
   TAutoSwitch FFtpTransferActiveImmediately;
   TFtps FFtps;
   TFtps FFtps;
   TTlsVersion FMinTlsVersion;
   TTlsVersion FMinTlsVersion;
@@ -414,7 +416,7 @@ private:
   void __fastcall SetFtpUseMlsd(TAutoSwitch value);
   void __fastcall SetFtpUseMlsd(TAutoSwitch value);
   void __fastcall SetFtpAccount(UnicodeString value);
   void __fastcall SetFtpAccount(UnicodeString value);
   void __fastcall SetFtpPingInterval(int value);
   void __fastcall SetFtpPingInterval(int value);
-  void __fastcall SetFtpPingType(TPingType value);
+  void __fastcall SetFtpPingType(TFtpPingType value);
   void __fastcall SetFtpTransferActiveImmediately(TAutoSwitch value);
   void __fastcall SetFtpTransferActiveImmediately(TAutoSwitch value);
   void __fastcall SetFtps(TFtps value);
   void __fastcall SetFtps(TFtps value);
   void __fastcall SetMinTlsVersion(TTlsVersion value);
   void __fastcall SetMinTlsVersion(TTlsVersion value);
@@ -698,7 +700,7 @@ public:
   __property UnicodeString FtpAccount = { read = FFtpAccount, write = SetFtpAccount };
   __property UnicodeString FtpAccount = { read = FFtpAccount, write = SetFtpAccount };
   __property int FtpPingInterval  = { read=FFtpPingInterval, write=SetFtpPingInterval };
   __property int FtpPingInterval  = { read=FFtpPingInterval, write=SetFtpPingInterval };
   __property TDateTime FtpPingIntervalDT  = { read=GetFtpPingIntervalDT };
   __property TDateTime FtpPingIntervalDT  = { read=GetFtpPingIntervalDT };
-  __property TPingType FtpPingType = { read = FFtpPingType, write = SetFtpPingType };
+  __property TFtpPingType FtpPingType = { read = FFtpPingType, write = SetFtpPingType };
   __property TAutoSwitch FtpTransferActiveImmediately = { read = FFtpTransferActiveImmediately, write = SetFtpTransferActiveImmediately };
   __property TAutoSwitch FtpTransferActiveImmediately = { read = FFtpTransferActiveImmediately, write = SetFtpTransferActiveImmediately };
   __property TFtps Ftps = { read = FFtps, write = SetFtps };
   __property TFtps Ftps = { read = FFtps, write = SetFtps };
   __property TTlsVersion MinTlsVersion = { read = FMinTlsVersion, write = SetMinTlsVersion };
   __property TTlsVersion MinTlsVersion = { read = FMinTlsVersion, write = SetMinTlsVersion };

+ 4 - 4
source/core/SessionInfo.cpp

@@ -1267,20 +1267,20 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
     ADF(L"Transfer Protocol: %s", (Data->FSProtocolStr));
     ADF(L"Transfer Protocol: %s", (Data->FSProtocolStr));
     if (Data->UsesSsh || (Data->FSProtocol == fsFTP))
     if (Data->UsesSsh || (Data->FSProtocol == fsFTP))
     {
     {
-      TPingType PingType;
+      UnicodeString PingType;
       int PingInterval;
       int PingInterval;
       if (Data->FSProtocol == fsFTP)
       if (Data->FSProtocol == fsFTP)
       {
       {
-        PingType = Data->FtpPingType;
+        PingType = EnumName(Data->FtpPingType, FtpPingTypeNames);
         PingInterval = Data->FtpPingInterval;
         PingInterval = Data->FtpPingInterval;
       }
       }
       else
       else
       {
       {
-        PingType = Data->PingType;
+        PingType = EnumName(Data->PingType, PingTypeNames);
         PingInterval = Data->PingInterval;
         PingInterval = Data->PingInterval;
       }
       }
       ADF(L"Ping type: %s, Ping interval: %d sec; Timeout: %d sec",
       ADF(L"Ping type: %s, Ping interval: %d sec; Timeout: %d sec",
-        (EnumName(PingType, PingTypeNames), PingInterval, Data->Timeout));
+        (PingType, PingInterval, Data->Timeout));
       ADF(L"Disable Nagle: %s",
       ADF(L"Disable Nagle: %s",
         (BooleanToEngStr(Data->TcpNoDelay)));
         (BooleanToEngStr(Data->TcpNoDelay)));
     }
     }

+ 18 - 2
source/forms/SiteAdvanced.cpp

@@ -302,10 +302,15 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
     PingIntervalSecEdit->AsInteger = FSessionData->PingInterval;
     PingIntervalSecEdit->AsInteger = FSessionData->PingInterval;
     switch (FSessionData->FtpPingType)
     switch (FSessionData->FtpPingType)
     {
     {
-      case ptDummyCommand:
+      case fptDummyCommand0:
+      case fptDummyCommand:
         FtpPingDummyCommandButton->Checked = true;
         FtpPingDummyCommandButton->Checked = true;
         break;
         break;
 
 
+      case fptDirectoryListing:
+        FtpPingDirectoryListingButton->Checked = true;
+        break;
+
       default:
       default:
         FtpPingOffButton->Checked = true;
         FtpPingOffButton->Checked = true;
         break;
         break;
@@ -499,7 +504,18 @@ void __fastcall TSiteAdvancedDialog::SaveSession(TSessionData * SessionData)
     SessionData->PingType = ptOff;
     SessionData->PingType = ptOff;
   }
   }
   SessionData->PingInterval = PingIntervalSecEdit->AsInteger;
   SessionData->PingInterval = PingIntervalSecEdit->AsInteger;
-  SessionData->FtpPingType = (FtpPingDummyCommandButton->Checked ? ptDummyCommand : ptOff);
+  if (FtpPingDummyCommandButton->Checked)
+  {
+    SessionData->FtpPingType = fptDummyCommand;
+  }
+  else if (FtpPingDirectoryListingButton->Checked)
+  {
+    SessionData->FtpPingType = fptDirectoryListing;
+  }
+  else
+  {
+    SessionData->FtpPingType = fptOff;
+  }
   SessionData->FtpPingInterval = FtpPingIntervalSecEdit->AsInteger;
   SessionData->FtpPingInterval = FtpPingIntervalSecEdit->AsInteger;
   SessionData->Timeout = TimeoutEdit->AsInteger;
   SessionData->Timeout = TimeoutEdit->AsInteger;
 
 

+ 4 - 5
source/forms/SiteAdvanced.dfm

@@ -1224,24 +1224,23 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
             TabOrder = 0
             TabOrder = 0
             OnClick = DataChange
             OnClick = DataChange
           end
           end
-          object FtpPingNullPacketButton: TRadioButton
+          object FtpPingDummyCommandButton: TRadioButton
             Left = 12
             Left = 12
             Top = 42
             Top = 42
             Width = 365
             Width = 365
             Height = 17
             Height = 17
             Anchors = [akLeft, akTop, akRight]
             Anchors = [akLeft, akTop, akRight]
-            Caption = 'Sending of &null SSH packets'
-            Enabled = False
+            Caption = 'Executing &dummy protocol commands'
             TabOrder = 1
             TabOrder = 1
             OnClick = DataChange
             OnClick = DataChange
           end
           end
-          object FtpPingDummyCommandButton: TRadioButton
+          object FtpPingDirectoryListingButton: TRadioButton
             Left = 12
             Left = 12
             Top = 65
             Top = 65
             Width = 365
             Width = 365
             Height = 17
             Height = 17
             Anchors = [akLeft, akTop, akRight]
             Anchors = [akLeft, akTop, akRight]
-            Caption = 'Executing &dummy protocol commands'
+            Caption = '&And additionally reading the current directory'
             TabOrder = 2
             TabOrder = 2
             OnClick = DataChange
             OnClick = DataChange
           end
           end

+ 1 - 1
source/forms/SiteAdvanced.h

@@ -189,7 +189,6 @@ __published:
   TLabel *FtpPingIntervalLabel;
   TLabel *FtpPingIntervalLabel;
   TUpDownEdit *FtpPingIntervalSecEdit;
   TUpDownEdit *FtpPingIntervalSecEdit;
   TRadioButton *FtpPingOffButton;
   TRadioButton *FtpPingOffButton;
-  TRadioButton *FtpPingNullPacketButton;
   TRadioButton *FtpPingDummyCommandButton;
   TRadioButton *FtpPingDummyCommandButton;
   TLabel *Label23;
   TLabel *Label23;
   TComboBox *SftpServerEdit;
   TComboBox *SftpServerEdit;
@@ -284,6 +283,7 @@ __published:
   TLabel *DetachedCertificateLabel;
   TLabel *DetachedCertificateLabel;
   TFilenameEdit *DetachedCertificateEdit;
   TFilenameEdit *DetachedCertificateEdit;
   TCheckBox *S3RequesterPaysCheck;
   TCheckBox *S3RequesterPaysCheck;
+  TRadioButton *FtpPingDirectoryListingButton;
   void __fastcall DataChange(TObject *Sender);
   void __fastcall DataChange(TObject *Sender);
   void __fastcall FormShow(TObject *Sender);
   void __fastcall FormShow(TObject *Sender);
   void __fastcall PageControlChange(TObject *Sender);
   void __fastcall PageControlChange(TObject *Sender);