getaddrinfo() 如何进行 DNS 查找?
getaddrinfo()
是一个我们需要在创建套接字和连接之前使用该函数(即调用 socket()
和 connect()
)。 getaddrinfo()
首先如何与 DNS 服务器通信?
在哪里可以看到 getaddrinfo()
的完整源代码?
getaddrinfo()
is a function we need to use before creating a socket and connecting (i.e. call socket()
and connect()
). How does getaddrinfo()
communicate with DNS server in the first place?
Where can I see the complete source of getaddrinfo()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
简短的回答是“它询问系统”,系统反过来知道如何进行 DNS 查找以及使用哪些服务器。
getaddrinfo()
由getaddrinfo(3)
手册页记录,这意味着它是一个 C 库函数。它也是一个POSIX函数,因此没有规范的“源”;符合 POSIX 的操作系统的每个标准 C 库都会实现自己的版本。无论哪种方式,该函数的源代码可能都不太有启发性,因为它只会调用其他函数和操作系统 API,并且您必须深入研究才能了解实际的 DNS 机制。如果您对其工作原理感兴趣,最好阅读 DNS 协议本身的文档。The short answer is "it asks the system", which in turn knows how to do DNS lookups and which servers to use.
getaddrinfo()
is documented by thegetaddrinfo(3)
manual page, which means it's a C library function. It is also a POSIX function, so there is no canonical "source"; each standard C library of an operating system that conforms to POSIX will implement its own version. Either way the source to just that function is probably not too enlightening, since it would just call other functions and OS APIs, and you'd have to drill down pretty far to get to the actual DNS mechanism. You'd be better off reading documentation of the DNS protocol itself if you're interested in how that works.在创建套接字或连接之前没有必要调用
getaddrinfo()
。它用于将域名(例如 stackoverflow.com)转换为 IP 地址(例如 69.59.196.211)。如果您知道 IP 地址,则可以直接连接到该地址,无需使用getaddrinfo()
。getaddrinfo()
使用 DNS 协议与您的名称服务器通信,这些服务器是使用其 IP 地址进行配置的。glibc 源代码为 这里。
It is not necessary to call
getaddrinfo()
before creating a socket or connecting. It is used to translate a domain name, like stackoverflow.com, to an IP address like 69.59.196.211. If you know the IP address then you can connect directly to that address and there is no need to usegetaddrinfo()
.getaddrinfo()
uses the DNS protocol to talk to your name servers, which are configured using their IP address.The glibc source code is here.
你的 Unix 系统有
/etc/nsswitch.conf
吗?如果是这样,则“hosts”条目给出将主机名解析为 IP 地址的搜索顺序。您的系统有/etc/resolv.conf
吗?如果是这样,那么它指定要使用的 DNS 服务器。正如您所看到的,getaddrinfo() 可以做很多事情(并且可能需要一段时间)!
Does your Unix system have
/etc/nsswitch.conf
? If so, then the "hosts" entry gives the search order for resolving hostnames into IP addresses. Does your system have/etc/resolv.conf
? If so, then it specifies what DNS servers to use.As you can see, getaddrinfo() can do quite a bit (and can take a while)!
getaddrinfo()
可能会在幕后进行connect()
调用,但是它已经知道需要连接到的 DNS 服务器的 IP 地址以便查询您要求其查询的主机的地址。仅当您要将“www.somehost.com”映射到 IP 地址时才需要
getaddrinfo()
,不需要将其作为调用connect( )
。您可能可以在 glibc 源代码中找到
getaddrinfo()
的完整源代码,您可以在此处(以及其他地方)找到该源代码。希望能为您澄清一些事情。
getaddrinfo()
likely does make aconnect()
call behind the scenes, however it already knows the IP address of the DNS server it needs to connect to in order to query for the address of the host you are asking it to query for.getaddrinfo()
is only needed if you want to map "www.somehost.com" to an IP address, it's not needed as a primer to callconnect()
.You can probably find the complete source code for
getaddrinfo()
in glibc sources which you'd be able to find here (among other places).Hope that clarifies things for you.
getaddrinfo()
来源是在 libc 实现中:glibc 和 uclibc-ng 使用
/etc/gai.conf
用于配置(glibc 扩展、uclibc- ng 尝试遵循 glibc API)。musl 有一些差异(例如,从< code>/etc/resolv.conf 全部并行并接受先到达的响应,最多仅支持 3 个名称服务器)。
Android 总是非常不同(像往常一样):它默认使用
/etc/ppp/resolv.conf
,但可以配置为使用/etc/resolv.conf
(通过注释掉-DANDROID_CHANGES
)。但是,检查较旧的 LineageOS,我没有看到此文件。resolv_private.h
有更多配置选项(例如重试间隔 5 秒)。
getaddrinfo()
sources are in libc implementation:glibc and uclibc-ng use
/etc/gai.conf
for configuration (glibc extension, uclibc-ng tries to follow glibc API).musl have some differences (e.g. queries names from
/etc/resolv.conf
in all in parallel and accepts whichever response arrives first, supports only up to 3 nameservers).Android is always very different (as usual): it uses by default
/etc/ppp/resolv.conf
, but can be configured to use/etc/resolv.conf
(by commenting out-DANDROID_CHANGES
). However, checking older LineageOS, I don't see this file.resolv_private.h
has more config options (e.g. 5 sec between retries).它使用 DNS 协议(UDP)
http://www.freesoft.org/CIE/Topics/77.htm
It is using DNS protocol (UDP)
http://www.freesoft.org/CIE/Topics/77.htm