[Libguestfs] [PATCH libnbd] lib/uri.c: nbd_get_uri: Do not translate port name into service

Richard W.M. Jones rjones at redhat.com
Wed Jun 30 19:37:46 UTC 2021


Because I forgot to use the NI_NUMERICSERV flag, getnameinfo would
translate the port number into a service name (when possible) using
/etc/services.  This is not really desirable since raw port numbers
are more portable and descriptive.  This also caused occasional test
failures when pick-a-port happened to pick a port number which
coincided with a service name.

This commit also adds a test.  Previous to the fix, the test failed with:

$ ./run tests/aio-connect-port
tests/.libs/aio-connect-port: actual URI nbd://127.0.0.1:sieve-filter/ != expected URI nbd://127.0.0.1:2000/

This test cannot be run as part of the test suite because it requires
a fixed port number.

See also
https://listman.redhat.com/archives/libguestfs/2021-June/msg00205.html

Reported-by: Martin Kletzander
---
 .gitignore               |   1 +
 lib/uri.c                |   3 +-
 tests/Makefile.am        |   9 +++
 tests/aio-connect-port.c | 128 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 140 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 865b689..602438d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -155,6 +155,7 @@ Makefile.in
 /stamp-h1
 /test-driver
 /tests/aio-connect
+/tests/aio-connect-port
 /tests/aio-parallel
 /tests/aio-parallel-load
 /tests/aio-parallel-load-tls
diff --git a/lib/uri.c b/lib/uri.c
index 9b97e46..bcecbad 100644
--- a/lib/uri.c
+++ b/lib/uri.c
@@ -422,7 +422,8 @@ nbd_unlocked_get_uri (struct nbd_handle *h)
 
       uri.scheme = using_tls ? "nbds" : "nbd";
       err = getnameinfo ((struct sockaddr *) &h->connaddr, h->connaddrlen,
-                         host, sizeof host, serv, sizeof serv, NI_NUMERICHOST);
+                         host, sizeof host, serv, sizeof serv,
+                         NI_NUMERICHOST | NI_NUMERICSERV);
       if (err != 0) {
         set_error (0, "getnameinfo: %s", gai_strerror (err));
         goto out;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 09de079..aad5513 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -203,6 +203,7 @@ check_PROGRAMS += \
 	connect-tcp \
 	connect-tcp6 \
 	aio-connect \
+	aio-connect-port \
 	aio-parallel \
 	aio-parallel-load \
 	synch-parallel \
@@ -252,6 +253,9 @@ TESTS += \
 	closure-lifetimes \
 	$(NULL)
 
+# This test is compiled but not run because it requires a fixed port:
+#	aio-connect-port
+
 errors_SOURCES = errors.c
 errors_CPPFLAGS = -I$(top_srcdir)/include
 errors_CFLAGS = $(WARNINGS_CFLAGS)
@@ -489,6 +493,11 @@ aio_connect_CPPFLAGS = -I$(top_srcdir)/include
 aio_connect_CFLAGS = $(WARNINGS_CFLAGS)
 aio_connect_LDADD = $(top_builddir)/lib/libnbd.la
 
+aio_connect_port_SOURCES = aio-connect-port.c
+aio_connect_port_CPPFLAGS = -I$(top_srcdir)/include
+aio_connect_port_CFLAGS = $(WARNINGS_CFLAGS)
+aio_connect_port_LDADD = $(top_builddir)/lib/libnbd.la
+
 aio_parallel_SOURCES = aio-parallel.c
 aio_parallel_CPPFLAGS = \
 	-I$(top_srcdir)/include \
diff --git a/tests/aio-connect-port.c b/tests/aio-connect-port.c
new file mode 100644
index 0000000..5f9613e
--- /dev/null
+++ b/tests/aio-connect-port.c
@@ -0,0 +1,128 @@
+/* NBD client library in userspace
+ * Copyright (C) 2013-2021 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Test connecting to a fixed IPv4 TCP port (2000) using
+ * nbd_aio_connect.  This test is compiled but not normally run
+ * because of the requirement for the fixed port number.
+ *
+ * See also:
+ * https://listman.redhat.com/archives/libguestfs/2021-June/msg00205.html
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <libnbd.h>
+
+#define PIDFILE "aio-connect-port.pid"
+
+int
+main (int argc, char *argv[])
+{
+  struct nbd_handle *nbd;
+  int port = 2000;
+  const char *port_str = "2000";
+  pid_t pid;
+  size_t i;
+  struct sockaddr_in addr;
+  char *actual_uri, *expected_uri;
+
+  unlink (PIDFILE);
+
+  pid = fork ();
+  if (pid == -1) {
+    perror ("fork");
+    exit (EXIT_FAILURE);
+  }
+  if (pid == 0) {
+    execlp ("nbdkit",
+            "nbdkit", "-f", "-p", port_str, "-P", PIDFILE,
+            "--exit-with-parent", "null", NULL);
+    perror ("nbdkit");
+    _exit (EXIT_FAILURE);
+  }
+
+  /* Wait for nbdkit to start listening. */
+  for (i = 0; i < 60; ++i) {
+    if (access (PIDFILE, F_OK) == 0)
+      break;
+    sleep (1);
+  }
+  unlink (PIDFILE);
+
+  nbd = nbd_create ();
+  if (nbd == NULL) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+  if (nbd_supports_uri (nbd) != 1) {
+    fprintf (stderr, "skip: compiled without URI support\n");
+    exit (77);
+  }
+
+  addr.sin_family = AF_INET;
+  addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+  addr.sin_port = htons (port);
+
+  if (nbd_aio_connect (nbd, (struct sockaddr *) &addr, sizeof addr) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+
+  /* Wait until we have connected. */
+  while (!nbd_aio_is_ready (nbd)) {
+    if (nbd_poll (nbd, -1) == -1) {
+      fprintf (stderr, "%s\n", nbd_get_error ());
+      exit (EXIT_FAILURE);
+    }
+  }
+
+  /* libnbd should be able to construct a URI for this connection. */
+  if (asprintf (&expected_uri, "nbd://127.0.0.1:%s/", port_str) == -1) {
+    perror ("asprintf");
+    exit (EXIT_FAILURE);
+  }
+  actual_uri = nbd_get_uri (nbd);
+  if (actual_uri == NULL) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+  if (strcmp (actual_uri, expected_uri) != 0) {
+    fprintf (stderr, "%s: actual URI %s != expected URI %s\n",
+             argv[0], actual_uri, expected_uri);
+    exit (EXIT_FAILURE);
+  }
+  free (actual_uri);
+  free (expected_uri);
+
+  if (nbd_shutdown (nbd, 0) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+
+  nbd_close (nbd);
+  exit (EXIT_SUCCESS);
+}
-- 
2.32.0




More information about the Libguestfs mailing list