Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Возможности тулкита GTK+ и сопутствующих библиотек

Низкоуровневые функции для работы с сетью

Автор: A. Панин
Дата публикации: 11 июня 2015 г.

2. Класс системы разрешения доменных имен GResolver

Как и в случае работы с системным API сокетов, при вызове метода соединения с удаленным узлом или метода отправки дейтаграммы на определенный узел должен передаваться IP-адрес целевого узла, а не имя соответствующего домена. Для получения IP-адресов, соответствующих заданному имени домена, в рамках библиотеки GIO реализован специальный класс системы разрешения доменных имен GResolver. На уровне системного API сокетов для разрешения доменных имен используются функции, блокирующие исполнение приложения или программного потока, поэтому в рамках класса GResolver реализованы механизмы создания программных потоков. Приложение, осуществляющее многократное разрешение доменных имен, может использовать собственную реализацию системы системы разрешения доменных имен с дополнительными механизмами кэширования результатов, причем соответствующий объект типа GResolver будет использоваться приложением по умолчанию после вызова функции g_resolver_set_default(). При этом в большинстве случаев приложение будет отлично работать и со стандартной реализацией системы разрешения доменных имен, представленной объектом, который может быть получен путем вызова функции g_resolver_get_default().

void
g_resolver_set_default (GResolver *resolver);
GResolver *
g_resolver_get_default (void);

Непосредственное разрешение доменных имен осуществляется либо с помощью метода g_resolver_lookup_by_name() в синхронном режиме, либо с помощью методов g_resolver_lookup_by_name_async() и g_resolver_lookup_by_name_finish() в асинхронном режиме.

GList *
g_resolver_lookup_by_name(GResolver *resolver,
                          const gchar *hostname,
                          GCancellable *cancellable,
                          GError **error);
void
g_resolver_lookup_by_name_async(GResolver *resolver,
                                const gchar *hostname,
                                GCancellable *cancellable,
                                GAsyncReadyCallback callback,
                                gpointer user_data);
GList *
g_resolver_lookup_by_name_finish(GResolver *resolver,
                                 GAsyncResult *result,
                                 GError **error);

Полученные адреса помещаются в двусвязный список типа GList, который может освобождаться как с помощью специального метода g_resolver_free_addresses(), так и вручную (с помощью метода g_list_free_full()). Имя домена передается с помощью аргумента hostname. При работе в асинхронном режиме с помощью аргумента callback метода g_resolver_lookup_by_name_async() должна быть задана функция обратного вызова, в рамках которой для проверки корректности разрешения доменного имени и получения списка IP-адресов должен вызываться метод g_resolver_lookup_by_name_finish(). В приведенных ниже примерах осуществляется разрешение доменных имен в асинхронном режиме. Обратное преобразование IP-адреса в доменное имя может осуществляться с помощью метода g_resolver_lookup_by_address() в синхронном режиме и комбинации методов g_resolver_lookup_by_address_async() и g_resolver_lookup_by_address_finish() в асинхронном режиме.

gchar *
g_resolver_lookup_by_address(GResolver *resolver,
                             GInetAddress *address,
                             GCancellable *cancellable,
                             GError **error);
void
g_resolver_lookup_by_address_async(GResolver *resolver,
                                   GInetAddress *address,
                                   GCancellable *cancellable,
                                   GAsyncReadyCallback callback,
                                   gpointer user_data);
gchar *
g_resolver_lookup_by_address_finish(GResolver *resolver,
                                    GAsyncResult *result,
                                    GError **error);

Очевидно, что IP-адрес передается с помощью аргумента address.

Поиск сервисов, объявленных в рамках записей SRV домена, по названиям и протоколам может осуществляться с помощью метода g_resolver_lookup_service() в синхронном режиме и комбинации методов g_resolver_lookup_service_async() и g_resolver_lookup_service_finish() в асинхронном режиме.

GList *
g_resolver_lookup_service(GResolver *resolver,
                          const gchar *service,
                          const gchar *protocol,
                          const gchar *domain,
                          GCancellable *cancellable,
                          GError **error);
void
g_resolver_lookup_service_async(GResolver *resolver,
                                const gchar *service,
                                const gchar *protocol,
                                const gchar *domain,
                                GCancellable *cancellable,
                                GAsyncReadyCallback callback,
                                gpointer user_data);
GList *
g_resolver_lookup_service_finish(GResolver *resolver,
                                 GAsyncResult *result,
                                 GError **error);

В данном случае имя сервиса передается с помощью аргумента service, название протокола - с помощью аргумента protocol, а имя домена - с помощью аргумента domain. Полученный список сервисов может быть уничтожен с помощью вспомогательного метода g_resolver_free_targets() или вручную.

void
g_resolver_free_targets (GList *targets);

Наконец, список ресурсных записей домена может быть получен с помощью метода g_resolver_lookup_records() в синхронном режиме и с помощью комбинации методов g_resolver_lookup_records_async() и g_resolver_lookup_records_finish() в асинхронном режиме.

GList *
g_resolver_lookup_records(GResolver *resolver,
                          const gchar *rrname,
                          GResolverRecordType record_type,
                          GCancellable *cancellable,
                          GError **error);
void
g_resolver_lookup_records_async(GResolver *resolver,
                                const gchar *rrname,
                                GResolverRecordType record_type,
                                GCancellable *cancellable,
                                GAsyncReadyCallback callback,
                                gpointer user_data);
GList *
g_resolver_lookup_records_finish(GResolver *resolver,
                                 GAsyncResult *result,
                                 GError **error);

Здесь с помощью аргумента rrname передается имя домена, а с помощью аргумента record_type - идентификатор ресурсной записи домена. Функции возвращают список из кортежей, каждый из которых упакован в контейнер типа GVariant (допустимые идентификаторы ресурсных записей домена и описания возвращаемых кортежей приведены в таблице ниже).

Таблица 5 - Ресурсные записи доменов

Ресурсная запись домена Идентификатор записи Описание кортежа
SRV - Запись с информацией для выбора сервера (Server selection, RFC 2782) G_RESOLVER_RECORD_SRV (qqqs) - (приоритет, важность, порт, имя узла)
MX - Запись с информацией о почтовом шлюзе (Mail Exchanger, RFC 1035) G_RESOLVER_RECORD_MX (qs) - (приоритет, имя сервера электронной почты)
TXT - Текстовая запись (Text string, RFC 1035) G_RESOLVER_RECORD_TXT (as) - (массив строк текста)
SOA - Запись с информацией о сервере, хранящем эталонные данные (Start of authority, RFC 1035) G_RESOLVER_RECORD_SOA (ssuuuuu) - (имя основного сервера имен, имя администратора, идентификатор, интервал обновления, интервал повтора, период актуальности информации, TTL)
NS - Запись с информацией о сервере DNS, обслуживающем домен (Authoritative name server, RFC 1035) G_RESOLVER_RECORD_NS (s) - имя узла сервера

Продолжение статьи : 3. Пример использования низкоуровневых функций для работы с протоколом TCP.