В Windows у меня есть два сетевых интерфейса с индексами 1 и 2 (согласно route print
).
Я хочу пропинговать хост, доступный через интерфейс 2, используя локальный адрес IPv6, скажем, fe80::42
. Это работает:
> ping fe80::42
Pinging fe80::42 with 32 bytes of data:
Reply from fe80::42: time<1ms
> ping fe80::42%2
Pinging fe80::42%2 with 32 bytes of data:
Reply from fe80::42%2: time<1ms
Все идет нормально.
Теперь предположим, что этот интерфейс 2 настроен с суффиксом DNS bar
и с DNS-сервером, который имеет запись для foo.bar
что возвращается fe80::42
. Я ожидал увидеть что-то вроде этого:
> ping /6 foo.bar
Pinging foo.bar [fe80::42%2] with 32 bytes of data:
Reply from fe80::42%2: time<1ms
Но вместо этого я был удивлен, обнаружив, что Windows, похоже, решает неправильную область:
> ping /6 foo.bar
Pinging foo.bar [fe80::42%1] with 32 bytes of data:
Destination host unreachable.
Зачем? Как я могу это исправить, чтобы Windows разрешила foo.bar
к fe80::42%2
не fe80::42%1
?
Версия Windows - 10.0.15063.
Я проверил с помощью сетевого сниффера, что пакеты DNS для разрешения foo.bar
отправляются на правильный DNS-сервер через интерфейс 2, как и настроено.
Наиболее конкретный маршрут IPv6, показанный в route print
четко заявляет, что пакеты собираются fe80::42
должен пройти через интерфейс 2. Обычно я вручную добавил маршрут, который выглядит следующим образом:
If Metric Network Destination Gateway
2 4242 fe80::42/128 On-link
Я не вижу абсолютно никаких причин, по которым Windows выбрала бы интерфейс 1 для всего, что связано с foo.bar
или fe80::42
.
Я независимо подтвердил, что вывод getaddrinfo()
виноват, создав и запустив пример программы из MSDN (немного изменено):
Calling getaddrinfo with following parameters:
nodename = foo.bar
servname (or port) = 0
getaddrinfo returned success
getaddrinfo response 1
Flags: 0x0
Family: AF_INET6 (IPv6)
IPv6 address fe80::42%1
Scope information: Zone 1 Level 0
Socket type: SOCK_STREAM (stream)
Protocol: IPPROTO_TCP (TCP)
Length of this sockaddr: 28
Canonical name: (null)
(Обратите внимание %1
и Zone 1
на выходе)
Вы не можете использовать локальные для ссылки адреса в DNS.
Использование этих адресов зависит от того, к какой ссылке подключен клиент, и клиенты могут даже быть подключены к нескольким ссылкам одновременно (например, Ethernet + Wi-Fi). Или клиент может быть на совершенно другой ссылке, чем сервер, и адрес, который он получает от DNS, будет совершенно бессмысленным.
Записи DNS не содержат области, поскольку области являются локальными для каждого клиента. DNS-сервер не имеет возможности предоставить клиенту значимую область действия, поэтому протокол даже не включает область действия в ответ. Это было бы бессмысленно.
Короче говоря: DNS предназначен для адресов глобальной области (включая ULA, если вы хотите использовать локальные адреса)