Почему lsof показывает, что мой сокет IPv4 — это IPv6?

Почему lsof показывает, что мой сокет IPv4 — это IPv6?

Я смотрю на вывод lsof -i и начинаю путаться! Например, следующее соединение между моим процессом java и базой данных отображается как IPv6:

[me ~] % lsof  -P -n -i :2315 -a -p xxxx
COMMAND  PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME
java    xxxx   me   93u  IPv6 2499087197      0t0  TCP 192.168.0.1:16712->192.168.0.2:2315 (ESTABLISHED)

Итак, тип вывода — IPv6, но в столбце NAME явно указан адрес IPv4. Более того, соединение было настроено с адресом IPv4! (В этом примере — 192.168.0.2)

Большое спасибо за любую информацию!

решение1

В Linux сокеты IPv6 могут быть как IPv4, так и IPv6 одновременно. Сокет IPv6 может также принимать пакеты отIPv6-адрес, сопоставленный с IPv4.

Эта функция управляется IPV6_V6ONLYопцией сокета, которая по умолчанию управляется net.ipv6.bindv6onlysysctl ( /proc/sys/net/ipv6/bindv6only). По умолчанию она равна 0 (т.е. выключена) в большинстве дистрибутивов Linux.

Это можно легко воспроизвести с помощью:

[prompt] nc -6 -l 9999 & nc -4 localhost 9999 &
[4] 10892
[5] 10893
[prompt] lsof -P -n -i :9999
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nc      10892    x    3u  IPv6 297229      0t0  TCP *:9999 (LISTEN)
nc      10892    x    4u  IPv6 297230      0t0  TCP 127.0.0.1:9999->127.0.0.1:41472 (ESTABLISHED)
nc      10893    x    3u  IPv4 296209      0t0  TCP 127.0.0.1:41472->127.0.0.1:9999 (ESTABLISHED)
[prompt] kill %4 %5

Клиентский сокет — IPv4, а серверный сокет — IPv6, и они соединены.

Связанный контент