Limiting listening socket to a range of available port numbers

I am very close to completing implementation of my FTPS server and client software. One final issue deals with firewalls and NAT. Under SSL the firewall does not provide the normal "assistance" to FTP command channel, such as tweaking NAT, and temporarily opening PASV data ports, which may otherwise be blocked. I have dealt with the NAT issue (each configured listen IP can have a configured "external" IP declared) but now the PORT issue is biting me. I have a couple of ideas.

1) I am thinking I could reserve a range of port numbers based on server configuration. The firewall admin would open those. Problem is I know how to listen on "any port", or a "specific port #", but don't know how to get the socket layer to choose a free port from a range. I also don't know how to query to see if a port is available, except by causing exceptions to be thrown. Maybe that is the only way is my question. Hopefully is there a well prescribed way to find available ports in a range

2) I could listen for data connections on the same port as command channel, typically port 21. I could correlate IP addresses of incoming connections to existing command channel connections, and if I see a duplicate, assume it is an incoming PASV data channel. I suspect there are numerous scenarios where this may fall on its face. But it would simplify life for my firewall admin.




Answer this question

Limiting listening socket to a range of available port numbers

  • C Dunn

    The other thing to keep in mind w.r.t port availability is that
    a given port is not in an ABSOLUTE Available/Non Available state.

    For example
    SourceIP:SourcePort  <-> DestIP:DestPort + Protocol is what the combination that matters

    so for example while the connection is active
    TCP 1.1.1.1:9000 <---> 2.2.2.2:80
    one could open another connection
    TCP 1.1.1.1:9000 <---> 3.3.3.3:80
    because the new combination is unique

    So it is very difficult to say that a "port" is in use. Thats way the bind could succeed the connect could fail -- You see the point :-)



  • Howez

    I would like to know more about the app you are writing and what the scenario is.
    If that can be shared, please send an email to me directly.
    I would really appreciate it

  • gr4nt

    Uhhh, I think so.

    My strategy is to allow the service config to specify a port range. I only need this if there is both a firewall with port blocking involved, and the FTP command channel is SSL. In this case, for the PASV data channel connection, I simply try listening on the ports until I get one that does not throw an exception when I listen. I tried this on known port ranges and it seems to work. It requires the service admin to know what ports are being passed by the firewall of course. But the main point is this approach seems to resolve the contention for ports reliably.

    The window of time for the FTP server to be listening for the negotiated incoming PASV data channel connection is VERY small, but does exist. That is why the range of port #s is needed. I suspect 2 or 3 ports would be plenty even in heavier load conditions, but I have asked admins to allow at least 5.

    In any solution I always TRY to avoid the use of exceptions for expected conditions, sensing conditions, rather than responding to failures. For one, it makes debugging easier. As a general philosophy I believe it is better to utilize objects in a well defined non-error state, that this TENDS to make larger software projects more stable and well behaved.

    But of course it is not always possible, hence the original question.

  • Dimitri Meeuws

    There is no way to specify a port range for a socket.
    You have to bind socket to ANY or a SPECIFIC port.

    There is also no real good way to see if the port is available. Even if you did
    this is not atomic so some other process could use that port in that instant

  • Limiting listening socket to a range of available port numbers