Selecting TCP Ports Numbers for Fun, Profit, and Reliability

Blue Bar separator

Why is it that every now and then when you start up your server application you get an error telling you that your server application's port number is already in use? You know there are no other server applications using the port number but when you check, sure enough someone is using it. The strange thing is that it is not another server application; it's a client application, maybe connected to an FTP or telnet server (or for VOS systems, the client portion of OSL).

The Internet Assigned Numbers Authority (IANA) divides the port number range in 3 parts. First there is the well-known port range (1 to 1023). The well-known ports are assigned by IANA to a specific protocol or process. Ports 1024 thru 49151 are called registered ports. IANA will register and list a port and its associated protocol/process. The basic difference between well-known and registered ports is that the documentation requirements for well-known ports are much greater. Also on many systems it takes special access to bind to a well-known port. Ports greater than 49152 are called dynamic or private or ephemeral ports. When an application does not bind a specific port number to its socket the TCP stack will assign the socket a port number from the dynamic port number range. Client applications typically don't assign a specific port number. From the Client's point of view it doesn't matter what port number it uses so it lets the TCP stack automagically assign one. The list of well-known and registered ports can be found on the IANA web site at http://www.iana.org/assignments/port-numbers. Some of you may be familiar with the RFC-1700, which used to hold the list of port assignments. RFC-1700 is obsolete. The RFC publication mechanism was found to be too slow for the timely dissemination of updated port assignments. For example, the port-numbers web page was last updated the day I updated this web page (08-06-27).

How do you register a port? See http://www.iana.org/cgi-bin/sys-port-number.pl to get a well know port and http://www.iana.org/cgi-bin/usr-port-number.pl to get a registered port.

All that's very nice but you want to know what caused the port collision problem I opened this article with? Well, there was a collision because the server application uses a port number from the dynamic port number range and the TCP stack had already assigned that port number to a client application.

Now I can hear all the TCP_OS people saying but, but, but I used port 1030 and STCP and ftServer users are thinking that they used port 12,345. Well TCP_OS, STCP, Linux and ftServer use different ranges than IANA. HP-UX 11x and FTX 3.4 by default use the same ranges as IANA but its possible for someone with access to the root user ID to change the ranges.

To display the current values use the get request in the ndd command:
       $ ndd -get /dev/tcp tcp_smallest_nonpriv_port
       1024
       $ ndd -get /dev/tcp tcp_smallest_anon_port
       49152
       $ ndd -get /dev/tcp tcp_largest_anon_port
       65535

To change the values use the set request. Note that I don't recommend that you change these values, but if for some reason you absolutely have to, this is how:
       # ndd -set /dev/tcp tcp_largest_anon_port 65000

You can also change the upper limit on the ftServer dynamic port range via the HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters registry key MaxUserPort. You can set the value to anything between 5000 and 65534. The default is 5,000. Note that the key does not exist by default so if you want to change it you will probably have to create it first.

There is no way to change the ranges used by TCP_OS and STCP. But starting in releases 14.5.0at, 14.6.0aj and all 14.7 and 15 releases STCP changed the starting point of its dynamic range for TCP ports to conform to the IANA recommendations. This was done when the suggestion stcp-1098 was implemented. STCP's Dynamic UDP port numbers start at 1024 and go up to 65535. stcp-2119 addresses this and suggests that the UDP range also conform to IANA recommendations, starting in VOS release 15.1.0ar, 15.2 and later it does.

Linux 2.2 and earlier used a dynamic range of 1024 thru 4999. In Linux 2.4 and later this was changed to 32768 thru 61000. In both versions of Linux you can change the range. To see the current minimum and maximum values do:
       $cat /proc/sys/net/ipv4/ip_local_port_range
       32768 61000

To change the values just put something else in the file for example to make it conform to the IANA do
       $echo '49152 65535' > /proc/sys/net/ipv4/ip_local_port_range
       $cat /proc/sys/net/ipv4/ip_local_port_range
       49152 65535

Port Ranges for IANA and each TCP stack supported Stratus
 Well Known Ports      Registered            Dynamic      
