70

Listening to TCP port 0 allocates a free port number on the system for me.

But what happens when I try to connect to TCP port 0? The obvious answer is: "It doesn't work":

$ nc localhost 0                 
nc: port number too small: 0

Where in the system is this handled? In the TCP stack of the OS kernel? Are there Unixes where connecting to TCP port 0 would work?

Matthias Braun
  • 7,797
  • 7
  • 45
  • 54
nh2
  • 1,611
  • 2
  • 14
  • 22
  • 2
    In theory you could build a custom TCP stack in which listening on or connecting from port 0 works, which means that two such implementations could talk to each other on port 0. – Joshua Jan 22 '15 at 22:02

3 Answers3

68

Just to make sure we're on the same page (your question is ambiguous this way), asking to bind TCP on port 0 indicates a request to dynamically generate an unused port number. In other words, the port number you're actually listening on after that request is not zero. There's a comment about this in [linux kernel source]/net/ipv4/inet_connection_sock.c on inet_csk_get_port():

/* Obtain a reference to a local port for the given sock,
 * if snum is zero it means select any available local port.
 */

Which is a standard Unix convention. There could be systems that will actually allow the use of port 0, but that would be considered a bad practice. This behaviour is not officially specified by POSIX, IANA, or the TCP protocol, however.1 You may find this interesting.

That's why you cannot sensibly make a TCP connection to port zero. Presumably nc is aware of this and informs you you're making a nonsensical request. If you try this in native code:

int fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = 0;
inet_aton("127.0.0.1", &addr.sin_addr);
if (connect(fd, (const struct sockaddr*)&addr, sizeof(addr)) == -1) {
    fprintf(stderr,"%s", strerror(errno));
}    

You get the same error you would trying to connect to any other unavailable port: ECONNREFUSED, "Connection refused". So in reply to:

Where in the system is this handled? In the TCP stack of the OS kernel?

Probably not; it doesn't require special handling. I.e., if you can find a system that allows binding and listening on port 0, you could presumably connect to it.


1. But IANA does refer to port 0 as "Reserved" (see here). Meaning, this port should not be used online. That makes it okay with regard to the dynamic assignment convention (since it won't actually be used). Stipulating that specifically as a purpose would probably be beyond the scope of IANA; in essence, operating systems are free to do what they want with it, including nothing.

Matthias Braun
  • 7,797
  • 7
  • 45
  • 54
goldilocks
  • 86,451
  • 30
  • 200
  • 258
  • It looks like the same idea as address 0.0.0.0 in ipv4. A reserved value, and used by the OS and programs for a special purpose. As an analogy, in radio there are reserved frequencies that no one uses for transmissions, but are used internally in equipment. – ctrl-alt-delor Jan 22 '15 at 19:09
  • 1
    @richard no, 0.0.0.0 has a different meaning ;) it is used to designate an invalid, unknown or non applicable target or as "broadcast" – AndreaCi Jan 22 '15 at 19:54
  • 2
    @AndreaCi wasn't broadcast 255.255.255.255? – ratchet freak Jan 22 '15 at 20:54
  • 4
    @ratchetfreak 255.255.255.255 is broadcast. 0.0.0.0 has two meanings depending on context. In programming it's synonymous w/ `INADDR_ANY`, which is what richard is referring to (the system will replace it with a default). But actually using the address on a network seems to have the implications Andrea mentions (except not so clear that it counts as "broadcast"): http://en.wikipedia.org/wiki/0.0.0.0 – goldilocks Jan 22 '15 at 21:07
  • +1 @ratchetfreak for using the word “Wasn't” to refer to an ipv4 address. Long live ipv6. – ctrl-alt-delor Jan 25 '15 at 22:24
  • Is it possible to get the randomly assigned port number somehow? I can image a scenario when the server can listen on a random port and report that port to a central server etc. – yegle Jan 27 '15 at 22:32
  • 2
    @yegle http://stackoverflow.com/questions/4046616/sockets-how-to-find-out-what-port-and-address-im-assigned – goldilocks Feb 02 '15 at 13:56
6

Asking for port 0 triggers the operating system to search for and allocate the next available port. This avoids you having to hard-code a specific port or having to search for an available port. My Linux Mint system returns

nc: port range not valid

to

nc localhost 0
Matthias Braun
  • 7,797
  • 7
  • 45
  • 54
MichaelJohn
  • 413
  • 1
  • 5
  • 17
2

nc -l 0 will ask the OS to listen on port 0. But as has been remarked above, most operating systems will see the 0 and invoke their particular customs for choosing a positive-numbered port for your application, so nc winds up listening on some port like 56514.

don_crissti
  • 79,330
  • 30
  • 216
  • 245
MC17
  • 21
  • 1