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。
我的 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。