Чтение онлайн

на главную

Жанры

UNIX: разработка сетевых приложений
Шрифт:

Невзирая на тот факт, что функция

getaddrinfo
«лучше», чем функции
gethostbyname
и
gethostbyaddr
(помимо того что эта функция упрощает написание кода, не зависящего от протокола, она обрабатывает и имя узла, и имя службы, и к тому же вся возвращаемая ею информация размещается в памяти динамически, а не статически), ее все же не так просто использовать, как это могло показаться. Проблема в том, что нам требуется разместить в памяти структуру
hints
, инициализировать ее нулем, заполнить необходимые поля, вызвать функцию
getaddrinfo
и затем пройти весь связный список, проверяя каждый его элемент. В последующих разделах мы предоставим более простые интерфейсы для типичных клиентов TCP и UDP и серверов, которые
будем создавать в оставшейся части книги.

Функция

getaddrinfo
решает проблему преобразования имен узлов и имен служб в структуры адресов сокетов. В разделе 11.17 мы опишем обратную функцию
getnameinfo
, которая преобразует структуры адресов сокетов в имена узлов и имена служб.

11.7. Функция gai_strerror

Ненулевые значения ошибок, возвращаемых функцией

getaddrinfo
, имеют названия и значения, показанные в табл. 11.2. Функция
gai_strerror
получает одно из этих значений в качестве аргумента и возвращает указатель на соответствующую текстовую строку с описанием ошибки.

#include <netdb.h>

char *gai_strerror(int error);

Возвращает: указатель на строку с описанием ошибки

Таблица 11.2. Ненулевые возвращаемые значения (константы) ошибок функции getaddrinfo

Константа Описание
EAI_AGAIN Временный сбой при попытке разрешения имен
EAI_BADFLAGS Недопустимое значение ai_flags
EAI_FAIL Неисправимая ошибка при разрешении имен
EAI_FAMILY Семейство ai_family не поддерживается
EAI_MEMORY Ошибка при выделении памяти
EAI_NONAME Имя узла или имя службы неизвестны или равны NULL
EAI_OVERFLOW Переполнен буфер пользовательских аргументов (только для getnameinfo)
EAI_SERVICE Запрошенная служба не поддерживается для данного типа сокета ai_socktype
EAI_SOCKTYPE Тип сокета ai_socktype не поддерживается
EAI_SYSTEM Другая системная ошибка, возвращаемая в переменной errno

11.8. Функция freeaddrinfo

Вся память, занимаемая структурами

addrinfo
, структурами
ai_addr
и строкой
ai_canonname
, которые возвращаются функцией
getaddrinfo
, динамически выделяется функцией
malloc
. Эта память освобождается при вызове функции
freeaddrinfo
.

#include <netdb.h>

void freeaddrinfo(struct addrinfo * ai);

Переменная

ai
должна указывать на первую из структур
addrinfo
, возвращаемых функцией
getaddrinfo
. Освобождается вся область памяти, занятая структурами из связного списка, вместе с динамически выделенной областью памяти, содержащей данные, на которые указывают эти структуры (например, структуры адресов сокетов и канонические имена узлов).

Предположим, что мы вызываем функцию

getaddrinfo
, проходим последовательно по всему связному списку структур
addrinfo
и находим нужную структуру. Если далее мы попытаемся сохранить нужную нам информацию
простым копированием структуры
addrinfo
, а затем вызовем функцию
freeaddrinfo
, мы получим скрытую ошибку. Причина в том, что структура
addrinfo
сама указывает на динамически выделенный участок памяти (для структуры адреса сокета и, возможно, для канонического имени). Но эта область памяти, на которую указывает сохраненная нами структура, при вызове функции
freeaddrinfo
освобождается и может использоваться для хранения какой-либо иной информации.

ПРИМЕЧАНИЕ

Создание копии только самой структуры addrinfo, а не структур, на которые она, в свою очередь, указывает, называется поверхностным копированием (shallow сору). Копирование структуры addrinfo и всех структур, на которые она указывает, называется детальным копированием (deep сору).

11.9. Функция getaddrinfo: IPv6

Стандарт POSIX определяет как

