How does getaddrinfo() do DNS lookup?
Asked Answered
C

6

37

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()?

Cytosine answered 28/1, 2010 at 20:5 Comment(3)
I'm sorry if this doesn't make much sense..started learning unix network programming only couple of days back- I'm quite confused.Cytosine
You don't need to call getaddrinfo() before creating a socket or before calling connect().Fash
connect() needs to be told the IP address of the destination host. And to have that, we need to perform hostname to IP lookup using getaddrinfo()Aftershaft
K
15

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 the getaddrinfo(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.

Kakalina answered 28/1, 2010 at 20:13 Comment(2)
This is completely incorrect. UNIX operating systems does not have a built in DNS lookup feature. This is done in userspace in the standard library. code.metager.de/source/xref/eglibc/libc/sysdeps/posix/…Fives
@HannesLandeholm I think the nuance here is that the UNIX kernel does not have a built-in DNS lookup feature, but the "system", in the more general sense of the word, includes userspace services that ship with the system.Stroboscope
M
12

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 use getaddrinfo(). getaddrinfo() uses the DNS protocol to talk to your name servers, which are configured using their IP address.

The glibc source code is here.

Modish answered 28/1, 2010 at 20:13 Comment(4)
Tell me one thing, if I want to do reverse DNS lookup then which system call requires?Luxor
Use getnameinfo() for address-to-name reverse DNS lookups.Modish
For more info, here's how it works in detail: jameshfisher.com/2018/02/03/what-does-getaddrinfo-do TL;DR it runs through /etc/nsswitch.conf, and uses whatever modules are listed in there to resolve the path. Usually this is hosts: files myhostname dns, when it finally hits the dns module it dynamically loads that library and then that does the DNS lookup by looking at /etc/hosts and /etc/resolv.conf.Moureaux
re mark4o's comment: beware, however, that there is zero guarantee that getnameinfo() will return even a legal hostname, much less a hostname which will resolve back to the IP you queried. Network administrators can set this as they please; I have personally set my own VPS to have valid rDNS records because it pleases me, but dynamically allocated residential IPs virtually always have rDNS records that are either "fake" or are non-public records from a split-horizon setup internal to the ISP.Furniture
D
10

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)!

Deepsea answered 28/1, 2010 at 20:18 Comment(0)
T
2

getaddrinfo() likely does make a connect() 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 call connect().

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.

Traveller answered 28/1, 2010 at 20:13 Comment(1)
If you want to see how glibc does name lookups, start here: cvs.savannah.gnu.org/viewvc/libc/resolv/nss_dns/… (beware: it's complicated).Dasilva
R
1

getaddrinfo() sources are in libc implementation:

  • musl (nice readable source as expected)
  • glibc (bloated as expected)
  • uclibc-ng (copied from glibc)
  • bionic (Android specific)

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).

Recti answered 24/8, 2023 at 16:27 Comment(0)
F
-3

It is using DNS protocol (UDP) http://www.freesoft.org/CIE/Topics/77.htm

Fulgurite answered 28/1, 2010 at 20:10 Comment(3)
False. See Steve Emmerson's reply.Damn
It does not? Can you prove it?Fulgurite
You can change your nsswitch.conf to only rely on /etc/hosts and NOT do any dns lookups.Maurits

© 2022 - 2024 — McMap. All rights reserved.