Name and Address Conversion: DNS Resolution & getaddrinfo()
Idea in plain words
Domain Name System (DNS) maps human-readable hostnames to binary IP addresses.
Exam tip
High-yield exam topic (High).
Explanation
Hardcoding IP addresses in client-server programs compromises architectural flexibility and breaks IPv4/IPv6 portability. getaddrinfo() accepts a hostname, a service name (e.g., 'http' or '80'), and an optional hints structure specifying criteria such as socket type (SOCK_STREAM). It queries DNS and /etc/hosts, returning a linked list of addrinfo structures containing valid sockaddr pointers ready for direct invocation with socket() and connect(). This protocol-independent design enables seamless migration to IPv6.
Key points
- Legacy functions gethostbyname() and gethostbyaddr() are obsolete and non-reentrant.
- getaddrinfo() provides modern protocol-independent, thread-safe name-to-address resolution supporting both IPv4 and IPv6.
- freeaddrinfo() frees the linked list of struct addrinfo dynamically allocated by getaddrinfo().
- gai_strerror() converts getaddrinfo error return codes into descriptive error strings.
Example
Example
Resolving 'localhost' and service 'http' returns 127.0.0.1 (IPv4) and ::1 (IPv6) sockaddr records.
Code examples
struct addrinfo hints, *res, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;
int status = getaddrinfo("www.purbanchaluniversity.edu.np", "80", &hints, &res);
if (status != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
exit(1);
}
// Iterate linked list and connect
for (p = res; p != NULL; p = p->ai_next) {
int sfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (connect(sfd, p->ai_addr, p->ai_addrlen) == 0) break; // Connected!
close(sfd);
}
freeaddrinfo(res);
Exam questions
- [8 Marks] Explain getaddrinfo(), freeaddrinfo(), and gai_strerror(). Why are they preferred over gethostbyname()?
- [5 Marks] Write a C program to resolve a given domain name to its corresponding IP address using getaddrinfo().