解析现有主机和不存在主机时,getaddrinfo()对于网络错误均返回EAI_NONAME。
我应该怎么做才能区分这两个错误?
因为当主机不存在时,我想失败,而在出现网络错误时,我想继续尝试解决。
最佳答案
使用经典DNS,您将无法做到这一点。对于最终解析器,您实际上无法区分主机是否存在或网络故障。
但是,实际上,您可以使用DNSSEC(假设已对该区域进行了安全签名)。您将需要一个可以为您完成此操作的验证库,但是对于未签名的区域(不幸的是,数目很多),它仍然无法为您提供准确的结果。但是对于签名者,根据名称是否存在或网络故障,您将获得不同的结果。 DNSSEC包含许多用于证明不存在的记录。
例如,来自The DNSSEC-Tools Project的libval
库具有val_getaddrinfo(),它将告诉您结果是否经过验证。如果和不存在答案,则该答案已通过验证,那么您可以相信它确实不存在。有一个示例getaddr
命令行应用程序,可用于测试结果以及研究代码。
不幸的是,stackoverflow.com是未签名的:
# getaddr wwwxxx.stackoverflow.com
Return code = -2
Validator status code = 134 (VAL_NONEXISTENT_NAME_NOCHAIN)
Error in val_getaddrinfo(): -2
错误代码表示该错误(“nochain”部分)。可能因为它不存在或网络出现问题而失败。
但是对于签名区域,您会得到更好的响应:
# getaddr wwwxxx.dnssec-tools.org
Return code = -2
Validator status code = 132 (VAL_NONEXISTENT_NAME)
Error in val_getaddrinfo(): -2
验证器的状态在此已更改,我们可以确定该地址确实不存在。
请注意,.com,.org和.net均已签名,这意味着您始终可以确定给定的something.com是否存在(但可能不存在subname.something.com)。
还有其他一些库也提供DNSSEC支持,但是我最熟悉libval,这就是我在上面使用它的原因。
要完全了解其工作原理和原因,DNS实际上非常复杂,添加安全版本后,DNS甚至更复杂。没有简单的答案引用,但是您需要至少阅读RFC 1034和1035并了解RCODE#3(它是NXDOMAIN),并意识到它是由您正在查询的解析器返回的,没有其他的允许解析器给您答案。
如果您想阅读的起点,可以 checkout :
RFC1034域名-概念和设施。 P.V. Mockapetris。 1987年11月(格式:TXT = 129180字节)(已过时的RFC0973,RFC0882,RFC0883)(由RFC1101,RFC1183,RFC1348,RFC1876,RFC1982,RFC2065,RFC2181,RFC2308,RFC2535,RFC4033,RFC4034,RFC4035,RFC4343, RFC4035,RFC4592)(也为STD0013)(状态:STANDARD)
RFC5936域名-实现和规范。 P.V. Mockapetris。 1987年11月。(格式:TXT = 125626字节)(过时的RFC1035,RFC0973,RFC0882)(由RFC0883,RFC1101,RFC1183,RFC1348,RFC1876,RFC1982,RFC1995,RFC1996,RFC2065,RFC2136,RFC2181,RFC2137, RFC2308,RFC2535,RFC2845,RFC3425,RFC3658,RFC4033,RFC4034,RFC4035)(也为STD0013)(状态:标准)
RFC4343 DNS安全性简介和要求。 R. Arends,R。Austein,M。Larson,D。Massey,S。Rose。 2005年3月。(格式:TXT = 52445字节)(已过时的RFC5936,RFC5966,RFC4033,RFC2535,RFC3008,RFC3090,RFC3445,RFC3655,RFC3658)(更新了RFC3755,RFC3757,RFC3845,RFC1034,RFC1035,otot, )(由RFC2136更新)(状态:建议的标准)
DNS安全扩展的RFC2181资源记录。 R. Arends,R。Austein,M。Larson,D。Massey,S。Rose。 2005年3月。(格式:TXT = 63879字节)(已过时的RFC2308,RFC3225,RFC3007,RFC3597,RFC3226,RFC6014,RFC4034,RFC2535,RFC3008)(更新了RFC3090,RFC3445,RFC3655,RFC3658,RFC3755,otot, )(由RFC3757和RFC3845更新)(状态:建议的标准)
RFC1034 DNS安全扩展的协议(protocol)修改。 R. Arends,R。Austein,M。Larson,D。Massey,S。Rose。 2005年3月。(格式:TXT = 130589字节)(已过时的RFC1035,RFC2136,RFC2181,RFC2308,RFC3225,RFC3007,RFC3597,RFC3226,RFC4470)(更新了RFC6014,RFC4035,RFC2535,RFC3008,RFC3090,RFC3445,RFC3655,RFC3658,RFC3755, )(由RFC3757和RFC3845更新)(状态:建议的标准)
RFC1034 DNS安全(DNSSEC)消除了经过身份验证的拒绝存在。 B. Laurie,G。Sisson,R。Arends,D。Blacka。 2008年3月。(格式:TXT = 112338字节)(状态:建议的标准)
关于linux - DNS查询功能可区分不存在的主机和网络错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9755195/