فهرست منبع

Bug 1381: Timeout when uploading to FTP over TLS and proxy when the FTP server responds with 1xy before proxy connection is processed

https://winscp.net/tracker/1381

Source commit: cea0dcc3302c3601f8306fb7309c8127f1f04b06
Martin Prikryl 9 سال پیش
والد
کامیت
5d0ad2154c
3فایلهای تغییر یافته به همراه44 افزوده شده و 12 حذف شده
  1. 1 1
      source/filezilla/AsyncSocketEx.h
  2. 40 11
      source/filezilla/TransferSocket.cpp
  3. 3 0
      source/filezilla/TransferSocket.h

+ 1 - 1
source/filezilla/AsyncSocketEx.h

@@ -257,7 +257,7 @@ protected:
   int m_nPendingEvents;
   int m_nPendingEvents;
 
 
   int GetState() const;
   int GetState() const;
-  void SetState(int nState);
+  virtual void SetState(int nState);
   static const TCHAR * GetStateDesc(int nState);
   static const TCHAR * GetStateDesc(int nState);
   static bool LogStateChange(int nState1, int nState2);
   static bool LogStateChange(int nState1, int nState2);
 
 

+ 40 - 11
source/filezilla/TransferSocket.cpp

@@ -37,6 +37,7 @@ CTransferSocket::CTransferSocket(CFtpControlSocket *pOwner, int nMode)
   m_transferdata.transferleft = 0;
   m_transferdata.transferleft = 0;
   m_nNotifyWaiting = 0;
   m_nNotifyWaiting = 0;
   m_bShutDown = FALSE;
   m_bShutDown = FALSE;
+  m_bActivationPending = false;
 
 
   UpdateStatusBar(true);
   UpdateStatusBar(true);
 
 
@@ -491,19 +492,47 @@ int CTransferSocket::CheckForTimeout(int delay)
   return 1;
   return 1;
 }
 }
 
 
+void CTransferSocket::SetState(int nState)
+{
+  CAsyncSocketEx::SetState(nState);
+  if (m_bActivationPending && Activate())
+  {
+    m_bActivationPending = false;
+  }
+}
+
+bool CTransferSocket::Activate()
+{
+  // Activation (OnSend => OnConnect) indirectly causes adding
+  // of TLS layer, which needs connected underlying layers.
+  // The code should be generic, but we particularly need it for this (TLS over proxy)
+  // scenario only. So for a safety, we use it for the scenario only.
+  bool Result =
+    (GetState() == connected) || (GetState() == attached) ||
+    (m_pSslLayer == NULL) || (m_pProxyLayer == NULL);
+  if (Result)
+  {
+    if (m_nTransferState == STATE_WAITING)
+      m_nTransferState = STATE_STARTING;
+    m_bCheckTimeout = TRUE;
+    m_LastActiveTime = CTime::GetCurrentTime();
+
+    if (m_nNotifyWaiting & FD_READ)
+      OnReceive(0);
+    if (m_nNotifyWaiting & FD_WRITE)
+      OnSend(0);
+    if (m_nNotifyWaiting & FD_CLOSE)
+      OnClose(0);
+  }
+  return Result;
+}
+
 void CTransferSocket::SetActive()
 void CTransferSocket::SetActive()
 {
 {
-  if (m_nTransferState == STATE_WAITING)
-    m_nTransferState = STATE_STARTING;
-  m_bCheckTimeout = TRUE;
-  m_LastActiveTime = CTime::GetCurrentTime();
-
-  if (m_nNotifyWaiting & FD_READ)
-    OnReceive(0);
-  if (m_nNotifyWaiting & FD_WRITE)
-    OnSend(0);
-  if (m_nNotifyWaiting & FD_CLOSE)
-    OnClose(0);
+  if (!Activate())
+  {
+    m_bActivationPending = true;
+  }
 }
 }
 
 
 void CTransferSocket::OnSend(int nErrorCode)
 void CTransferSocket::OnSend(int nErrorCode)

+ 3 - 0
source/filezilla/TransferSocket.h

@@ -49,12 +49,14 @@ public:
   virtual void OnConnect(int nErrorCode);
   virtual void OnConnect(int nErrorCode);
   virtual void OnClose(int nErrorCode);
   virtual void OnClose(int nErrorCode);
   virtual void OnSend(int nErrorCode);
   virtual void OnSend(int nErrorCode);
+  virtual void SetState(int nState);
 
 
 protected:
 protected:
   virtual int OnLayerCallback(std::list<t_callbackMsg> & callbacks);
   virtual int OnLayerCallback(std::list<t_callbackMsg> & callbacks);
   int ReadDataFromFile(char * buffer, int len);
   int ReadDataFromFile(char * buffer, int len);
   virtual void LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg);
   virtual void LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg);
   virtual void ConfigureSocket();
   virtual void ConfigureSocket();
+  bool Activate();
 
 
   CFtpControlSocket * m_pOwner;
   CFtpControlSocket * m_pOwner;
   CAsyncProxySocketLayer * m_pProxyLayer;
   CAsyncProxySocketLayer * m_pProxyLayer;
@@ -75,6 +77,7 @@ protected:
   int m_nMode;
   int m_nMode;
   int m_nNotifyWaiting;
   int m_nNotifyWaiting;
   BOOL m_bShutDown;
   BOOL m_bShutDown;
+  bool m_bActivationPending;
 
 
   void CloseAndEnsureSendClose(int Mode);
   void CloseAndEnsureSendClose(int Mode);
   void EnsureSendClose(int Mode);
   void EnsureSendClose(int Mode);