— это либо имя узла, либо строка адреса (точечно-десятичная запись для IPv4 или шестнадцатеричная строка для IPv6). Переменная
service
— это либо имя службы, либо строка, содержащая десятичный номер порта. (См. также упражнение 11.4.)
Аргумент
hints
— это либо пустой указатель, либо указатель на структуру
addrinfo
, заполненную рекомендациями вызывающего процесса о типах
информации, которую он хочет получить. Например, если заданная служба предоставляется и для TCP, и для UDP (служба
domain
, которая ссылается на сервер DNS), вызывающий процесс может присвоить элементу
ai_socktype
структуры
hints
значение
SOCK_DGRAM
. Тогда возвращение информации будет иметь место только для дейтаграммных сокетов.
Вызывающим процессом могут быть установлены значения следующих элементов структуры
hints
:
ai_flags
(несколько констант
AI_XXX
, объединенных операцией ИЛИ);
ai_family
(значение
AF_xxx
);
ai_socktype
(значение
SOCK_xxx
);
ai_protocol
.
Поле
ai_flags
может содержать следующие константы:
AI_PASSIVE
указывает, что сокет будет использоваться для пассивного открытия;
AI_CANONNAME
указывает функции на необходимость возвратить каноническое имя узла;
AI_NUMERICHOST
запрещает преобразование между именами и адресами. Аргумент
hostname
должен представлять собой строку адреса;
AI_NUMERICSERV
запрещает преобразование между именами служб и номерами портов. Аргумент
service
должен представлять собой строку с десятичным номером порта;
AI_V4MAPPED
вместе с
ai_family = AF_INET6
указывает функции на необходимость вернуть адреса IPv4 из записей А, преобразованные к IPv6, если записи типа AAAA отсутствуют;
AI_ALL
при указании вместе с
AI_V4MAPPED
говорит о необходимости вернуть адреса IPv4, преобразованные к IPv6, вместе с истинными адресами IPv6;
AI_ADDRCONFIG
возвращает адреса, относящиеся к заданной версии IP, когда имеется несколько интерфейсов, имеющих IP-адреса другой версии.
Если аргументом структуры
hints
является пустой указатель, функция подразумевает нулевое значение для
ai_flags
,
ai_socktype
и
ai_protocol
и значение
AF_UNSPEC
для
ai_family
.
Если функция завершается успешно (0), то в переменную, на которую указывает аргумент
result
, записывается указатель на список структур
addrinfo
, связанных через
указатель
ai_next
. Имеется два способа возвращения множественных структур.
1. Если существует множество адресов, связанных с узлом
hostname
, то одна структура возвращается для каждого адреса, который может использоваться с запрашиваемым семейством адресов (значение
ai_family
, если задано).
2. Если служба предоставляется для множества типов сокетов, то одна структура может быть возвращена для каждого типа сокета в зависимости от
ai_socktype
. (Заметьте, что большинство реализаций
getaddrinfo
считают, что номер порта используется только тем типом сокета, который запрашивается в
ai_socktype
. Если аргумент
ai_socktype
не определен, функция возвращает ошибку.)
Например, если структура
hints
пуста, а вы запрашиваете записи для службы
domain
на узле с двумя IP-адресами, возвращаются четыре структуры
addrinfo
:
одна для первого IP-адреса и типа сокета SOCK_STREAM;
одна для первого IP-адреса и типа сокета SOCK_DGRAM;
одна для второго IP-адреса и типа сокета SOCK_STREAM;
одна для второго IP-адреса и типа сокета SOCK_DGRAM.
Мы показываем схематическое изображение этого примера на рис. 11.3. Не существует никакого гарантированного порядка структур при возвращении множества элементов. Например, мы не можем считать, что службы TCP возвращаются перед службами UDP.
Рис. 11.3. Пример информации, возвращаемой функцией getaddrinfo
ПРИМЕЧАНИЕ
Хотя это и не гарантируется, реализация должна возвращать IP-адреса в том же порядке, в котором они возвращаются DNS. Некоторые распознаватели позволяют администратору указывать порядок сортировки адресов в файле /etc/resolv.conf. Протокол IPv6 определяет правила выбора адресов (RFC 3484 [28]), которые могут влиять на порядок адресов, возвращаемых getaddrinfo.
Информация, возвращаемая в структурах
addrinfo
, готова для передачи функциям
socket
и
connect
или
sendto
(для клиента) и
bind
(для сервера). Аргументы функции
socket
— это элементы
ai_family
,
ai_socktype
и
ai_protocol
. Второй и третий аргументы функций
connect
и
bind
— это элементы
ai_addr
(указатель на структуру адреса сокета соответствующего типа, заполняемую функцией