implement GNUNET_NETWORK_test_port_free() for testcases to conveniently check if...
authorChristian Grothoff <christian@grothoff.org>
Fri, 24 Mar 2017 17:17:50 +0000 (18:17 +0100)
committerChristian Grothoff <christian@grothoff.org>
Fri, 24 Mar 2017 17:18:48 +0000 (18:18 +0100)
src/include/gnunet_network_lib.h
src/util/network.c

index beca8380754834364cb824b117d3de4e6f4dc894..d9d3d90e778ba8854dd9ec43334125174e9f8794 100644 (file)
@@ -588,6 +588,18 @@ void
 GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds);
 
 
+/**
+ * Test if the given @a port is available.
+ *
+ * @param ipproto transport protocol to test (i.e. IPPROTO_TCP)
+ * @param port port number to test
+ * @return #GNUNET_OK if the port is available, #GNUNET_NO if not
+ */
+int
+GNUNET_NETWORK_test_port_free (int ipproto,
+                              uint16_t port);
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif
index c82caafd9aef4a914c6a77d634fc3d8d842de153..66a468e455a8f314eb5c56bb488d497f63d0681d 100644 (file)
@@ -1697,6 +1697,64 @@ initialize_select_thread ()
 
 #endif
 
+/**
+ * Test if the given @a port is available.
+ *
+ * @param ipproto transport protocol to test (i.e. IPPROTO_TCP)
+ * @param port port number to test
+ * @return #GNUNET_OK if the port is available, #GNUNET_NO if not
+ */
+int
+GNUNET_NETWORK_test_port_free (int ipproto,
+                              uint16_t port)
+{
+  struct GNUNET_NETWORK_Handle *socket;
+  int bind_status;
+  int socktype;
+  char open_port_str[6];
+  struct addrinfo hint;
+  struct addrinfo *ret;
+  struct addrinfo *ai;
+
+  GNUNET_snprintf (open_port_str,
+                  sizeof (open_port_str),
+                  "%u",
+                  (unsigned int) port);
+  socktype = (IPPROTO_TCP == ipproto)
+    ? SOCK_STREAM
+    : SOCK_DGRAM;
+  ret = NULL;
+  memset (&hint, 0, sizeof (hint));
+  hint.ai_family = AF_UNSPEC;  /* IPv4 and IPv6 */
+  hint.ai_socktype = socktype;
+  hint.ai_protocol = ipproto;
+  hint.ai_addrlen = 0;
+  hint.ai_addr = NULL;
+  hint.ai_canonname = NULL;
+  hint.ai_next = NULL;
+  hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */
+  GNUNET_assert (0 == getaddrinfo (NULL,
+                                  open_port_str,
+                                  &hint,
+                                  &ret));
+  for (ai = ret; NULL != ai; ai = ai->ai_next)
+  {
+    socket = GNUNET_NETWORK_socket_create (ai->ai_family,
+                                          ai->ai_socktype,
+                                          ai->ai_protocol);
+    if (NULL == socket)
+      continue;
+    bind_status = GNUNET_NETWORK_socket_bind (socket,
+                                             ai->ai_addr,
+                                             ai->ai_addrlen);
+    GNUNET_NETWORK_socket_close (socket);
+    if (GNUNET_OK != bind_status)
+      break;
+  }
+  freeaddrinfo (ret);
+  return bind_status;
+}
+
 
 #ifndef MINGW
 /**