Re: lftp/proftpd: ctrl connection close on data reset

"Alexander V. Lukyanov" <[email protected]> Thu, 20 Oct 2005 11:03:02 +0400
Newsgroups gmane.network.lftp.devel
Message-ID <[email protected]>
On Wed, Oct 19, 2005 at 05:04:38PM +0300, Konstantinos Koukopoulos wrote:
> ---- Connecting data socket to (XXX.XXX.XXX.XXX) port 65272
> ---- Data connection established
> ---> NLST
> **** data-socket: Connection reset by peer
> ---- Closing data socket
> ---- Closing control socket
>
> In the source code you have a workaround for the case where proftpd would
> return a 450 error when you NLST a empty directory. In the case above though,
> it seems that lftp decides to call DisconnectNow() when the data socket is
> reset (which happens because proftpd writes nothing to the data socket and
> just returns 450). This totally breaks mirroring so I've found a small
> workaround, which I've attached as a patch against the lftp-3.3.2 source
> code. With the patch applied I get the following correct behaviour:

I think attached fix would be more correct. It delays error checking on data
connection to after receiving error code on control connection. Please test.

--
   Alexander.
diff (text/plain, 932 B)
Index: ftpclass.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ftpclass.cc,v
retrieving revision 1.362
diff -u -p -r1.362 ftpclass.cc
--- ftpclass.cc	19 Oct 2005 14:13:20 -0000	1.362
+++ ftpclass.cc	20 Oct 2005 07:01:46 -0000
@@ -2197,12 +2197,19 @@ int   Ftp::Do()
          return MOVED;
 
       BumpEventTime(conn->data_iobuf->EventTime());
-      if(conn->data_iobuf->Error())
+      // handle errors on data connection only when storing or got all replies
+      if(conn->data_iobuf->Error() && (mode==STORE || expect->IsEmpty()))
       {
 	 DebugPrint("**** ",conn->data_iobuf->ErrorText(),0);
 	 if(conn->data_iobuf->ErrorFatal())
 	    SetError(FATAL,conn->data_iobuf->ErrorText());
-	 DisconnectNow();
+	 if(!expect->IsEmpty())
+	    DisconnectNow();
+	 else
+	 {
+	    DataClose();
+	    state=EOF_STATE;
+	 }
 	 return MOVED;
       }
       if(mode!=STORE)