В качестве ввода функция getaddrinfo() принимает аргументы host, service и hints. Аргумент host содержит либо имя сетевого узла, либо строку в формате IPv4 или IPv6, состоящую из десятичных чисел и точек или шестнадцатеричного значения (если быть точным, функция getaddrinfo() поддерживает более общий формат IPv4-адреса, представленный в подразделе 55.13.1). Аргумент service включает в себя либо имя службы, либо десятичный номер порта. Аргумент hints (подробно рассмотрен чуть ниже) указывает на структуру addrinfo, в которой описываются дальнейшие критерии для выбора структур с адресами сокетов, возвращаемых с помощью result.
Для возвращения результата функция getaddrinfo() динамически выделяет список связей со структурами addrinfo и делает так, чтобы аргумент result на него указывал. Каждая из этих структур содержит указатель на структуру с адресом сокета соответствующих
struct addrinfo {
int ai_flags; /* Флаги ввода (константы вида AI_*) */
int ai_family; /* Семейство адресов */
int ai_socktype; /* Тип: SOCK_STREAM или SOCK_DGRAM */
int ai_protocol; /* Протокол сокета */
size_t ai_addrlen; /* Размер структуры, на которую указывает ai_addr */
char *ai_canonname; /* Каноническое имя узла */
struct sockaddr *ai_addr; /* Указатель на структуру с адресом сокета */
struct addrinfo *ai_next; /* Следующая структура в связном списке */
};
Аргумент result возвращает список структур, так как критерию, заданному с помощью аргументов host, service и hints, может соответствовать сразу несколько комбинаций из имен узлов и служб. Например, это относится к компьютерам, у которых больше одного сетевого интерфейса. Кроме того, если поле hints.ai_socktype равно 0, то можно получить две структуры для сокетов: одну для SOCK_DGRAM, а другую — для SOCK_STREAM (при условии, что служба доступна как по UDP, так и по TCP).
Поля структур addrinfo, которые возвращаются через аргумент result, описывают свойства соответствующих структур с адресами сокетов. Поле ai_family информирует о типе адреса и может быть равно либо AF_INET, либо AF_INET6. Поле ai_socktype обозначает протокол службы (TCP или UDP) и может принимать значения SOCK_STREAM и SOCK_DGRAM. Поле ai_protocol возвращает значение протокола для соответствующего семейства адресов и типа сокета (поля ai_family, ai_socktype и ai_protocol хранят значения, передающиеся в качестве аргументов вызова socket() при создании сокета для заданного адреса). Поле ai_addrlen обозначает размер структуры с адресом сокета, на которую указывает ai_addr (в байтах). Поле in_addr отмечает структуру с адресом сокета (in_addr для IPv4 или in6_addr для IPv6). Поле ai_flags игнорируется (оно используется для аргумента hints). Поле ai_canonname задействуется только в первой структуре addrinfo и только если в поле hints.ai_flags указан флаг AI_CANONNAME (см. ниже).
По аналогии с gethostbyname(), для возвращения результата функции getaddrinfo() иногда приходится обращаться к DNS-серверу, что может занять некоторое время. То же самое касается функции getnameinfo(), описанной в подразделе 55.10.4.
Применение функции getaddrinfo() будет продемонстрировано в разделе 55.11.
Аргумент hints задает подробные критерии для выбора структур с адресами сокетов, которые возвращает функция getaddrinfo(). При его использовании в структуре addrinfo можно задать только поля ai_flags, ai_family, ai_socktype и ai_protocol. Остальные поля игнорируются и при необходимости должны быть инициализированы нулями или значением NULL.
Поле hints.ai_family определяет домен для итоговых структур с адресами сокетов. Оно может быть равно AF_INET или AF_INET6 (или какой-то другой константе вида AF_*, если это поддерживается на уровне реализации). Для получения структуры всех типов можно указать в данном поле значение AF_UNSPEC.
Поле hints.ai_socktype определяет тип сокета, для которого будет использоваться возвращаемая структура с адресом. При указании в нем значения SOCK_DGRAM запрос будет выполнен для UDP-службы, а соответствующая структура возвращена с помощью аргумента result. В случае указания SOCK_STREAM поиск будет выполняться среди TCP-служб. Если поле hints.ai_socktype равно 0, то подходящим будет считаться сокет любого типа.
Поле hints.ai_protocol определяет протокол сокета для итоговой структуры с адресом. В наших примерах оно всегда равно 0, поскольку нам подходит любой протокол.
Поле hints.ai_flags представляет собой битовую маску, которая влияет на поведение функции getaddrinfo(). Маска формируется путем применения побитового ИЛИ к следующим значениям.
• AI_ADDRCONFIG — возвращает IPv4-адреса, только если в локальной системе имеется хотя бы один IPv4-адрес (не считая адреса, замкнутого на себя). То же самое касается адресов формата IPv6.
• AI_ALL — см. ниже описание константы AI_V4MAPPED.