为什么在不存在的主机名上gethostbyname()不会失败?

时间:2018-12-30 18:33:30

标签: c sockets dns

我正在尝试从主机名获取IPv4地址,因此我想可以为此目的使用gethostbyname()。这很好用,但有一个问题:当不存在的主机名传递给它时,它不会失败。

以下是一些代码:

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    printf("%p\n", gethostbyname("fkldsjflkasdjflkajsdflkjasdf.com"));
    return 0;
}

在Ubuntu上,输出为:

0x7fb891c1b8a0

为什么不是NULL

*编辑*

这是转储结果的更完整示例:

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    struct hostent *hp = gethostbyname("fkldsjflkasdjflkajsdflkjasdf.com");

    printf("%s %d %d %p\n", hp->h_name, hp->h_addrtype, hp->h_length, hp->h_addr_list);
    printf("%s\n", inet_ntoa(*((struct in_addr *) hp->h_addr)));

    return 0;
}

结果是这样的:

fkldsjflkasdjflkajsdflkjasdf.com 2 4 0x1c141a0
62.138.238.45

如您所见,我什至可以为不存在的主机名获取IP地址!不知道这怎么可能...

2 个答案:

答案 0 :(得分:2)

这似乎是您使用的DNS服务器的问题。当我运行代码时,它不会返回任何有用的信息。

鉴于返回的IP地址62.138.238.45的whois查找包含描述www.t-online.de,我假设您正在使用Deutsche Telekom(T-Online)提供的Internet访问,并且您正在使用T-Online的默认名称服务器。该名称服务器不会为不存在的域返回NXDOMAIN,而是会提供一个IP地址,该地址会导致“有用的”错误-即广告。

一个简短的测试,该测试与该IP上的HTTP服务器手动对话,并使用Host标头中的相关域,

$ telnet 62.138.238.45 80
GET / HTTP/1.0 
Host: fkldsjflkasdjflkajsdflkjasdf.com
<newline>

结果是:

HTTP/1.1 302 Found
Date: Sun, 30 Dec 2018 19:42:04 GMT
Server: Apache/2.4.7 (Ubuntu)
Location: http://navigationshilfe1.t-online.de/dnserror?url=fkldsjflkasdjflkajsdflkjasdf.com/
Content-Length: 267
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://navigationshilfe1.t-online.de/dnserror?url=fkldsjflkasdjflkajsdflkjasdf.com/">here</a>.</p>
</body></html>

有关此“服务”的更多信息以及有关如何禁用它的信息,请参见this information(德语)。

答案 1 :(得分:1)

h_errno包含什么?应该是HOST_NOT_FOUND

gethostbyname仅在发生内部错误时才返回null,即它无法为该结构分配内存