DNS
Модуль dns содержит функции, относящиеся к двум различным категориям:
1) Функции, использующие ресурсы операционной системы для выполнения разрешения имен и, возможно, не выполняющие сетевое общение. Эта категория содержит только одну функцию: dns.lookup(). Разработчикам, желающим выполнить разрешение имен так же, как и другие приложения в той же операционной системе, следует использовать dns.lookup().
Например, для поиска iana.org.
const dns = require('dns');
dns.lookup('nodejs.org', (err, addresses, family) => {
console.log('addresses:', addresses);
});
// address: "192.0.43.8" family: IPv4
2) Функции, которые подключаются к фактическому серверу DNS для выполнения разрешения имен и всегда используют сеть для выполнения запросов DNS. Эта категория содержит все функции в модуле dns за исключением dns.lookup(). Эти функции не используют тот же набор конфигурационных файлов, что и dns.lookup() (например, /etc/hosts). Эти функции следует использовать разработчикам, которые не хотят использовать ресурсы операционной системы для разрешения имен и вместо этого всегда хотят выполнять запросы DNS.
Ниже приведен пример, который выполняет разрешение 'archive.org' и затем обратное разрешение возвращенных IP-адресов.
const dns = require('dns');
dns.resolve4('archive.org', (err, addresses) => {
if (err) throw err;
console.log(`addresses: ${JSON.stringify(addresses)}`);
addresses.forEach((a) => {
dns.reverse(a, (err, hostnames) => {
if (err) {
throw err;
}
console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
});
});
});
Существуют тонкие последствия при выборе одного варианта над другим. Для получения дополнительной информации обратитесь к разделу Учёт практических аспектов реализации.
dns.getServers()
Возвращает массив строк IP-адресов, используемых для разрешения имен.
dns.lookup(hostname[, options], callback)
Разрешает имя хоста (например, 'nodejs.org') в первый найденный A (IPv4) или AAAA (IPv6) запись. options может быть объектом или целым числом. Если options не указан, то IPv4 и IPv6 адреса являются допустимыми. Если options является целым числом, то оно должно быть 4 или 6.
В качестве альтернативы, options может быть объектом, содержащим следующие свойства:
-
family<Число> - Семейство записей. Если присутствует, должно быть целым числом4или6. Если не указано, принимаются IP-адреса v4 и v6. -
hints: <Число> - Если присутствует, должно быть одним или несколькими поддерживаемыми флагамиgetaddrinfo. Еслиhintsне указан, то флаги не передаются вgetaddrinfo. Несколько флагов могут быть переданы черезhintsс помощью побитовогоORзначения. См. поддерживаемыеgetaddrinfoфлаги для получения дополнительной информации о поддерживаемых флагах. -
all: <Булево> - Еслиtrue, функция обратного вызова возвращает все разрешенные адреса в массиве, в противном случае возвращает один адрес. По умолчаниюfalse.
Все свойства являются необязательными. Пример использования опций показан ниже.
{
family: 4,
hints: dns.ADDRCONFIG | dns.V4MAPPED,
all: false
}
Функция callback имеет аргументы (err, address, family). address представляет собой строковое представление IPv4 или IPv6 адреса. family — это целое число 4 или 6 и обозначает семейство address (не обязательно значение, первоначально переданное в lookup).
С опцией all установленной в true, аргументы меняются на (err, addresses), где addresses является массивом объектов со свойствами address и family.
При ошибке err — это объект Error, где err.code — код ошибки. Имейте в виду, что err.code будет установлено в 'ENOENT' не только в случае, если хост не существует, но и в случае, если поиск не удался по другим причинам, например, отсутствии доступных дескрипторов файлов.
dns.lookup() не обязательно имеет отношение к протоколу DNS. Реализация использует средство операционной системы, которое может сопоставлять имена с адресами и наоборот. Эта реализация может иметь тонкие, но важные последствия для поведения любой программы Node.js. Пожалуйста, ознакомьтесь с разделом Учёт практических аспектов реализации перед использованием dns.lookup().
Пример использования:
const dns = require('dns');
const options = {
family: 6,
hints: dns.ADDRCONFIG | dns.V4MAPPED,
};
dns.lookup('example.com', options, (err, address, family) =>
console.log('address: %j family: IPv%s', address, family));
// address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
// When options.all is true, the result will be an Array.
options.all = true;
dns.lookup('example.com', options, (err, addresses) =>
console.log('addresses: %j', addresses));
// addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
Поддерживаемые флаги getaddrinfo
Следующие флаги могут быть переданы в качестве подсказок в dns.lookup().
-
dns.ADDRCONFIG: Типы возвращаемых адресов определяются типами адресов, поддерживаемых текущей системой. Например, IPv4 адреса возвращаются только в том случае, если текущая система имеет по крайней мере один настроенный IPv4 адрес. Локальные адреса не учитываются. -
dns.V4MAPPED: Если было указано семейство IPv6, но IPv6 адреса не были найдены, то возвращаются IPv4-сопоставленные IPv6 адреса. Обратите внимание, что это не поддерживается на некоторых операционных системах (например, FreeBSD 10.1).
dns.lookupService(address, port, callback)
Разрешает заданный address и port в имя хоста и сервис, используя внутреннюю реализацию getnameinfo операционной системы.
Функция обратного вызова имеет аргументы (err, hostname, service). Аргументы hostname и service являются строками (например, 'localhost' и 'http' соответственно).
При ошибке err — это объект Error, где err.code — код ошибки.
const dns = require('dns');
dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
console.log(hostname, service);
// Prints: localhost ssh
});
dns.resolve(hostname[, rrtype], callback)
Использует протокол DNS для разрешения имени хоста (например, 'nodejs.org') в массив типов записей, указанных в rrtype.
Допустимые значения для rrtype:
-
'A'- IP-адреса IPv4, по умолчанию -
'AAAA'- IP-адреса IPv6 -
'MX'- записи MX (Mail Exchange) -
'TXT'- текстовые записи -
'SRV'- записи SRV -
'PTR'- для обратного поиска IP-адресов -
'NS'- записи сервера имен -
'CNAME'- записи канонических имён -
'SOA'- начальная запись авторитета -
'NAPTR'- запись указателя авторитета имени
Функция callback имеет аргументы (err, addresses). При успехе addresses будет массивом, за исключением случаев разрешения записи SOA, которая возвращает объект, структурированный аналогично объекту, возвращаемому методом dns.resolveSoa(). Тип каждого элемента в addresses определяется типом записи и описан в документации соответствующих методов поиска.
При ошибке err — это объект Error, где err.code — один из кодов ошибок, указанных здесь.
dns.resolve4(hostname, callback)
Использует протокол DNS для разрешения IPv4 адресов (записей A) для hostname. Аргумент addresses передаваемый в функцию callback будет содержать массив IPv4 адресов (например, ['74.125.79.104', '74.125.79.105', '74.125.79.106']).
dns.resolve6(hostname, callback)
Использует протокол DNS для разрешения IPv6 адресов (записей AAAA ) для hostname. Аргумент addresses передаваемый в функцию callback будет содержать массив IPv6 адресов.
dns.resolveCname(hostname, callback)
Использует протокол DNS для разрешения записей CNAME для hostname. Аргумент addresses передаваемый в функцию callback будет содержать массив записей канонических имён, доступных для hostname (например, ['bar.example.com']).
dns.resolveMx(hostname, callback)
Использует протокол DNS для разрешения записей MX (почтового обмена) (записей MX) для hostname. Аргумент addresses передаваемый в функцию callback будет содержать массив объектов, содержащих как свойство priority, так и свойство exchange (например, [{priority: 10, exchange: 'mx.example.com'}, ...]).
dns.resolveNaptr(hostname, callback)
Использует протокол DNS для разрешения записей, основанных на регулярных выражениях (записей NAPTR ) для hostname. Функция callback имеет аргументы (err, addresses). Аргумент addresses передаваемый в функцию callback будет содержать массив объектов со следующими свойствами:
flagsserviceregexpreplacementorderpreference
Например:
{
flags: 's',
service: 'SIP+D2U',
regexp: '',
replacement: '_sip._udp.example.com',
order: 30,
preference: 100
}
dns.resolveNs(hostname, callback)
Использует протокол DNS для разрешения записей сервера имен (записей NS ) для hostname. Аргумент addresses передаваемый в функцию callback будет содержать массив записей сервера имен, доступных для hostname (например, ['ns1.example.com', 'ns2.example.com']).
dns.resolveSoa(hostname, callback)
Использует протокол DNS для получения записи начала зоны ответственности (SOA запись) для hostname. Аргумент addresses, передаваемый в функцию callback, будет объектом со следующими свойствами:
nsnamehostmasterserialrefreshretryexpireminttl
{
nsname: 'ns.example.com',
hostmaster: 'root.example.com',
serial: 2013101809,
refresh: 10000,
retry: 2400,
expire: 604800,
minttl: 3600
}
dns.resolveSrv(hostname, callback)
Использует протокол DNS для разрешения записей сервисов (SRV записи) для hostname. Аргумент addresses, передаваемый в функцию callback, будет массивом объектов со следующими свойствами:
priorityweightportname
{
priority: 10,
weight: 5,
port: 21223,
name: 'service.example.com'
}
dns.resolveTxt(hostname, callback)
Использует протокол DNS для разрешения запросов текста (TXT записи) для hostname. Аргумент addresses, передаваемый в функцию callback, представляет собой двумерный массив доступных записей текста для hostname (например, [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Каждый подмассив содержит фрагменты TXT одной записи. В зависимости от использования, их можно объединить или обрабатывать по отдельности.
dns.reverse(ip, callback)
Выполняет обратный запрос DNS, который преобразует IP-адрес IPv4 или IPv6 в массив имён хостов.
Функция callback имеет аргументы (err, hostnames), где hostnames — массив разрешенных имён хостов для данного ip.
При ошибке err — объект Error, где err.code — один из кодов ошибок DNS.
dns.setServers(servers)
Устанавливает IP-адреса серверов, которые будут использоваться при разрешении. Аргумент servers — массив IP-адресов IPv4 или IPv6.
Если порт указан в адресе, он будет удалён.
Будет выброшена ошибка, если предоставлен неверный адрес.
Метод dns.setServers() не должен вызываться во время выполнения запроса DNS.
Коды ошибок
Каждый запрос DNS может вернуть один из следующих кодов ошибок:
-
dns.NODATA: Сервер DNS вернул ответ без данных. -
dns.FORMERR: Сервер DNS утверждает, что запрос был неверно отформатирован. -
dns.SERVFAIL: Сервер DNS вернул общую ошибку. -
dns.NOTFOUND: Имя домена не найдено. -
dns.NOTIMP: Сервер DNS не поддерживает запрашиваемую операцию. -
dns.REFUSED: Сервер DNS отклонил запрос. -
dns.BADQUERY: Неверно отформатированный запрос DNS. -
dns.BADNAME: Неверно отформатированное имя хоста. -
dns.BADFAMILY: Неподдерживаемая семейство адресов. -
dns.BADRESP: Неверно отформатированный ответ DNS. -
dns.CONNREFUSED: Не удалось связаться с серверами DNS. -
dns.TIMEOUT: Истечение времени ожидания при попытке связи с серверами DNS. -
dns.EOF: Конец файла. -
dns.FILE: Ошибка чтения файла. -
dns.NOMEM: Нет памяти. -
dns.DESTRUCTION: Канал уничтожается. -
dns.BADSTR: Неверно отформатированная строка. -
dns.BADFLAGS: Указаны недопустимые флаги. -
dns.NONAME: Указанное имя хоста не является числовым. -
dns.BADHINTS: Указаны недопустимые флаги подсказок. -
dns.NOTINITIALIZED: Инициализация библиотеки c-ares ещё не выполнена. -
dns.LOADIPHLPAPI: Ошибка при загрузке iphlpapi.dll. -
dns.ADDRGETNETWORKPARAMS: Не удалось найти функцию GetNetworkParams. -
dns.CANCELLED: Запрос DNS отменён.
Рекомендации по реализации
Хотя dns.lookup() и различные функции dns.resolve*()/dns.reverse() преследуют одну и ту же цель — сопоставить имя сети с сетевым адресом (или наоборот), их поведение значительно отличается. Эти различия могут иметь тонкие, но существенные последствия для поведения программ Node.js.
dns.lookup()
Внутри dns.lookup() используется те же средства операционной системы, что и в большинстве других программ. Например, dns.lookup() почти всегда разрешает заданное имя таким же образом, как команда ping. На большинстве POSIX-подобных операционных систем поведение функции dns.lookup() может быть изменено путём изменения настроек в nsswitch.conf(5) и/или resolv.conf(5), но учтите, что изменение этих файлов изменит поведение всех других программ, работающих на той же операционной системе.
Хотя вызов dns.lookup() асинхронный с точки зрения JavaScript, он реализован как синхронный вызов getaddrinfo(3), который выполняется в пуле потоков libuv. Поскольку пул потоков libuv имеет фиксированный размер, это означает, что если по какой-либо причине вызов getaddrinfo(3) занимает много времени, другие операции, которые могут выполняться в пуле потоков libuv (например, файловые операции), будут испытывать снижение производительности. Чтобы смягчить эту проблему, одним из потенциальных решений является увеличение размера пула потоков libuv путём установки переменной среды 'UV_THREADPOOL_SIZE' на значение, большее 4 (текущее значение по умолчанию). Дополнительную информацию о пуле потоков libuv см. в официальной документации libuv.
dns.resolve(), dns.resolve*() и dns.reverse()
Эти функции реализованы совершенно иначе, чем dns.lookup(). Они не используют getaddrinfo(3) и всегда выполняют запрос DNS в сети. Эта сетевая коммуникация всегда асинхронна и не использует пул потоков libuv.
В результате эти функции не могут иметь такого же отрицательного влияния на другие операции, выполняемые в пуле потоков libuv, как dns.lookup().
Они не используют тот же набор конфигурационных файлов, что и dns.lookup(). Например, они не используют конфигурацию из /etc/hosts.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v4.x/docs/api/dns.html