Node.JS dns.reverse 多个域名服务器

Node.JS dns.reverse multiple nameservers

我的 Node.JS 申请有问题。
出于某种原因,dns.reverse 仅使用指定的第一个名称服务器并忽略第二个。

我有如下一段代码:

import Resolver from '~/classes/resolver';

Resolver.addNameServer('192.168.2.1', '192.168.1.254').boot();

Resolver.hostnameFromIP('192.168.1.30').then((hostname: string) => {
    console.log(hostname);
}).catch((error) => {
    console.log(error); // We are going to end up here as the 192.168.2.1 is the first and only nameserver which will be queried
});

这是解析器 class:

import q, { Deferred } from 'q';
import dns from 'dns';
import { ResolverInterface } from '~/classes/resolver/interfaces';

/**
 * Resolver class
 */
class Resolver implements ResolverInterface {

    /**
     * List of nameservers used for hostname resolution
     * @type { string[] }
     */
    public nameservers: string[] = [];

    /**
     * Add nameserver for resolver to use
     * @param { string } nameserver
     * @return { Resolver }
     */
    public addNameServer(...nameserver: string[]) : Resolver {
        this.nameservers.push(...nameserver);
        return this;
    }

    /**
     * Initialize resolver
     * @return { void }
     */
    public boot() : void {
        if (this.nameservers.length === 0) {
            this.initializeWithDefaultNameServers();
        }
        dns.setServers(this.nameservers);
    }

    /**
     * Resolve hostname from the IP address
     * @param { string } ip
     * @return { q.Promise<string> }
     */
    public hostnameFromIP(ip: string) : q.Promise<string> {
        const deferred: Deferred<any> = q.defer();
        dns.reverse(ip, (error: NodeJS.ErrnoException | null, hostnames: string[]) => {
            const defaultErrorMessage: string = 'Unable to resolve hostname';
            if (error) {
                return deferred.reject(defaultErrorMessage);
            }
            let hostname: string = hostnames.length === 0 ? defaultErrorMessage : hostnames[0];
            hostname = hostname.replace('.localdomain', '').trim();
            deferred.resolve(hostname);
        });
        return deferred.promise as q.Promise<string>;
    }

    /**
     * Initialize resolver with default nameservers
     * @return { void }
     * @private
     */
    private initializeWithDefaultNameServers() : void {
        const nameservers: string[] = [
            '192.168.0.1',
            '192.168.1.1',
            '192.168.2.1',
        ];
        nameservers.forEach((nameserver: string) : void => {
            this.nameservers.push(nameserver);
        });
    }

}



export default new Resolver;

预期行为: 应用程序应通过所有指定的名称服务器来解析指定 IP 地址的主机名

实际行为: 根据哪个名称服务器是第一个,只有该名称服务器将被查询主机名。
如果 192.168.2.1 是第一个,我可以查询 192.168.2.10 的数据,但我不能为 192.168.1.30 查询数据。
如果 192.168.1.254 是第一个,我可以查询 192.168.1.30 的数据,但我不能为 192.168.2.10 查询数据。

有没有办法在使用 Node.JS 中的 dns.reverse 进行反向主机名查找时使用所有指定的名称服务器?

感谢 Jorge Fuentes González 的帮助,这是我最终使用的版本,至少适用于 2名称服务器。

     /**
     * Resolve hostname from IP address
     * @param { string } ip
     * @return { Promise<string> }
     */
    public async hostnameFromIP(ip: string) : Promise<string> {
        return await this.resolveForHostnameFromIP(ip)
            .then((hostname: string): string => hostname)
            .catch(async (error: string): Promise<string> => {
                const indexOf: number = this.nameservers.indexOf(this.currentNameServer);
                const newNameserverIndex: number = indexOf + 1;
                if (newNameserverIndex <= this.nameservers.length - 1) {
                    this.currentNameServer = this.nameservers[indexOf + 1];
                    this.setCurrentNameServerValue();
                    return await this.hostnameFromIP(ip).then((hostname: string): string => hostname);
                }
                return error;
            });
    }

    /**
     * Helper method to resolve hostname from the IP address
     * @param { string } ip
     * @return { q.Promise<string> }
     */
    private resolveForHostnameFromIP(ip: string) : q.Promise<string> {
        const deferred: Deferred<any> = q.defer();
        this.resolver.reverse(ip, (error: NodeJS.ErrnoException | null, hostnames: string[]) => {
            const defaultErrorMessage: string = 'Unable to resolve hostname';
            if (error) {
                return deferred.reject(defaultErrorMessage);
            } else {
                let hostname: string = hostnames.length === 0 ? defaultErrorMessage : hostnames[0];
                hostname = hostname.replace('.localdomain', '').trim();
                deferred.resolve(hostname);
            }
        });
        return deferred.promise as q.Promise<string>;
    }

    /**
     * Update resolver configuration with current name server
     * @return { void }
     * @private
     */
    private setCurrentNameServerValue() : void {
        this.resolver.setServers([this.currentNameServer]);
    };

对不起,我答错了,所以这部分不重要。正确答案如下。顺便说一句,把它放在这里以防万一有人遇到这样的问题:
这不是 DNS 服务器列表在几乎任何平台上的工作方式。如果您查看系统网络设置(Windows、Mac 或 Linux),您肯定会看到 2 个名称服务器(这是所有 ISP 提供的默认数量)。那是因为有一个主服务器和一个 fallback 服务器,如果主服务器出现故障。当您浏览 Internet 时,您的系统不会 return 2 个不同的 IP。那真是怪了。您的浏览器需要的只是一个要连接的 IP,而不是 IP 列表。 NodeJS 的工作原理相同。其余名称服务器只是后备服务器,以防万一主要服务器出现故障。

现在是正确的部分:
当名称服务器回复 NOTFOUND 时,nodejs 将 而不是 继续到下一个名称服务器,因为它实际上是一个工作的名称服务器。后备名称服务器仅在名称服务器出现故障时使用(出现奇怪的 error/response 或超时。下面的文档 link 包含此信息)。

要实现您想要的效果,您需要设置您的名称服务器、进行查询、等待响应、设置下一个名称服务器、进行查询等...使用您当前的代码一定是一件容易的事。挺好看的

小心,因为当 DNS 查询正在进行时,您不能更改名称服务器 as you can read in the documentation