summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-03-24 18:17:50 +0100
committerChristian Grothoff <christian@grothoff.org>2017-03-24 18:18:48 +0100
commit2ad934742422ecb63fe3fafdc8c73d067a9e2fb7 (patch)
tree780edc647a3ce9fdfd824e2dc233dd70a2bb79f3 /src
parent7307d73db807dd1fa295629d2b89c70cf603aeb4 (diff)
implement GNUNET_NETWORK_test_port_free() for testcases to conveniently check if a port is available
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_network_lib.h12
-rw-r--r--src/util/network.c58
2 files changed, 70 insertions, 0 deletions
diff --git a/src/include/gnunet_network_lib.h b/src/include/gnunet_network_lib.h
index beca83807..d9d3d90e7 100644
--- a/src/include/gnunet_network_lib.h
+++ b/src/include/gnunet_network_lib.h
@@ -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
diff --git a/src/util/network.c b/src/util/network.c
index c82caafd9..66a468e45 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -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
/**