[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [libmicrohttpd] 03/06: MHD_start_daemon(): added port autod
From: |
gnunet |
Subject: |
[GNUnet-SVN] [libmicrohttpd] 03/06: MHD_start_daemon(): added port autodetection if '0' (autoselect) is used for port number, Added new MHD_FEATURE value MHD_FEATURE_AUTODETECT_BIND_PORT. |
Date: |
Thu, 15 Jun 2017 23:43:28 +0200 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit da9f4fd6f2f37346d1cae368ec7683506df2287a
Author: Evgeny Grin (Karlson2k) <address@hidden>
AuthorDate: Thu Jun 15 10:37:40 2017 +0300
MHD_start_daemon(): added port autodetection if '0' (autoselect) is used
for port number,
Added new MHD_FEATURE value MHD_FEATURE_AUTODETECT_BIND_PORT.
---
configure.ac | 113 +++++++++++++++++++++++++++++++++++++++++++++++
src/include/microhttpd.h | 19 ++++++--
src/microhttpd/daemon.c | 92 +++++++++++++++++++++++++++++++++++++-
3 files changed, 219 insertions(+), 5 deletions(-)
diff --git a/configure.ac b/configure.ac
index 3b87c42b..443dcf24 100644
--- a/configure.ac
+++ b/configure.ac
@@ -756,6 +756,119 @@ AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
#endif
])
+AC_CHECK_DECLS([getsockname],
+ [
+ AC_CHECK_FUNCS([getsockname],
+ [
+ AC_CACHE_CHECK([[whether getsockname() is usable]],
[[mhc_cv_getsockname_usable]],
+ [
+ AC_RUN_IFELSE(
+ [
+ AC_LANG_SOURCE(
+ [[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+
+static void zr_mem(void *ptr, socklen_t size)
+{ char *mem = ptr; while(size--) {mem[0] = 0; mem++;} }
+
+int main(void)
+{
+ const socklen_t c_addr_size = (socklen_t)sizeof(struct sockaddr_in);
+ struct sockaddr_in sa;
+ socklen_t addr_size;
+ int ret = 1;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ int sckt;
+ const int invld_sckt = -1;
+#else
+ SOCKET sckt;
+ const SOCKET invld_sckt = INVALID_SOCKET;
+ WSADATA wsa_data;
+
+ if (0 != WSAStartup(MAKEWORD(2, 2), &wsa_data) || MAKEWORD(2, 2) !=
wsa_data.wVersion)
+ return 20;
+#endif
+
+ sckt = socket (PF_INET, SOCK_STREAM, 0);
+ if (invld_sckt != sckt)
+ {
+ zr_mem(&sa, c_addr_size);
+ sa.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ sa.sin_len = c_addr_size;
+#endif
+ if (0 == bind (sckt, (struct sockaddr *)&sa, c_addr_size))
+ {
+ if (0 == listen (sckt, 1))
+ {
+ addr_size = c_addr_size;
+ if (0 == getsockname (sckt, (struct sockaddr *)&sa, &addr_size))
+ {
+ if (c_addr_size >= addr_size)
+ {
+ if (0 != ntohs(sa.sin_port))
+ { ret = 0;
+ } else ret = 7;
+ } else ret = 6;
+ } else ret = 5;
+ } else ret = 4;
+ } else ret = 3;
+ } else ret = 2;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ close (sckt);
+#else
+ closesocket (sckt);
+ WSACleanup();
+#endif
+ return ret;
+}
+ ]]
+ )
+ ],
+ [[mhc_cv_getsockname_usable='yes']],
+ [[mhc_cv_getsockname_usable='no']],
+ [[mhc_cv_getsockname_usable='assuming yes']]
+ )
+ ]
+ )
+ AS_VAR_IF([[mhc_cv_getsockname_usable]], [["no"]], [:],
+ [AC_DEFINE([[MHD_USE_GETSOCKNAME]], [[1]], [Define if you have usable
`getsockname' function.])])
+ ]
+ )
+ ], [],
+ [[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+ ]]
+)
# Check for inter-thread signaling type
AC_ARG_ENABLE([[itc]],
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index d3b87c05..2319eef3 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -2095,7 +2095,11 @@ typedef int
* Start a webserver on the given port.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to (in host byte order)
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if MHD_OPTION_SOCK_ADDR or
+ * MHD_OPTION_LISTEN_SOCKET is provided
+ * or MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -2121,7 +2125,11 @@ MHD_start_daemon_va (unsigned int flags,
* #MHD_start_daemon_va.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if MHD_OPTION_SOCK_ADDR or
+ * MHD_OPTION_LISTEN_SOCKET is provided
+ * or MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -3425,7 +3433,12 @@ enum MHD_FEATURE
* It's always safe to use same file FD in multiple responses if MHD
* is run in any single thread mode.
*/
- MHD_FEATURE_RESPONSES_SHARED_FD = 18
+ MHD_FEATURE_RESPONSES_SHARED_FD = 18,
+
+ /**
+ * Get whether MHD support automatic detection of bind port number.
+ */
+ MHD_FEATURE_AUTODETECT_BIND_PORT = 19
};
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 0bf97b7c..dfb92b4d 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -4346,7 +4346,11 @@ unescape_wrapper (void *cls,
* #MHD_start_daemon_va.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if MHD_OPTION_SOCK_ADDR or
+ * MHD_OPTION_LISTEN_SOCKET is provided
+ * or MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -5082,7 +5086,11 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
* Start a webserver on the given port.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to (in host byte order)
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if MHD_OPTION_SOCK_ADDR or
+ * MHD_OPTION_LISTEN_SOCKET is provided
+ * or MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -5621,6 +5629,80 @@ MHD_start_daemon_va (unsigned int flags,
listen_fd = daemon->listen_fd;
}
+ if ( (0 == daemon->port) &&
+ (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
+ { /* Get port number. */
+ struct sockaddr *realaddr;
+#ifdef MHD_POSIX_SOCKETS
+ socklen_t alloc_len;
+#endif /* MHD_POSIX_SOCKETS */
+#ifdef HAVE_INET6
+ if (0 != (*pflags & MHD_USE_IPv6))
+ {
+ memset (&servaddr6,
+ 0,
+ sizeof (struct sockaddr_in6));
+ servaddr6.sin6_family = AF_INET6;
+#ifdef HAVE_SOCKADDR_IN_SIN_LEN
+ servaddr6.sin6_len = sizeof (struct sockaddr_in6);
+#endif /* HAVE_SOCKADDR_IN_SIN_LEN */
+ addrlen = (socklen_t) sizeof (struct sockaddr_in6);
+ realaddr = (struct sockaddr *) &servaddr6;
+ }
+ else
+#else /* ! HAVE_INET6 */
+ if (1)
+#endif /* ! HAVE_INET6 */
+ {
+ memset (&servaddr4,
+ 0,
+ sizeof (struct sockaddr_in));
+ servaddr4.sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_IN_SIN_LEN
+ servaddr4.sin_len = sizeof (struct sockaddr_in);
+#endif /* HAVE_SOCKADDR_IN_SIN_LEN */
+ addrlen = (socklen_t) sizeof (struct sockaddr_in);
+ realaddr = (struct sockaddr *) &servaddr4;
+ }
+#ifdef MHD_POSIX_SOCKETS
+ alloc_len = addrlen;
+#endif /* MHD_POSIX_SOCKETS */
+ if (0 != getsockname (listen_fd, realaddr, &addrlen))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _("Failed to get listen port number: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif /* HAVE_MESSAGES */
+ }
+#ifdef MHD_POSIX_SOCKETS
+ else if (alloc_len < addrlen)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _("Failed to get listen port number due to small buffer\n"));
+#endif /* HAVE_MESSAGES */
+ }
+#endif /* MHD_POSIX_SOCKETS */
+ else
+ {
+#ifdef HAVE_INET6
+ if (0 != (*pflags & MHD_USE_IPv6))
+ {
+ mhd_assert (AF_INET6 == servaddr6.sin6_family);
+ daemon->port = ntohs(servaddr6.sin6_port);
+ }
+ else
+#else /* ! HAVE_INET6 */
+ if (1)
+#endif /* ! HAVE_INET6 */
+ {
+ mhd_assert (AF_INET == servaddr4.sin_family);
+ daemon->port = ntohs(servaddr4.sin_port);
+ }
+ }
+ }
+
if ( (MHD_INVALID_SOCKET != listen_fd) &&
(! MHD_socket_nonblocking_ (listen_fd)) )
{
@@ -6425,6 +6507,12 @@ MHD_is_feature_supported(enum MHD_FEATURE feature)
#else
return MHD_NO;
#endif
+ case MHD_FEATURE_AUTODETECT_BIND_PORT:
+#ifdef MHD_USE_GETSOCKNAME
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
}
return MHD_NO;
}
--
To stop receiving notification emails like this one, please contact
address@hidden
- [GNUnet-SVN] [libmicrohttpd] branch master updated (8eb8e558 -> e8d937be), gnunet, 2017/06/15
- [GNUnet-SVN] [libmicrohttpd] 05/06: test_daemon: fixed error description, resource leak, gnunet, 2017/06/15
- [GNUnet-SVN] [libmicrohttpd] 01/06: Configure: removed unwanted extra square brackets, gnunet, 2017/06/15
- [GNUnet-SVN] [libmicrohttpd] 02/06: Correctly initialize IPv6 "any" address and non-standard IPv4 "any" address., gnunet, 2017/06/15
- [GNUnet-SVN] [libmicrohttpd] 04/06: MHD_get_daemon_info(): return bind port number by MHD_DAEMON_INFO_BIND_PORT, gnunet, 2017/06/15
- [GNUnet-SVN] [libmicrohttpd] 03/06: MHD_start_daemon(): added port autodetection if '0' (autoselect) is used for port number, Added new MHD_FEATURE value MHD_FEATURE_AUTODETECT_BIND_PORT.,
gnunet <=
- [GNUnet-SVN] [libmicrohttpd] 06/06: Make testsuite parallel build compatible (part 1), gnunet, 2017/06/15