Назад | Перейти на главную страницу

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 на выходе)

Вы не можете использовать локальные для ссылки адреса в DNS.

Использование этих адресов зависит от того, к какой ссылке подключен клиент, и клиенты могут даже быть подключены к нескольким ссылкам одновременно (например, Ethernet + Wi-Fi). Или клиент может быть на совершенно другой ссылке, чем сервер, и адрес, который он получает от DNS, будет совершенно бессмысленным.

Записи DNS не содержат области, поскольку области являются локальными для каждого клиента. DNS-сервер не имеет возможности предоставить клиенту значимую область действия, поэтому протокол даже не включает область действия в ответ. Это было бы бессмысленно.

Короче говоря: DNS предназначен для адресов глобальной области (включая ULA, если вы хотите использовать локальные адреса)