2
votes

I'm working on a simple ftp server in c. I don't know when ftp server accepts passive data connection from client. To my understanding here is how passive ftp works:

  1. client sends "PASV" command to server
  2. server creates and binds a socket, and listens on a random port.
  3. server uses getsockname to get random port
  4. assemble passive reply message in format: 227 Entering Passive Mode(a1,a2,a3,a4,a5,a6). Note: server ip is a1.a2.a3.a4 and port number is: a5 * 256 + a6.

my question is: when does ftp server accepts the connection to said random port? should server accept data connection after sending reply? or should ftp server accept connection right before data connection is required, i.e. when client is requesting a file?

I have RFC959. is there any other useful ftp resource out there? google is not particularly helpful.

thanks in advance

3

3 Answers

5
votes

I would have the server start accepting connections on that port (by calling listen()) before sending the 227 reply. If you wait until after sending the 227, the client may try to connect before you're accepting connections, and get a "connection refused" error.

After calling listen() which starts the TCP system listening, you can call accept() whenever you're ready to start accepting connections. When to call that is an application-level decision (but obviously once the client sends a data transfer command, it will want to connect). Connections from the client will wait in an accept queue until the server actually calls accept(), which removes them from the accept queue.

1
votes

It will open this port only when a transfer is required by the client. The server (which must know its own external IP address) will then tell the client where to connect, including IP (4 bytes) and port (in 2 separated bytes) so it can transfer the data. Something in this format:

printf("227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\n",
(unsigned int)((my_ip >> 24) & 0xff),
(unsigned int)((my_ip >> 16) & 0xff),
(unsigned int)((my_ip >> 8) & 0xff),
(unsigned int)(my_ip & 0xff),
(unsigned int)(this_session->pasv_port >> 8),
(unsigned int)(this_session->pasv_port & 0xff));

The port is used when user requires a LIST, RETR, STOR or some other transfering.

I guess the client in passive mode will require PASV always before any LIST, RETR or STOR, to do concurrent transfers.

I recommend you installing and studying FileZilla Client and Server. They both show up all the raw FTP talking so you can comprehend whats going on and what should happen for your program.

0
votes

IMHO, the best resource on implementing FTP is http://cr.yp.to/ftp.html

There are also more recent FTP RFCs that you might find useful: