【发布时间】:2014-09-11 09:38:40
【问题描述】:
理论上,getaddrinfo(3) 的返回值应该允许区分无法解析的主机名和 DNS 服务器的问题:
RETURN VALUE
getaddrinfo() returns 0 if it succeeds, or one of the following
nonzero error codes:
EAI_ADDRFAMILY
The specified network host does not have any network addresses
in the requested address family.
EAI_AGAIN
The name server returned a temporary failure indication. Try
again later.
EAI_NODATA
The specified network host exists, but does not have any net-
work addresses defined.
(摘自man 3 getaddrinfo)。
实际上,似乎差别不大:
$ ./getaddr_test www.google.invalid 80
getaddrinfo returned -2 (Name or service not known), errno is errno: 2
$ sudo vim /etc/resolv.conf # point to non-existing nameserver
$ ./getaddr_test www.google.com 80
getaddrinfo returned -2 (Name or service not known), errno is errno: 2
$ ./getaddr_test www.google.invalid 80
getaddrinfo returned -2 (Name or service not known), errno is errno: 2
$ uname -o -v
#1 SMP Debian 3.14.12-1 (2014-07-11) GNU/Linux
是否有任何其他方法可以将无法解析的主机名与无法访问的 DNS 服务器区分开来(不需要我再次查找“已知良好”的主机名)?
这是我使用的测试程序的源代码:
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[]) {
struct addrinfo hints;
struct addrinfo *result;
int ret;
if (argc < 3) {
fprintf(stderr, "Usage: %s host port...\n", argv[0]);
exit(EXIT_FAILURE);
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Stream socket */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_flags = 0;
ret = getaddrinfo(argv[1], argv[2], &hints, &result);
if (ret != 0)
printf("getaddrinfo returned %d (%s), errno is errno: %d\n",
ret, gai_strerror(ret), errno);
else
printf("getaddrinfo succeeded.");
}
【问题讨论】:
-
查看netdb.h后发现-2的返回值等于EAI_NONAME。