connect error: Operation timed out
trying 140.252.1.4:13
connect error: Operation timed out
trying 140.252.104.1:13
connect error: Connection refused
unable to connect
11.6. Функция getaddrinfo
Функции gethostbyname и gethostbyaddr поддерживают только IPv4. Интерфейс IPv6 разрабатывался в несколько этапов (история разработки описана в разделе 11.20), и в конечном итоге получилась функция getaddrinfo. Последняя осуществляет трансляцию имен в адреса и служб в порты, причем возвращает она список структур sockaddr, а не список адресов. Такие структуры могут непосредственно использоваться функциями сокетов. Благодаря этому функция getaddrinfo скрывает все различия между протоколами в библиотеке функций. Приложение работает только со структурами адресов сокетов, которые заполняются getaddrinfo. Эта функция определяется стандартом POSIX.
ПРИМЕЧАНИЕОпределение этой функции в POSIX происходит от более раннего предложения Кейта Склоуэра (Keith Sklower) для функции, называемой getconninfo. Эта функция стала результатом обсуждений с Эриком Олменом (Eric Allman), Вилльямом Дастом (William Durst), Майклом Карелсом (Michael Karels) и Стивеном Вайсом (Steven Wise), а также более ранней реализации, написанной Эриком Олменом. Замечание о том, что указания имени узла и имени службы достаточно для соединения с этой службой независимо от деталей протокола, было сделано Маршалом Роузом (Marshall Rose) в проекте X/Open.
#include <netdb.h>
int getaddrinfo(const char *<i>hostname</i>, const char *<i>service</i>,
const struct addrinfo *<i>hints</i>, struct addrinfo **<i>result</i>);
<i>Возвращает: 0 в случае успешного выполнения, ненулевое значение в случае ошибки</i>
<i>(см. табл. 11.2).</i>
Через указатель result функция возвращает указатель на связный список структур addrinfo, который задается в заголовочном файле <netdb.h> :
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* AF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 или IPPROTO_xxx для IPv4 и IPv6 */
size_t ai_addrlen; /* длина ai_addr */
char* ai_canonname; /* указатель на каноническое имя узла */
struct sockaddr *ai_addr; /* указатель на структуру адреса сокета */
struct addrinfo *ai_next; /* указатель на следующую структуру в связном
списке */
};
Переменная hostname — это либо имя узла, либо строка адреса (точечно-десятичная запись для 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, если задано).