From 2ad934742422ecb63fe3fafdc8c73d067a9e2fb7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 24 Mar 2017 18:17:50 +0100 Subject: implement GNUNET_NETWORK_test_port_free() for testcases to conveniently check if a port is available --- src/include/gnunet_network_lib.h | 12 +++++++++ src/util/network.c | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) 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 /** -- cgit v1.2.3