Please help debug my socket code!

Joe Nelson joe at begriffs.com
Wed Feb 13 06:50:03 UTC 2019


Hey all, I've been stuck on a bug for a few nights now, wondering if you
can help me figure out what's wrong.

I'm writing an FTP server that exposes a git database as if it were a
folder on disk (it's part of a bigger idea). However I'm having trouble
getting the PASV command to work properly.

Here's some context about FTP. When a client connects, they interact
with the FTP server through a "control channel." This is a TCP socket
where the client can issue commands. However when the client wants to
transfer files or get a directory listing they have to open a second
"data" socket. Either the server determines the port number of this
new socket, or the client does. This is called passive or active mode
respectively. Once the port is chosen the server binds it and starts
listening. The client connects to it, then issues the next command such
as LIST on the control channel. The server then sends data through the
data channel.

I've chosen to implement passive mode, which the client initiates with
the PASV command. My server is able to pick a random available port and
send the port value to the client. However when the client tries to
connect it's as if the server isn't listening on that port. Wireshark
shows me that the server responds with [RST ACK], refusing the client
connection. This is super weird to me because I am calling listen() on
the socket as part of my negotiate_listen() function, and I am choosing
a TCP backlog of SOMAXCONN so there should be room in the connection
queue for the client.

Here's the code, I'd love any help debugging.

https://github.com/begriffs/gitftp/blob/master/gitftp.c

To test it, clone the repo, install libgit2, run make, then start the
program with `gitftp .` which will serve its own git repo. The server
runs on port 8021 for now to avoid needing escalated permissions to bind
on 21.  You can connect to it with `ncftp -P 8021 localhost` or `ftp
localhost 8021`. Try running an ls command and (nc)ftp should send a
PASV command but be unable to connect.


More information about the Friends mailing list