getaddrinfo
, так и возвращаемые этой функцией данные для протоколов IPv4 и IPv6. Отметим следующие моменты, прежде чем свести возвращаемые значения воедино в табл. 11.3.

Входные данные функции

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

Семейством адресов, указанным вызывающим процессом в структуре

hints
, задается тип структуры адреса сокета, который вызывающий процесс предполагает получить. Если вызывающий процесс задает
AF_INET
, функция не должна возвращать структуры
sockaddr_in6
, а для
AF_INET6
функция не должна возвращать структур
sockaddr_in
.

POSIX утверждает, что при задании семейства

AF_UNSPEC
должны возвращаться адреса, которые могут использоваться с любымсемейством протоколов, допускающим применение имени узла и имени службы. Это подразумевает, что если у узла имеются как записи типа AAAA, так и записи типа А, то записи типа AAAA возвращаются как структуры
sockaddr_in6
, а записи типа A — как структуры
sockaddr_in
. Нет смысла возвращать еще и записи типа А как адреса IPv4, преобразованные к виду IPv6, в структурах
sockaddr_in6
, потому что при этом не возвращается никакой дополнительной информации — эти адреса уже возвращены в структурах
sockaddr_in
.

Это утверждение POSIX также подразумевает, что если флаг

AI_PASSIVE
задан без имени узла, то должен быть возвращен универсальный адрес IPv6 (
IN6ADDR_ANY_INIT
или 0::0) в структуре
sockaddr_in6
вместе с универсальным адресом IPv4 (
INADDR_ANY
или 0.0.0.0) в структуре
sockaddr_in
. Также нет смысла возвращать сначала универсальный адрес IPv4, поскольку мы увидим в разделе 12.2, что на узле с двойным стеком сокет сервера IPv6 может обрабатывать и клиенты IPv4, и клиенты IPv6.

Семейство адресов, указанное в поле

ai_family
структуры
hint
вместе с флагами
AI_V4MAPPED
и
AI_ALL
поля
ai_flags
, задают тип записей, поиск которых ведется в DNS (тип А или тип AAAA), и тип возвращаемых адресов (IPv4, IPv6 или IPv4, преобразованные к виду IPv6). Мы обобщили это в табл. 11.3.

Имя узла может также быть либо шестнадцатеричной строкой IPv6, либо строкой в точечно-десятичной записи IPv4. Допустимость этой строки зависит от семейства адресов, заданного вызывающим процессом. Шестнадцатеричная строка IPv6 неприемлема, если задано семейство

AF_INET
, а строка в точечно-десятичной записи IPv4 неприемлема, если задано семейство
AF_INET6
. Но если задано семейство
AF_UNSPEC
, то допустимы оба варианта, и при этом возвращается соответствующий тип структуры адреса сокета.

Поделиться:
Популярные книги

Законы Рода. Том 5

Flow Ascold
5. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 5

Идеальный мир для Социопата 4

Сапфир Олег
4. Социопат
Фантастика:
боевая фантастика
6.82
рейтинг книги
Идеальный мир для Социопата 4

Архонт

Прокофьев Роман Юрьевич
5. Стеллар
Фантастика:
боевая фантастика
рпг
7.80
рейтинг книги
Архонт

Идущий в тени. Книга 2

Амврелий Марк
2. Идущий в тени
Фантастика:
фэнтези
6.93
рейтинг книги
Идущий в тени. Книга 2

Мне нужна жена

Юнина Наталья
Любовные романы:
современные любовные романы
6.88
рейтинг книги
Мне нужна жена

Я же бать, или Как найти мать

Юнина Наталья
Любовные романы:
современные любовные романы
6.44
рейтинг книги
Я же бать, или Как найти мать

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Ты не мой BOY

Рам Янка
5. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты не мой BOY

Маршал Советского Союза. Трилогия

Ланцов Михаил Алексеевич
Маршал Советского Союза
Фантастика:
альтернативная история
8.37
рейтинг книги
Маршал Советского Союза. Трилогия

Авиатор: назад в СССР 12

Дорин Михаил
12. Покоряя небо
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Авиатор: назад в СССР 12

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу