From d050a3a45ec66606a9d38a36a041afb76094e838 Mon Sep 17 00:00:00 2001 From: Narate Taerat Date: Fri, 19 Jan 2024 10:21:43 -0600 Subject: [PATCH] Make `ldms_xprt_listen_by_name()` prefers IPv6. `ldms_xprt_listen_by_name()` listened to 0.0.0.0 IPv4 address by default if `host` is `NULL`. This patch made `ldms_xprt_listen_by_name()` to fully rely on `getaddrinfo()` in resolving the addresses, and then we pick the first IPv6 address. If no IPv6 addresses available, the first address returned by `getaddrinfo()` is used. This has been tested with `ldmsd` on IPv4-only machine, and IPv4+6 machine. On IPv4+6 machine, if the users only to listen on IPv4 addresses, they have to either provide listening address on the CLI (e.g. `-x sock:411:0.0.0.0`), or specify the host in config file (e.g. `listen port=411 xprt=sock host=0.0.0.0`). --- ldms/src/core/ldms_xprt.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/ldms/src/core/ldms_xprt.c b/ldms/src/core/ldms_xprt.c index 2c8ac1a29..55df52f52 100644 --- a/ldms/src/core/ldms_xprt.c +++ b/ldms/src/core/ldms_xprt.c @@ -4180,32 +4180,26 @@ int ldms_xprt_listen_by_name(ldms_t x, const char *host, const char *port_no, ldms_event_cb_t cb, void *cb_arg) { int rc; - struct sockaddr_in sin; - struct addrinfo *ai; + struct addrinfo *ai_list, *ai, *aitr; struct addrinfo hints = { .ai_socktype = SOCK_STREAM, .ai_flags = AI_PASSIVE, }; - if (host) { - rc = getaddrinfo(host, port_no, &hints, &ai); - if (rc) - return EHOSTUNREACH; - rc = ldms_xprt_listen(x, ai->ai_addr, ai->ai_addrlen, cb, cb_arg); - freeaddrinfo(ai); - } else { - long ptmp; - ptmp = atol(port_no); - if (ptmp < 1 || ptmp > USHRT_MAX) { - return EINVAL; + rc = getaddrinfo(host, port_no, &hints, &ai_list); + if (rc) + return EHOSTUNREACH; + ai = NULL; + /* Prefer the first IPv6 address */ + for (aitr = ai_list; aitr; aitr = aitr->ai_next) { + if (aitr->ai_family == AF_INET6) { + ai = aitr; + break; } - unsigned short port = ptmp; - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = 0; - sin.sin_port = htons(port); - rc = ldms_xprt_listen(x, (struct sockaddr *)&sin, sizeof(sin), - cb, cb_arg); } + if (!ai) + ai = ai_list; + rc = ldms_xprt_listen(x, ai->ai_addr, ai->ai_addrlen, cb, cb_arg); + freeaddrinfo(ai); return rc; }