]> git.proxmox.com Git - pve-cluster.git/commitdiff
pmxcfs: check all addresses from getaddrinfo to find non-loopback one
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 30 Jun 2023 09:29:18 +0000 (11:29 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Sat, 1 Jul 2023 14:35:24 +0000 (16:35 +0200)
Make the resolution of the node name to a local non-loopback address
through getaddrinfo more flexible.

Don't just ask for one, but for all addresses, then loop through the
returned linked list until the first non-loopback one is found.

It seems that some cloud-init templates hosting providers, like e.g.
OVH use, are misconfigured in always adding 127.0.1.1 for the
hostname to /etc/hosts, even if another mapping for the hostname
exists already. This popped up in our community forum with the
upgrade to bookworm, so might be related to the cloud-init version
from Bookworm.

Some examples pointed out by Alexandre:
https://forum.proxmox.com/threads/129678/
https://forum.proxmox.com/threads/129669/#post-568172
https://forum.proxmox.com/threads/129398/#post-568290

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
src/pmxcfs/pmxcfs.c

index d78a248e760241301c1cb614ee5fedd71bf440c6..9a14adefd9d0f08359c4ba654ace59d7d13d5625 100644 (file)
@@ -727,27 +727,32 @@ lookup_node_ip(const char *nodename)
 {
        char buf[INET6_ADDRSTRLEN];
        struct addrinfo *ainfo;
-       struct addrinfo ahints;
-       char *res = NULL;
-       memset(&ahints, 0, sizeof(ahints));
-
+       struct addrinfo ahints = {
+               .ai_flags = AI_V4MAPPED | AI_ALL,
+       };
        if (getaddrinfo(nodename, NULL, &ahints, &ainfo))
                return NULL;
 
-       if (ainfo->ai_family == AF_INET) {
-               struct sockaddr_in *sa = (struct sockaddr_in *)ainfo->ai_addr;
-               inet_ntop(ainfo->ai_family, &sa->sin_addr, buf, sizeof(buf));
-               if (strncmp(buf, "127.", 4) != 0) {
-                       res = g_strdup(buf);
-               }
-       } else if (ainfo->ai_family == AF_INET6) {
-               struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ainfo->ai_addr;
-               inet_ntop(ainfo->ai_family, &sa->sin6_addr, buf, sizeof(buf));
-               if (strcmp(buf, "::1") != 0) {
-                       res = g_strdup(buf);
+       char *res = NULL;
+       for (struct addrinfo *addr = ainfo; addr != NULL; addr = addr->ai_next) {
+               if (addr->ai_family == AF_INET) {
+                       struct sockaddr_in *sa = (struct sockaddr_in *)addr->ai_addr;
+                       inet_ntop(addr->ai_family, &sa->sin_addr, buf, sizeof(buf));
+                       if (strncmp(buf, "127.", 4) != 0) {
+                               res = g_strdup(buf);
+                               goto ret;
+                       }
+               } else if (addr->ai_family == AF_INET6) {
+                       struct sockaddr_in6 *sa = (struct sockaddr_in6 *)addr->ai_addr;
+                       inet_ntop(addr->ai_family, &sa->sin6_addr, buf, sizeof(buf));
+                       if (strcmp(buf, "::1") != 0) {
+                               res = g_strdup(buf);
+                               goto ret;
+                       }
                }
        }
 
+ret:
        freeaddrinfo(ainfo);
 
        return res;