Windows использует неправильную область для локальных IPv6-адресов, полученных из DNS
В 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
в выходной)
1 ответ
Вы не можете использовать локальные адреса в DNS.
Использование этих адресов зависит от того, к какой ссылке подключен клиент, и клиенты могут даже подключаться к нескольким ссылкам одновременно (например, ethernet + wifi). Или клиент может быть на совершенно другой ссылке, чем сервер, и адрес, который он получает от DNS, будет совершенно бессмысленным.
Записи DNS не содержат область действия, поскольку области являются локальными для каждого клиента. DNS-сервер не может предоставить значимую область клиенту, поэтому протокол даже не включает область в ответ. Это было бы бессмысленно.
Итак, вкратце: DNS предназначен для адресов глобальной области (включая ULA, если вы хотите использовать локальные адреса)