Connection closed after 3600 Seconds

657 views
Skip to first unread message

tm

unread,
Feb 10, 2011, 12:54:38 PM2/10/11
to Python FTP server library - Discussion group
Hello,

First let me say pyftpdlib is amazing. I've had great success with it
an appreciate all the work that has gone into it! I have a question
that came about while doing large file transfers ( > 2 GB) from
Filezilla on Windows Vista (I know, ew) to a Ubuntu 9.10 server. For
some reason, if a file takes longer than 1 hour to upload I get this
message:

Error: Connection closed by server
Error: File transfer failed after transferring 330,891,264 bytes in
3600 seconds

It is a very consistent drop at 3600 seconds and I am wondering if
there is a setting in pyftpdlib that I'm missing. I've wailed around
trying to create my own timeouts but it doesn't seem to have any
effect on the 3600 second time out:

....

class MyDTPHandler(ftpserver.DTPHandler):
timeout = 864000000

if __name__ == "__main__":

....
handler.dtp_handler = MyDTPHandler
....
ftpd = ftpserver.FTPServer(address, handler)
ftpd.serve_forever(timeout=600000)


I'm sure I'm missing something, but I'm not sure if the server is the
one closing the connection, or the client has something to do with
it. Any help would be greatly appreciated!

Kindest Regards,

tm

Giampaolo Rodolà

unread,
Feb 10, 2011, 1:16:08 PM2/10/11
to pyft...@googlegroups.com, tmug...@gmail.com
Hi,
by default the data connection is supposed to timeout after 300
seconds (5 minutes) of inactivity.
By "inactivity" I mean that the data transfer stall with no progress
(hence no sending/receiving) for over 300 seconds, in which case the
client gets disconnected.
Is the server expressively replying with "421 data connection timeout"?
Please paste the server output if you think this might help.

Also, assuming this is not a bug with pyftpdlib, the only other reason
I see is that it's the client which suddenly stops transmitting data,
in which case the server is doing the right thing.


--- Giampaolo

2011/2/10 tm <tmug...@gmail.com>:

> --
> You received this message because you are subscribed to the "Python FTP server library" project group:
> http://code.google.com/p/pyftpdlib/
> To post to this group, send email to pyft...@googlegroups.com
> To unsubscribe from this group, send email to pyftpdlib-...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/pyftpdlib

tm

unread,
Feb 11, 2011, 12:17:15 PM2/11/11
to Python FTP server library - Discussion group
Awesome, thanks for the insight. The transfer is not stalling but it
seems like it might be related to the control signal. I pinged the
FileZilla boards and they said they use "TCP keep-alive which, in
accordance to the TCP specifications, is sent every two hours. As
such, a NAT router or firewall that drops a connection that it idle
for less than 2 hours and 4 minutes is considered broken as it does
not adhere to the specs." I'm uploading to an EC2 instance which
hosts my pyftpdlib server. I have reached out to Amazon to see if
this is in fact true, and if it is I want to ask:

Is there a way to send keep alives on the control signal from the
pyftpdlib side?




On Feb 10, 1:16 pm, Giampaolo Rodolà <g.rod...@gmail.com> wrote:
> Hi,
> by default the data connection is supposed to timeout after 300
> seconds (5 minutes) of inactivity.
> By "inactivity" I mean that the data transfer stall with no progress
> (hence no sending/receiving) for over 300 seconds, in which case the
> client gets disconnected.
> Is the server expressively replying with "421 data connection timeout"?
> Please paste the server output if you think this might help.
>
> Also, assuming this is not a bug with pyftpdlib, the only other reason
> I see is that it's the client which suddenly stops transmitting data,
> in which case the server is doing the right thing.
>
> --- Giampaolo
>
> 2011/2/10 tm <tmugav...@gmail.com>:

tm

unread,
Feb 11, 2011, 1:35:36 PM2/11/11
to Python FTP server library - Discussion group
Ok, If I set the type to active in FileZilla the upload completes.
I'm guessing something with passive uploads is not keeping the control
channel alive. The reason it worked in WinSCP is because it defaults
to Active. I'll keep digging since I can't expect my users to set
active vs. passive all the time, but it's a stop gap for now.

Giampaolo Rodolà

unread,
Feb 11, 2011, 9:47:25 PM2/11/11
to pyft...@googlegroups.com
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) should do the trick.
I'm not sure whether you have to do this on control connection, data
connection or both of them.
Either way this is how you do it to both (not tested):


import socket
from pyftpdlib import ftpserver


class DTPHandler(ftpserver.DTPHandler):

def __init__(self, sock, cmd_channel):
ftpserver.DTPHandler.__init__(self, sock, cmd_channel)
if self.connected:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)


class FTPHandler(ftpserver.FTPHandler):

dtp_handler = CustomizedDTPHandler

def __init__(self, conn, server):
ftpserver.FTPHandler.__init__(self, conn, server)
if self.connected:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)


authorizer = ftpserver.DummyAuthorizer()
authorizer.add_user('user', '12345', homedir='.', perm='elradfmw')
handler = FTPHandler
handler.authorizer = authorizer
server = ftpserver.FTPServer(("", 21), handler)
server.serve_forever()

Let me know if it helps,

--- Giampaolo


2011/2/11 tm <tmug...@gmail.com>:

Giampaolo Rodolà

unread,
Feb 11, 2011, 10:11:33 PM2/11/11
to pyft...@googlegroups.com, tmug...@gmail.com
By reading here and there it seems (although I'm not completely sure)
that SO_KEEPALIVE must be set before creating the socket, hence before
connect() and bind() calls.
In this case you have to subclasss ActiveDTP and PassiveDTP classes
instead, but first let me know if the code above works.

---- Giampaolo

2011/2/12 Giampaolo Rodolà <g.ro...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages