Cada entrada en la salida netstat
o lsof -i
se llama socket .
Cada toma se hace única por una combinación de:
- familia de protocolos (por ejemplo, IPv4 o IPv6)
- protocolo (por ejemplo, TCP o UDP)
- dirección local
- puerto local
- dirección remota
- Puerto remoto
Esta combinación de variables se llama tupla de conexión .
Considere ssh
.
Si su máquina está funcionando sshd
, verá una entrada en la netstat
salida del servidor que se está ejecutando en el puerto 22
, escuchando y esperando nuevas conexiones.
# netstat -tnl | grep 22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
Pero también verá entradas para cada conexión activa.
# 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
Entonces, la salida anterior muestra que el puerto 22
se está utilizando 3 veces en la misma máquina.
En este caso, cada conexión es única porque cada una tiene una dirección remota o puerto diferente. Tenga en cuenta que incluso si solo uno de ellos es diferente, todavía hace que el socket sea único.
Pero también puede ser único por dirección local o puerto.
Por ejemplo, podría estar utilizando hosts virtuales basados en IP de Apache para mostrar un sitio diferente según el nombre de host o la dirección IP:
# 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
Aquí, hay dos sockets escuchando en el puerto 80.
En este ejemplo, si el tráfico entra con una dirección de destino de 1.2.3.4, se entregará al primer socket; si el destino es 1.2.3.5, va al segundo.
Sin embargo, el servidor tiene que hacer esto explícitamente. El valor predeterminado para un servidor es establecer la dirección local en 0.0.0.0
, también escrita *
, lo que significa que solo habrá un socket de escucha en ese puerto y aceptará todo el tráfico entrante en ese puerto.
Como has descubierto, también es único por protocolo.
Por ejemplo, el servidor DNS BIND usa TCP y 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
Cada conexión también es única por familia de protocolos, lo que significa que IPv4 e IPv6 pueden ser distintos.
Esto depende de si el programador solicitó un zócalo solo IPv4, un zócalo solo IPv6 o un zócalo combinado IPv4 / IPv6.
En Linux, un socket IPv6 también acepta tráfico IPv4 a menos que el programador se lo indique y, por lo tanto, solo aparece una vez en la netstat
salida.
$ 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
Pero el código fuente de Memcached muestra que está pidiendo explícitamente un socket solo IPv6, por lo que IPv4 e IPv6 aparecen por separado en su ejemplo.
error = setsockopt(sfd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));