getaddrinfo() from musl libc

5. getaddrinfo() from musl libc #

musl libc is a lightweight, fast, and simple implementation of the standard C library (libc) that aims for efficiency, standards compliance, and security.

It gained popularity following its extensive use in Alpine Linux, a security-oriented, lightweight Linux distribution often used as a base image for Docker containers.

However, it is crucial for us to understand that musl libc incorporates a completely new resolver code that behaves differently in certain situations. The most significant differences include:

  • Instead of querying nameservers in /etc/resolv.conf sequentially, one by one, musl libc queries all of them in parallel and returns the fastest response.

  • musl libc does not support the single-request and single-request-reopen in /etc/resolv.conf, which aim to wrap around borked and weirdly behaved network devices.

  • The handling of the domain and search directives may also differ depending on the ndots setting in /etc/resolv.conf.

    musl’s resolver previously did not support the domain and search keywords in resolv.conf. This feature was added in version 1.1.13, but its behavior differs slightly from glibc’s: queries with fewer dots than the ndots configuration variable are processed with search first then tried literally (just like glibc), but those with at least as many dots as ndots are only tried in the global namespace (never falling back to search, which glibc would do if the name is not found in the global DNS namespace).

  • Default ai_flags differences which are important for dual stack applications which we will cover later in the series.

    In glibc (we will cover these flags later in the dual stack section):

    ai_flags = AI_ADDRCONFIG|AI_V4MAPPED
    

    In musl libc:

    ai_flags = 0
    

It is also important to note that TCP support for DNS queries was introduced in version 1.2.4. Prior to this, there could be issues handling larger packets, such as those required for DNSSEC or when a large number of records are returned—situations that are not unusual in Kubernetes setups.

Also if we run our example from the Chapter 3 built with musl under strace: we can observe that it doesn’t open /etc/nsswitch.conf, the nscd socket, nor /etc/gai.conf (which we discuss later). The only files it reads are:

$ strace -e openat ./getaddrinfo microsoft.com
openat(AT_FDCWD, "/etc/services", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
Read next chapter →