UNIX: разработка сетевых приложений
11.20. Устаревшие функции поиска адресов IPv6
В процессе разработки IPv6 интерфейс поиска адресов IPv6 много раз претерпевал серьезные изменения. В какой-то момент интерфейс был сочтен усложненным и недостаточно гибким, так что от него полностью отказались в RFC 2553 [38]. Документ RFC 2553 предлагал собственные функции, которые в RFC 3493 [36] были попросту заменены
иgetaddrinfo. В этом разделе мы вкратце рассмотрим старые интерфейсы на тот случай, если вам придется переписывать программы, использующие их.getnameinfoКонстанта RES_USE_INET6
Поскольку функция
не имеет аргумента для указания нужного семейства адресов (подобногоgethostbynameдляhints.ai_family), в первом варианте API использовалась константаgetaddrinfo, которая должна была добавляться к флагам распознавателя посредством внутреннего интерфейса. Этот API был недостаточно переносимым, поскольку системам, использовавшим альтернативные внутренние интерфейсы распознавателя, приходилось имитировать интерфейс BIND.RES_USE_INET6Включение
приводило к тому, что функцияRES_USE_INET6начинала поиск с записей AAAA, а записи А возвращались только в случае отсутствия первых. Поскольку в структуреgethostbynameесть только одно поле длины адреса, функцияhostentмогла возвращать адреса только одного типа (либо IPv6, либо IPv4).gethostbynameКроме того, включение
приводило к тому, что функцияRES_USE_INET6начинала возвращать адреса IPv4 в преобразованном к IPv6 виде.gethostbyname2Функция gethostbyname2
Функция
имеет добавочный аргумент, позволяющий задать семейство адресов.gethostbyname2#include <netdb.h>struct hostent *gethostbyname2(const char *<i>hostname</i>, int <i>family</i>);<i>Возвращает: непустой указатель в случае успешного выполнения, в случае ошибки возвращает NULL и задает значение переменной h_errno</i>Возвращаемое значение то же, что и у функции
— указатель на структуруgethostbyname, и сама эта структура устроена так же. Логика функции зависит от аргументаhostentи параметра распознавателяfamily(который мы упомянули в конце предыдущего раздела).RES_USE_INET6Функция getipnodebyname
Документ RFC 2553 [38] запретил использование
иRES_USE_INET6из-за глобальности флагаgethostbyname2и желания предоставить больше возможностей по управлению возвращаемыми сведениями. Для решения перечисленных проблем была предложена функцияRES_USE_INET6.getipnodebyname#include <sys/socket.h>#include <netdb.h>struct hostent *getipnodebyname(const char *<i>name</i>, int <i>af</i>,int <i>flags</i>, int *<i>error_num</i>);<i>Возвращает: ненулевой указатель в случае успешного завершения, нулевой в случае ошибки</i>Функция возвращает указатель на ту же структуру
, которая использоваласьhostent. Аргументыgethostbynameиafнепосредственно соответствуют полямflagsиhints.ai_family. Для обеспечения безопасности в многопоточной среде возвращаемое значение выделяется динамически, поэтому его приходится освобождать вызовомhints.ai_flags.freehostent#include <netdb.h>void freehostent(struct hostent *<i>ptr</i>);Функции
иgetipnodebynameбыли отменены в RFC 3493 [36], а вместо них было предложено использоватьgetipnodebyaddrиgetaddrinfo.getnameinfo11.21. Другая информация о сетях
В этой главе мы сфокусировали внимание на именах узлов, IP-адресах, именах и номерах портов служб. Если же обобщить полученную информацию, мы увидим, что существует четыре типа данных (имеющих отношение к сетям), которые могут понадобиться приложению: узлы, сети, протоколы и службы. В большинстве случаев происходит поиск данных, относящихся к узлам (функции
иgethostbyname), реже — к службам (функцииgethostbyaddrиgetservbyname) и еще реже — к сетям и протоколам.getservbyaddrВсе четыре типа данных могут храниться в файле, и для каждого из четырех типов определены три функции:
1. Функция
, читающая следующую запись в файле, при необходимости открывающая файл.get<i>XXX</i>ent2. Функция
, которая открывает файл (если он еще не открыт) и переходит к началу файла.set<i>XXX</i>ent3. Функция
, закрывающая файл.end<i>XXX</i>entДля каждого из четырех типов данных определяется его собственная структура (соответственно, структуры
,hostent,netentиprotoent), что требует включения заголовкаservent.<netdb.h>В дополнение к трем функциям
,getиset, которые допускают последовательную обработку файла, для каждого из четырех типов данных предоставляются функции ключевого поиска, или поиска по ключу (keyed lookup). Эти функции последовательно проходят файл (вызывая функциюendдля чтения каждой строки файла), но вместо того чтобы возвращать каждую строку вызывающему процессу, эти функции ищут элемент, совпадающий с аргументом. Имена функций поиска по ключу имеют видget<i>XXX</i>ent. Например, две функции ключевого поиска для информации об узле — это функцииget<i>XXX</i>by<i>YYY</i>(ищет элемент, совпадающий с именем узла) иgethostbyname(ищет элемент, совпадающий с IP-адресом). Таблица 11.5 обобщает эту информацию.gethostbyaddr