IANA1 - 10231024 - 4915149152 - 65535
TCP_OS1 - 10235001 - 655351024 - 5000
STCP (TCP pre stcp-1098)1 - 10231024 - 999910000 - 65535
STCP (TCP post stcp-1098)1 - 10231024 - 4915149152 - 65535
STCP (UDP ports)1 - 1024 1025 - 65535
STCP (UDP post stcp-2119)1 - 10231024 - 4915149152 - 65535
HP-UX 11x1 - 10231024 - 4915149152 - 65535
FTX 3.3 (and earlier)1 - 10236124 - 655351024 - 6123
FTX 3.4 (and later)1 - 10231024 - 4915149152 - 65535
ftServer1 - 10245001 - 655351024 - 5000
Linux 2.21 - 10235000 - 655351024 - 4999
Linux 2.4 (and later)1 - 10231024 - 3276732768 - 61000

Is it necessary to contact IANA to get a well-known or registered port number before using it? No, there is nothing that prevents you from using someone else's well-known or registered port number, or an unused number from those ranges for your application. As long as all your clients know what number you are using and you are not using a number that another server on your system is using things will work just fine. If you intend your application to work outside your immediate environment getting your port number registered won't hurt. Also, it never hurts to make sure that you have some way to customize your port number. Even if you go to the trouble of getting a well-known port assigned to your application you may someday find yourself in an environment with another server application that uses the same port number that can't be changed. If your customers can only run 1 application you only have a 50% chance of it being yours. The ability to use a different port number increases the odds significantly.

One more point about the well-known port range on VOS. Originally both TCP_OS and STCP allowed any process to bind to ports in the well-known port range. This was considered a security issue since some systems, notably Unix based, assume that any request from a well-known port is coming from the "root" user. So starting in VOS 14.3 TCP_OS (bug otp-804) requires that processes binding to ports in the well-known port range be privileged. If you absolutely have to have non-privileged processes bind to well-known ports in TCP_OS you can set the external variable allow_unpriv_bind$ to go back to previous, less secure, behavior. For example:

       as: d allow_unpriv_bind$.
       FED9A000 0 00000000
       as: set_word FED9A000 1 -check 0
       addr from to
       FED9A000 0000 0001

This requirement was also added to STCP (bug stcp-1316) starting with releases 14.1.0aq, 14.2.2aa and 14.3, but with a slight twist. Privileged in STCP means that you have write access to the streams device. This is controlled by an access control list on a file. To specify a file name add an access_list_name entry in the device definition of the STCP device, that is:

    / =namestcp.m10
      =module_namem10
      =device_typestreams
      =access_list_namestreams_user <-- add to control well known port access
      =streams_driverstcp
      =clone_limit5120

If it is not already in >system>acl it will automagically be created when you boot. You can then give certain users write access to allow them to bind to well know ports or just read access to prevent it. I do not recommend changing the system_default file.

One final point, many people have thought that adding an entry in the services file will reserve that port number. The services file is a database that allows applications to determine what port they should bind to. A reverse look up is also provided so that given a port number you can find the service name, netstat uses this feature. None of the TCP stacks check the services file before binding a client application to a port.

So in a nutshell when selecting a port number for your server use a number that is in the registered range for the TCP stack that you are using. Or better yet, pick a number in the range 5001 - 9999 and be assured that no matter what Stratus OS you use now or in the future you will never have a collision with a stack assigned dynamic port.

-----------------------------
03-10-21 updated to include information about stcp-1098. All updates are in red.
03-11-13 updated to include FTX 3.3 and earlier (thanks to Gordon Watson for this info)
05-07-29 updated to include information about stcp-2119 and STCP's UDP ports
05-12-21 updated to include Linux 2.2 and later
08-06-27 Converted from a Microsoft Word format to HTML and updated to include changes to STCP's UDP due to the fix for stcp-2119

Blue Bar separator
This page was last modified on 08-06-27
mailbox Send comments and suggestions
to ndav1@cox.net