Определение того, когда следует попробовать подключение IPv6, а когда использовать IPv4

StackOverflow https://stackoverflow.com/questions/1350592

  •  20-09-2019
  •  | 
  •  

Вопрос

Я работаю над сетевой клиентской программой, которая подключается к общедоступным серверам, указанным пользователем.Если пользователь предоставляет мне имя хоста для подключения, у которого есть адреса IPv4 и IPv6 (обычно это DNS-имя с обоими A и AAAA записи), я не уверен, как мне следует решать, к какому адресу мне следует подключиться.

Проблема в том, что довольно часто компьютеры поддерживают как IPv4, так и IPv6, но только для того, чтобы иметь глобальное подключение по IPv4.Наиболее распространенным случаем этого является настройка только локальных адресов IPv6-канала.На данный момент лучшими альтернативами, которые я могу предложить, являются:

  1. Сначала попробуйте использовать IPv6-адреса - если соединение не удается установить, попробуйте использовать IPv4-адреса;или
  2. Просто позвольте пользователю указать это в качестве параметра конфигурации ("prefer_ipv6" вместо "prefer_ipv4").

Проблема, которую я вижу с вариантом 1, заключается в том, что соединение может прерваться не сразу - для тайм-аута может потребоваться довольно много времени.

Это было полезно?

Решение

Пожалуйста, попробуйте использовать IPv6.В значительном большинстве установок при попытке создать соединение IPv6 будет сразу же потерпите неудачу, если по какой-то причине это не удастся:

  • если система не поддерживает сокеты IPv6, создание сокета завершится неудачей
  • если система поддерживает IPv6 и настроила локальные адреса связи, в таблице маршрутизации не будет никаких записей для глобальных адресов IPv6.Опять же, локальное ядро сообщит о сбое без отправки каких-либо пакетов.
  • если у системы действительно есть глобальный IP-адрес, но какая-либо ссылка, необходимая для маршрутизации, отсутствует, источник следует получает сообщение об ошибке ICMPv6, указывающее, что пункт назначения не может быть достигнут;аналогично, если у получателя есть IPv6-адрес, но служба его не прослушивает.

Конечно, бывают случаи, когда что-то может сломаться, напримересли настроен глобальный (или туннельный) адрес, и что-то ошибочно отфильтровывает сообщения об ошибках ICMPv6.Вам не стоит беспокоиться об этом случае - возможно, и к лучшему, что подключение по IPv4 каким-то образом нарушено.

Конечно, спорно, действительно ли вам нужно использовать IPv6-адреса Первый - с таким же успехом ты мог бы попробовать их во второй раз.В общем, вы должны пробовать адреса в том порядке, в котором они возвращаются из getaddrinfo.Сегодня системы поддерживают параметры конфигурации, которые позволяют администраторам решать, в каком порядке адреса должны быть возвращены из getaddrinfo.

Другие советы

После заданного вопроса IETF предложил ответ на этот вопрос: RFC6555, он же Счастливые глаза.

Соответствующим моментом является то, что клиент и сервер могут иметь IPv4 и IPv6, но промежуточный переход может отсутствовать, поэтому невозможно надежно предсказать, какой путь будет работать.

Вам следует пусть общесистемная конфигурация решает благодаря getaddrinfo().Точно так же, как это делает Java.Просить каждое отдельное приложение попытаться обслужить каждую возможную (неправильную) конфигурацию IPv6 на самом деле невозможно масштабировать!В случае неправильной конфигурации пользователю будет гораздо удобнее, если все или ничего приложения ломаются.

С другой стороны, вы хотите попытаться бревно обильное количество раздражающих задержек и тайм-аутов, поэтому пользователи могут быстро определить, в чем виновата.Как и любые другие задержки в идеале, включая (очень распространенные) тайм-ауты DNS.

Этот в разговоре есть решение.Обобщить;

  • Иногда возникают проблемы либо с поиском DNS, либо с последующим подключением к разрешенному адресу.
  • Вы не хотите ждать, пока истечет время ожидания подключения к адресу IPv6, прежде чем подключаться к адресу IPv4, или наоборот.
  • Вы не хотите ждать, пока истечет время ожидания поиска записи AAAA, прежде чем искать запись A, или наоборот.
  • Вы не хотите останавливаться в ожидании записей AAAA и A, прежде чем пытаться подключиться к той записи, которую вы получите первой.

Решение состоит в том, чтобы искать записи AAAA и A одновременно и независимо, а также независимо подключаться к разрешенным адресам.Используйте любое соединение, которое будет успешным в первую очередь.


Самый простой способ сделать это — позволить сетевому API сделать это за вас, используя сетевые API подключения по имени.Например, в Java:

InetSocketAddress socketAddress = new InetSocketAddress("www.example.com", 80);
SocketChannel channel = SocketChannel.open(socketAddress);
channel.write(buffer);

В примечаниях к слайдам на этом этапе говорится:

Здесь мы производим непрозрачный объект, называемый inetsocketaddress от хоста и порта, а затем, когда мы открываем этот новичок, который может заполнять под обложками, делая все необходимое, если приложение никогда не видит IP -адрес.

Windows также имеет API-интерфейсы подключения по имени.У меня нет фрагментов кода для тех, кто здесь.

Теперь я не говорю, что все реализации этих API обязательно делают правильные вещи сегодня, но если приложения используют эти API, то реализации могут быть улучшены с течением времени.

Распределение с GetAddrinfo () и аналогичным API заключается в том, что они принципиально не могут быть улучшены с течением времени.Определение API заключается в том, что они возвращают вам полный список адресов, поэтому им приходится ждать, пока у них не будет этот полный список, чтобы дать вам.Нет никакого способа, чтобы GetAddrinfo не сможет вернуть вам частичный список, а затем дать вам еще немного.

Некоторые идеи:

  1. Разрешить пользователю указывать предпочтения для каждого сайта отдельно.
  2. Сначала попробуйте IPv4.
  3. Попытайтесь использовать IPv6 параллельно при первом подключении.
  4. При последующих подключениях используйте IPv6, если ранее подключение было успешным.

Я предлагаю сначала попробовать IPv4, потому что этот протокол лучше разработан и протестирован.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top