Литмир - Электронная Библиотека
Содержание  
A
A

На рис. 12.2 показано, как обрабатывается полученная дейтаграмма IPv4 или IPv6 в зависимости от типа принимающего сокета для TCP и UDP. Предполагается, что это узел с двойным стеком.

UNIX: разработка сетевых приложений - img_90.png

Рис. 12.2. Обработка полученных дейтаграмм IPv4 или IPv6 в зависимости от типа принимающего сокета

■ Если дейтаграмма IPv4 приходит на сокет IPv4, ничего особенного не происходит. На рисунке изображены две стрелки, помеченные «IPv4»: одна для TCP, другая для UDP. Между клиентом и сервером происходит обмен дейтаграммами IPv4.

■ Если дейтаграмма IPv6 приходит на сокет IPv6, ничего особенного не происходит. На рисунке изображены две стрелки, помеченные «IPv6»: одна для TCP. другая для UDP. Между клиентом и сервером происходит обмен дейтаграммами IPv6.

■ Когда дейтаграмма IPv4 приходит на сокет IPv6, ядро возвращает соответствующий адрес IPv4, преобразованный к виду IPv6, в качестве адреса, возвращаемого функцией accept (TCP) или recvfrom (UDP). На рисунке это показано двумя штриховыми стрелками. Такое сопоставление возможно, поскольку адрес IPv4 можно всегда представить как адрес IPv6. Между клиентом и сервером происходит обмен дейтаграммами IPv4.

■ Обратное неверно: поскольку, вообще говоря, адрес IPv6 нельзя представить как адрес IPv4, на рисунке отсутствуют стрелки от протокола IPv6 к двум сокетам IPv4.

Большинство узлов с двойным стеком должны использовать следующие правила обращения с прослушиваемыми сокетами:

1. Прослушиваемый сокет IPv4 может принимать соединения только от клиентов IPv4.

2. Если у сервера есть прослушиваемый сокет IPv6, связанный с универсальным адресом, и параметр сокета IPV6_V6ONLY (см. раздел 7.8) не установлен, этот сокет может принимать исходящие соединения как от клиентов IPv4, так и от клиентов IPv6. Для соединения с клиентом IPv4 локальный адрес сервера для соединения будет соответствующим адресом IPv4, преобразованным к виду IPv6.

3. Если у сервера есть прослушиваемый сокет IPv6, связанный с адресом IPv6, не являющимся адресом IPv4, преобразованным к виду IPv6, или его сокет связан с универсальным адресом при установленном параметре сокета IPV6_V6ONLY (раздел 7.8), этот сокет может принимать исходящие соединения только от клиентов IPv6.

12.3. Клиент IPv6, сервер IPv4

Теперь мы поменяем протоколы, используемые клиентом и сервером в примере из предыдущего раздела. Сначала рассмотрим TCP-клиент IPv6, запущенный на узле с двойным стеком протоколов.

1. Сервер IPv4 запускается на узле, поддерживающем только IPv4, и создает прослушиваемый сокет IPv4.

2. Запускается клиент IPv6 и вызывает функцию

gethostbyname
, запрашивая только адреса IPv6 (запрашивает семейство
AF_INET6
и устанавливает флаг
AI_V4MAPPED
в структуре
hints
). Поскольку у сервера, поддерживающего только IPv4, есть лишь записи типа А, мы видим, согласно табл. 11.3, что клиенту возвращается адрес IPv4, преобразованный к виду IPv6.

3. Клиент IPv6 вызывает функцию connect с адресом IPv4, преобразованным к виду IPv6, в структуре адреса сокета IPv6. Ядро обнаруживает преобразованный адрес и автоматически посылает серверу сегмент SYN IPv4.

4. Сервер отвечает сегментом SYN/ACK IPv4, и устанавливается соединение, по которому происходит обмен дейтаграммами IPv4. Этот сценарий мы схематически изображаем на рис. 12.3.

UNIX: разработка сетевых приложений - img_91.png

Рис. 12.3. Обработка клиентских запросов в зависимости от типа адреса и типа сокета

■ Если TCP-клиент IPv4 вызывает функцию

connect
, задавая адрес IPv4, или если UDP-клиент IPv4 вызывает функцию
sendto
, задавая адрес IPv4, ничего особенного не происходит. На рисунке это изображено двумя стрелками, помеченными «IPv4».

■ Если TCP-клиент IPv6 вызывает функцию

connect
, задавая адрес IPv6, или если UDP-клиент IPv6 вызывает функцию
sendto
, задавая адрес IPv6, тоже ничего особенного не происходит. На рисунке это показано двумя стрелками, помеченными «IPv6».

■ Если TCP-клиент IPv6 вызывает функцию

connect
, задавая адрес IPv4, преобразованный к виду IPv6, или если UDP-клиент вызывает функцию
sendto
, задавая адрес IPv4, преобразованный к виду IPv6, ядро обнаруживает сопоставленный адрес и инициирует отправку дейтаграммы IPv4 вместо дейтаграммы IPv6. На рисунке это показано двумя штриховыми стрелками.

■ Клиент IPv4 не может задать адрес IPv6 ни функции

connect
, ни функции
sendto
, поскольку 16-байтовый адрес IPv6 не соответствует 4-байтовой структуре
in_addr
в структуре IPv4
sockaddr_in
. Следовательно, на рисунке нет стрелок от сокетов IPv4 к протоколу IPv6.

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

accept
или
recvfrom
. В этом разделе (если необходимо отправить дейтаграмму IPv4 на сокете IPv6) преобразование адреса IPv4 к виду IPv6 выполняется распознавателем в соответствии с правилами, представленными в табл. 11.3, и затем преобразованный адрес прозрачно передается приложению функцией
connect
или
sendto
.

Резюме: совместимость IPv4 и IPv6

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

Таблица 12.2. Обобщение совместимости клиентов и серверов IPv4 и IPv6

Сервер IPv4, узел только IPv4 (только А) Сервер IPv4, узел только IPv6 (только AAAA) Сервер IPv4, узел с двойным стеком (А и AAAA) Сервер IPv6, узел с двойным стеком (А и AAAA)
Клиент IPv4, узел только IPv4 IPv4 Нет IPv4 IPv4
Клиент IPv6, узел только IPv6 Нет IPv6 Нет IPv6
Клиент IPv4, узел с двойным стеком IPv4 Нет IPv4 IPv4
Клиент IPv6, узел с двойным стеком IPv4 IPv6 Нет* IPv6

Каждая ячейка этой таблицы содержит поля «IPv4» или «IPv6» с указанием используемого протокола, если данное сочетание работает, либо «нет», если комбинация недопустима. Ячейка в последней строке третьей колонки отмечена звездочкой, поскольку совместимость зависит от адреса, выбранного клиентом. При выборе записи типа AAAA отправка дейтаграммы IPv6 будет невозможна. Но выбор записи типа А, которая возвращается клиенту как адрес IPv4, преобразованный к виду IPv6, приведет к отправке дейтаграммы IPv4. Перебрав все адреса, возвращаемые

getaddrinfo
, мы обязательно доберемся до адреса IPv4, преобразованного к виду IPv6, пусть даже и потратив некоторое время на безуспешное ожидание.

144
{"b":"225366","o":1}