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

на главную - закладки

Жанры

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

Эта технология также используется функциями

getnameinfo
и
inet_ntop
.

2. Входящая функция вызывает функцию

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

Обсудим функции Solaris 2.x, допускающие повторное вхождение, не используемые для сопоставления имен с адресами, и наоборот (то есть для разрешения имен).

#include <netdb.h>

struct hostent *gethostbyname_r(const char * hostname,

struct hostent * result, char * buf, int buflen, int * h_errnop);

struct hostent *gethostbyaddr_r(const char * addr, int len,

int type, struct hostent * result, char * buf, int buflen,

int * h_errnop);

Обе функции возвращают: непустой указатель в случае успешного выполнения, NULL в случае ошибки

Для каждой функции требуется четыре дополнительных аргумента. Аргумент

result
— это структура
hostent
, размещенная в памяти вызывающим процессом и заполняемая данной функцией. При успешном выполнении функции этот указатель также является возвращаемым значением.

Аргумент

buf
— это буфер, размещенный в памяти вызывающим процессом, a
buflen
— его размер. Буфер будет содержать каноническое имя, массив указателей на псевдонимы, строки псевдонимов, массив указателей на адреса и сами адреса. Все указатели в структуре
hostent
, на которую указывает
result
, указывают на этот буфер. Насколько большим должен быть этот буфер? К сожалению, все, что сказано в большинстве руководств, это что-то неопределенное вроде «Буфер должен быть достаточно большим, чтобы содержать все данные, связанные с записью узла». Текущие реализации функции
gethostbyname
могут возвращать до 35 указателей на альтернативные имена (псевдонимы), до 35 указателей на адреса и использовать буфер размером 8192 байт для хранения альтернативных имен (псевдонимов) и адресов. Поэтому буфер размером 8192 байт можно считать подходящим.

Если происходит ошибка, код ошибки возвращается через указатель

h_errnop
, а не через глобальную переменную
h_errno
.

ПРИМЕЧАНИЕ

К сожалению, проблема повторного вхождения гораздо серьезнее, чем может показаться. Во-первых, не существует стандарта относительно повторного вхождения и функций gethostbyname и gethostbyaddr. POSIX утверждает, что эти две функции не обязаны быть безопасными в многопоточной среде.

Во-вторых, не существует стандарта для функций _r. В этом разделе (в качестве примера) мы привели две функции _r, предоставляемые Solaris 2.x. В Linux присутствуют аналогичные функции, возвращающие hostent в качестве аргумента типа значение-результат. В Digital Unix и HP-UX имеются версии этих функций с другими аргументами. Первые два аргумента функции gethostbyname_r такие же, как и в версии Solaris, но оставшиеся три аргумента версии Solaris объединены в новую структуру hostent_data (которая

должна быть размещена в памяти вызывающим процессом), а указатель на эту структуру — это третий и последний аргумент. Обычные функции gethostbyname и gethostbyaddr в Digital Unix 4.0 и в HP-UX 10.30 допускают повторное вхождение при использовании собственных данных потоков (см. раздел 23.5). Интересный рассказ о разработке функций _r Solaris 2.x содержится в [70].

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

11.20. Устаревшие функции поиска адресов IPv6

В процессе разработки IPv6 интерфейс поиска адресов IPv6 много раз претерпевал серьезные изменения. В какой-то момент интерфейс был сочтен усложненным и недостаточно гибким, так что от него полностью отказались в RFC 2553 [38]. Документ RFC 2553 предлагал собственные функции, которые в RFC 3493 [36] были попросту заменены

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

Константа RES_USE_INET6

Поскольку функция

gethostbyname
не имеет аргумента для указания нужного семейства адресов (подобного
hints.ai_family
для
getaddrinfo
), в первом варианте API использовалась константа
RES_USE_INET6
, которая должна была добавляться к флагам распознавателя посредством внутреннего интерфейса. Этот API был недостаточно переносимым, поскольку системам, использовавшим альтернативные внутренние интерфейсы распознавателя, приходилось имитировать интерфейс BIND.

Включение

RES_USE_INET6
приводило к тому, что функция
gethostbyname
начинала поиск с записей AAAA, а записи А возвращались только в случае отсутствия первых. Поскольку в структуре
hostent
есть только одно поле длины адреса, функция
gethostbyname
могла возвращать адреса только одного типа (либо IPv6, либо IPv4).

Кроме того, включение

RES_USE_INET6
приводило к тому, что функция
gethostbyname2
начинала возвращать адреса IPv4 в преобразованном к IPv6 виде.

Функция gethostbyname2

Функция

gethostbyname2
имеет добавочный аргумент, позволяющий задать семейство адресов.

#include <netdb.h>

struct hostent *gethostbyname2(const char * hostname, int family);

Возвращает: непустой указатель в случае успешного выполнения, в случае ошибки возвращает NULL и задает значение переменной h_errno

Возвращаемое значение то же, что и у функции

gethostbyname
— указатель на структуру
hostent
, и сама эта структура устроена так же. Логика функции зависит от аргумента
family
и параметра распознавателя
RES_USE_INET6
(который мы упомянули в конце предыдущего раздела).

Функция getipnodebyname

Документ RFC 2553 [38] запретил использование

RES_USE_INET6
и
gethostbyname2
из-за глобальности флага
RES_USE_INET6
и желания предоставить больше возможностей по управлению возвращаемыми сведениями. Для решения перечисленных проблем была предложена функция
getipnodebyname
.

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

Ратник

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

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

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

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

Восход. Солнцев. Книга X

Скабер Артемий
10. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга X

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

Менталист. Конфронтация

Еслер Андрей
2. Выиграть у времени
Фантастика:
боевая фантастика
6.90
рейтинг книги
Менталист. Конфронтация

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

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

Ты не мой Boy 2

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

Лорд Системы 14

Токсик Саша
14. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 14

Приручитель женщин-монстров. Том 1

Дорничев Дмитрий
1. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 1

Девочка-яд

Коэн Даша
2. Молодые, горячие, влюбленные
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Девочка-яд

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Темный Патриарх Светлого Рода

Лисицин Евгений
1. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода