# xray.dns Предоставляет интерфейсы DNS-запросов и доступа к вышестоящим серверам. ```lua local dns = require("xray.dns") ``` ## Указатель API | Категория | Член API | Описание | | --------- | ----------------------------------------------------- | ---------------------------------- | | Функция | [`dns.Query(domain, ipv4, ipv6, fake)`](#dns-query) | Запрос через DNS-клиент Xray | | Поле | [`dns.Servers`](#dns-servers) | Массив вышестоящих серверов | | Объект | [`serverObj`](#server) | Отдельный вышестоящий DNS-сервер | | Поле | [`serverObj.ID`](#id) | Идентификатор сервера | | Метод | [`serverObj:Query(domain, ipv4, ipv6, fake)`](#query) | Прямой запрос к указанному серверу | ## Функции ### dns.Query ```lua local ips, ttl, err = dns.Query(domain, ipv4, ipv6, fake) ``` Запрашивает домен через DNS-клиент Xray. В Hook DNS недоступен, поскольку скрипт заменяет именно этот процесс обработки запросов. **Параметры** | Параметр | Тип | Описание | | -------- | --------- | ------------------------- | | `domain` | `string` | Запрашиваемый домен | | `ipv4` | `boolean` | Разрешены ли запросы IPv4 | | `ipv6` | `boolean` | Разрешены ли запросы IPv6 | | `fake` | `boolean` | Разрешён ли FakeDNS | **Возвращаемые значения** | Значение | Тип | Описание | | -------- | ------------------------------------------------ | ------------------------------------------------------------ | | `ips` | [`[]net.IP`](./data-types.md#net-ip-1) или `nil` | Результаты запроса | | `ttl` | `number` | TTL в секундах, диапазон `0 .. 4294967295`; никогда не `nil` | | `err` | [`error`](./data-types.md#error) или `nil` | Ошибка запроса; `nil` означает отсутствие ошибки | **Поведение** Все четыре параметра нужно передать явно с правильными типами, иначе возникает исключение Lua. Запрос учитывает глобальные ограничения типов запросов клиента, Hosts и настройки вышестоящих серверов. Если настроен [скрипт DNS](../guide/dns.md), запрос также передаётся ему. Если встроенный DNS не настроен, используется системный DNS. При успехе возвращается непустой срез IP; при ошибке запроса или отсутствии доступных адресов — `nil, 0, err`. **Пример** ```lua local ips, ttl, err = dns.Query("example.com", true, true, false) if err == nil and ips ~= nil and #ips > 0 then local firstIP = ips[1]:String() end ``` ## Поля ### dns.Servers ```lua local servers = dns.Servers ``` | Имя | Тип | Описание | | ------------- | ------- | ------------------------------------------------------------------------------ | | `dns.Servers` | `table` | Массив [`serverObj`](#server), индексы с 1, порядок соответствует конфигурации | При использовании встроенного DNS список содержит настроенные вышестоящие серверы. Если DNS или его серверы не настроены, список содержит только `localhost` (системный DNS). Для перебора списка используйте `ipairs`; при выходе индекса за границы `servers[i]` равен `nil`. **Пример** ```lua for _, serverObj in ipairs(dns.Servers) do local id = serverObj.ID end ``` ## Объекты ### server `serverObj` представляет вышестоящий DNS-сервер с его идентификатором и методом запроса. | Свойство | Описание | | ------------------- | --------------------------------------------- | | Реализация в Go | `luaDNSServer` из `app/dns` | | Представление в Lua | `table` | | Получение | Элемент массива [`dns.Servers`](#dns-servers) | #### ID ```lua local id = serverObj.ID ``` | Имя | Тип | Описание | | -------------- | -------- | ------------------------------------------------------------------------------------------------ | | `serverObj.ID` | `string` | Поле `id` в [конфигурации DNS-сервера](../../../config/dns.md#dnsserverobject); никогда не `nil` | Если `id` не задан, значение равно `""`, в том числе у серверов, настроенных строками. Автоматически добавленный системный DNS имеет ID `"localhost"`. Если нужно различать серверы по ID, самостоятельно задайте уникальные значения: ядро не проверяет дубликаты. #### Query ```lua local ips, ttl, err = serverObj:Query(domain, ipv4, ipv6, fake) ``` Запрашивает вышестоящий сервер, представленный `serverObj`. **Параметры и возвращаемые значения** Требования к параметрам и типы возвращаемых значений такие же, как у [`dns.Query`](#dns-query). **Поведение** Обычно настроенный сервер при успехе возвращает непустой срез IP, TTL и `nil`. При ошибке запроса, отсутствии адресов, удовлетворяющих условиям, или запросе FakeDNS с `fake == false` возвращается `nil, 0, err`. Запрашивает этот сервер напрямую, обходя глобальные Hosts и скрипт DNS. Собственные настройки сервера `queryStrategy`, кеш, `timeoutMs`, `clientIP`, `tag`, а также `expectedIPs` / `unexpectedIPs` и соответствующие `actPrior` / `actUnprior` продолжают действовать. **Пример** Вернуть результат запроса к первому серверу напрямую из Hook DNS: ```lua function HandleDNSQuery(domain, ipv4, ipv6, fake) return dns.Servers[1]:Query(domain, ipv4, ipv6, fake) end ```