So port is not unique by machine at all?

5

1

$ lsof

memcached 15844 root   28u  IPv6     113604       TCP *:11051 (LISTEN)
memcached 15844 root   29u  IPv4     113605       TCP *:11051 (LISTEN)
memcached 15844 root   30u  IPv6     113609       UDP *:11051 
memcached 15844 root   31u  IPv4     113610       UDP *:11051 

Is it by IP, by protocol or by any other dimensions?

gdb

Posted 2011-04-06T07:26:36.533

Reputation:

4You can have both IPv6 and IPv4 listening on the same port. You can have both UDP and TCP listening on the same port. And combinations thereof. – Rafał Dowgird – 2011-04-06T07:31:16.990

@Rafal Dowgird,are the 4 combinations complete? – None – 2011-04-06T07:32:42.980

2Umm, there's also the network interface (e.g. two different apps may listen on IPv4 TCP port 9000 on two different network interfaces). – Rafał Dowgird – 2011-04-06T07:38:12.373

@Rafal Dowgird,are all protocols included in TCP/UDP family? Why the above output by lsof doesn't show which network interface it's using? – None – 2011-04-06T07:42:35.827

@gdb: Here lsof shows "*" as the interface, which means "all available". I don't quite understand the question about all protocols included in the TCP/UDP family. – Rafał Dowgird – 2011-04-06T07:52:25.247

@Rafal Dowgird,that question can be rephrased as:is it true that if one protocol is not TCP,then it's UDP? – None – 2011-04-06T07:59:01.860

1

@Rafal Dowgird: Other than TCP and UDP, it could be SCTP. http://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol

– Mikel – 2011-04-06T10:51:17.827

Answers

4

The same port number can be used once for TCP and once for UDP, and each of these exists on IPv4 and IPv6.

TCP and UDP port numbers are an entirely different number spaces, they just happen to be assigned in pairs and applications that need both usually use the same number on each.

IPv4 and IPv6 are somewhat distinct protocols; in principle, an IPv6 application can accept IPv4 connections, but it is generally considered good style to have two separate sockets.

Simon Richter

Posted 2011-04-06T07:26:36.533

Reputation: 2 384

Are you sure that port has no other dimensions/coordinations? – None – 2011-04-06T07:35:48.940

As Rafał mentioned, you can bind sockets to specific interfaces; whether multiple sockets with the same protocol and port on different interfaces are permitted depends on the IP stack implementation. Also, I think there are IPsec implementations that allow binding a port so that only authenticated traffic is accepted; again, depending on the implementation, this may but need not conflict with a binding that accepts only unauthenticated traffic. In short, there is no exhaustive list, as you can always invent some exception to the rule. – Simon Richter – 2011-04-06T07:47:08.710

1Is it per interface or per local address? I thought it was per address. – Mikel – 2011-04-06T11:00:11.347

1For TCP (when using bind() in BSD Sockets) it's per local address. – user1686 – 2011-04-06T11:56:21.883

Again, implementation defined. grawity is correct about the BSD implementation. – Simon Richter – 2011-04-06T14:42:33.913

3

Each entry in the netstat or lsof -i output is called a socket.

Each socket is made unique by a combination of:

  • protocol family (e.g. IPv4 or IPv6)
  • protocol (e.g. TCP or UDP)
  • local address
  • local port
  • remote address
  • remote port

This combination of variables is called the connection tuple.

Consider ssh.

If your machine is running sshd, you will see an entry in the netstat output for the server that is running on port 22, listening and waiting for new connections.

# netstat -tnl | grep 22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN

But you will also see entries for each active connection.

# netstat -tn
tcp        0      0 192.168.x.y:22          192.168.x.a:ppppp       ESTABLISHED
tcp        0      0 192.168.x.y:22          192.168.x.b:qqqqq       ESTABLISHED

So the above output shows port 22 is being used 3 times on the same machine.

In this case, each connection is unique because each one has a different remote address or port. Note that even if only one of those is different, it still makes the socket unique.

But it can also be unique by local address or port.

For example, you could be using Apache IP-based virtual hosts to show a different site depending on the host name or IP address:

# netstat -tnlp | grep 80
tcp        0      0 1.2.3.4:80              0.0.0.0:*               LISTEN      9876/apache2
tcp        0      0 1.2.3.5:80              0.0.0.0:*               LISTEN      9876/apache2

Here, there are two sockets listening on port 80.

In this example, if traffic comes in with a destination address of 1.2.3.4, it will be delivered to the first socket; if the destination is 1.2.3.5 it goes to the second one.

The server has to do this explicitly however. The default for a server is to set the local address to 0.0.0.0, also written *, which means there will only be one listening socket on that port, and it will accept all incoming traffic on that port.

As you have discovered, it is also unique per protocol.

For example, the BIND DNS server uses both TCP and UDP:

# netstat -nlp | grep named
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      567/named
tcp        0      0 192.168.x.y:53          0.0.0.0:*               LISTEN      567/named
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      567/named
udp        0      0 127.0.0.1:53            0.0.0.0:*                           567/named
udp        0      0 192.168.x.y:53          0.0.0.0:*                           567/named

Each connection is also unique per protocol family, meaning IPv4 and IPv6 can be distinct.

This depends on whether the programmer asked for an IPv4-only socket, an IPv6-only socket, or a combined IPv4/IPv6 socket.

On Linux an IPv6 socket also accepts IPv4 traffic unless the programmer tells it not to, and therefore only appears once in the netstat output.

$ port=55555
$ nc -6 -l $port || echo "Error listening on port $port" &
$ netstat -tnl | grep $port
tcp6       0      0 :::55555                :::*                    LISTEN     
$ nc -z 127.0.0.1 $port && echo "Port $port is accepting IPv4 connections"
Port 55555 is accepting IPv4 connections

But the memcached source code shows it is explicitly asking for an IPv6-only socket, which is why IPv4 and IPv6 appear separately in your example.

error = setsockopt(sfd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));

Mikel

Posted 2011-04-06T07:26:36.533

Reputation: 7 890