aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--doc/libmicrohttpd.texi14
-rw-r--r--src/include/microhttpd.h10
-rw-r--r--src/microhttpd/connection.c3
-rw-r--r--src/microhttpd/connection_https.c6
-rw-r--r--src/microhttpd/daemon.c239
-rw-r--r--src/microhttpd/internal.c2
-rw-r--r--src/microhttpd/internal.h9
8 files changed, 212 insertions, 76 deletions
diff --git a/ChangeLog b/ChangeLog
index afbef967..e4af5f12 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
1Wed Oct 29 20:45:21 CET 2014
2 Adding MHD_OPTION_LISTENING_ADDRESS_REUSE option allowing clients
3 to force allowing re-use of the address:port combination
4 (SO_REUSEPORT). -MS
5
1Wed Oct 29 16:27:05 CET 2014 6Wed Oct 29 16:27:05 CET 2014
2 Adding MHD_DAEMON_INFO_CURRENT_CONNECTIONS to allow clients 7 Adding MHD_DAEMON_INFO_CURRENT_CONNECTIONS to allow clients
3 to query the number of active connections. -MS 8 to query the number of active connections. -MS
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index dcfbfc9d..91579c62 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -856,6 +856,20 @@ by the HTTPS daemon for key exchange. This option must be followed by
856a @code{const char *} argument. The argument would be a zero-terminated 856a @code{const char *} argument. The argument would be a zero-terminated
857string with a PEM encoded PKCS3 DH parameters structure suitable 857string with a PEM encoded PKCS3 DH parameters structure suitable
858for passing to @code{gnutls_dh_parms_import_pkcs3}. 858for passing to @code{gnutls_dh_parms_import_pkcs3}.
859
860@item MHD_OPTION_LISTENING_ADDRESS_REUSE
861@cindex bind, restricting bind
862@cindex reusing listening address
863This option must be followed by a @code{unsigned int} argument.
864If this option is present and true (nonzero) parameter is given, allow reusing
865the address:port of the listening socket (using @code{SO_REUSEPORT} on most
866platforms, and @code{SO_REUSEADDR} on Windows). If a false (zero) parameter is
867given, disallow reusing the the address:port of the listening socket (this
868usually requires no special action, but @code{SO_EXCLUSIVEADDRUSE} is needed on
869Windows). If this option is not present, default behaviour is undefined
870(currently, @code{SO_REUSEADDR} is used on all platforms, which disallows
871address:port reusing with the exception of Windows).
872
859@end table 873@end table
860@end deftp 874@end deftp
861 875
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index aac7b61b..27a29d42 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -846,8 +846,16 @@ enum MHD_OPTION
846 * HTTPS daemon for key exchange. 846 * HTTPS daemon for key exchange.
847 * This option must be followed by a `const char *` argument. 847 * This option must be followed by a `const char *` argument.
848 */ 848 */
849 MHD_OPTION_HTTPS_MEM_DHPARAMS = 24 849 MHD_OPTION_HTTPS_MEM_DHPARAMS = 24,
850 850
851 /**
852 * If present and set to true, allow reusing address:port socket
853 * (by using SO_REUSEPORT on most platform, or platform-specific ways).
854 * If present and set to false, disallow reusing address:port socket
855 * (does nothing on most plaform, but uses SO_EXCLUSIVEADDRUSE on Windows).
856 * This option must be followed by a `unsigned int` argument.
857 */
858 MHD_OPTION_LISTENING_ADDRESS_REUSE = 25,
851}; 859};
852 860
853 861
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 772af9f5..0515e1fb 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1306,7 +1306,8 @@ parse_cookie_header (struct MHD_Connection *connection)
1306 if (NULL == cpy) 1306 if (NULL == cpy)
1307 { 1307 {
1308#if HAVE_MESSAGES 1308#if HAVE_MESSAGES
1309 MHD_DLOG (connection->daemon, "Not enough memory to parse cookies!\n"); 1309 MHD_DLOG (connection->daemon,
1310 "Not enough memory to parse cookies!\n");
1310#endif 1311#endif
1311 transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE, 1312 transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1312 REQUEST_TOO_BIG); 1313 REQUEST_TOO_BIG);
diff --git a/src/microhttpd/connection_https.c b/src/microhttpd/connection_https.c
index b566d83c..0d7d5980 100644
--- a/src/microhttpd/connection_https.c
+++ b/src/microhttpd/connection_https.c
@@ -134,8 +134,10 @@ MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
134 unsigned int timeout; 134 unsigned int timeout;
135 135
136#if DEBUG_STATES 136#if DEBUG_STATES
137 MHD_DLOG (connection->daemon, "%s: state: %s\n", 137 MHD_DLOG (connection->daemon,
138 __FUNCTION__, MHD_state_to_string (connection->state)); 138 "%s: state: %s\n",
139 __FUNCTION__,
140 MHD_state_to_string (connection->state));
139#endif 141#endif
140 timeout = connection->connection_timeout; 142 timeout = connection->connection_timeout;
141 if ( (timeout != 0) && (timeout <= (MHD_monotonic_time() - connection->last_activity))) 143 if ( (timeout != 0) && (timeout <= (MHD_monotonic_time() - connection->last_activity)))
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 52cea5d8..b8b0ed55 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -552,7 +552,8 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
552 return 0; 552 return 0;
553#endif 553#endif
554#if HAVE_MESSAGES 554#if HAVE_MESSAGES
555 MHD_DLOG (daemon, "You need to specify a certificate and key location\n"); 555 MHD_DLOG (daemon,
556 "You need to specify a certificate and key location\n");
556#endif 557#endif
557 return -1; 558 return -1;
558} 559}
@@ -736,7 +737,9 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
736#if DEBUG_CONNECT 737#if DEBUG_CONNECT
737#if HAVE_MESSAGES 738#if HAVE_MESSAGES
738 if (NULL != max_fd) 739 if (NULL != max_fd)
739 MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd); 740 MHD_DLOG (daemon,
741 "Maximum socket in select set: %d\n",
742 *max_fd);
740#endif 743#endif
741#endif 744#endif
742 return MHD_YES; 745 return MHD_YES;
@@ -826,7 +829,7 @@ MHD_handle_connection (void *data)
826 { 829 {
827#if HAVE_MESSAGES 830#if HAVE_MESSAGES
828 MHD_DLOG (con->daemon, 831 MHD_DLOG (con->daemon,
829 "Can't add FD to fd_set\n"); 832 "Can't add FD to fd_set\n");
830#endif 833#endif
831 goto exit; 834 goto exit;
832 } 835 }
@@ -1200,7 +1203,9 @@ internal_add_connection (struct MHD_Daemon *daemon,
1200 1203
1201#if HAVE_MESSAGES 1204#if HAVE_MESSAGES
1202#if DEBUG_CONNECT 1205#if DEBUG_CONNECT
1203 MHD_DLOG (daemon, "Accepted connection on socket %d\n", client_socket); 1206 MHD_DLOG (daemon,
1207 "Accepted connection on socket %d\n",
1208 client_socket);
1204#endif 1209#endif
1205#endif 1210#endif
1206 if ( (daemon->connections == daemon->connection_limit) || 1211 if ( (daemon->connections == daemon->connection_limit) ||
@@ -1226,7 +1231,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
1226 { 1231 {
1227#if DEBUG_CLOSE 1232#if DEBUG_CLOSE
1228#if HAVE_MESSAGES 1233#if HAVE_MESSAGES
1229 MHD_DLOG (daemon, "Connection rejected, closing connection\n"); 1234 MHD_DLOG (daemon,
1235 "Connection rejected, closing connection\n");
1230#endif 1236#endif
1231#endif 1237#endif
1232 if (0 != MHD_socket_close_ (client_socket)) 1238 if (0 != MHD_socket_close_ (client_socket))
@@ -1415,7 +1421,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
1415 { 1421 {
1416 eno = errno; 1422 eno = errno;
1417#if HAVE_MESSAGES 1423#if HAVE_MESSAGES
1418 MHD_DLOG (daemon, "Failed to create a thread: %s\n", 1424 MHD_DLOG (daemon,
1425 "Failed to create a thread: %s\n",
1419 MHD_strerror_ (res_thread_create)); 1426 MHD_strerror_ (res_thread_create));
1420#endif 1427#endif
1421 goto cleanup; 1428 goto cleanup;
@@ -1839,7 +1846,9 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1839#endif 1846#endif
1840#if HAVE_MESSAGES 1847#if HAVE_MESSAGES
1841#if DEBUG_CONNECT 1848#if DEBUG_CONNECT
1842 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s); 1849 MHD_DLOG (daemon,
1850 "Accepted connection on socket %d\n",
1851 s);
1843#endif 1852#endif
1844#endif 1853#endif
1845 (void) internal_add_connection (daemon, s, 1854 (void) internal_add_connection (daemon, s,
@@ -1961,7 +1970,8 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
1961 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 1970 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1962 { 1971 {
1963#if HAVE_MESSAGES 1972#if HAVE_MESSAGES
1964 MHD_DLOG (daemon, "Illegal call to MHD_get_timeout\n"); 1973 MHD_DLOG (daemon,
1974 "Illegal call to MHD_get_timeout\n");
1965#endif 1975#endif
1966 return MHD_NO; 1976 return MHD_NO;
1967 } 1977 }
@@ -2196,7 +2206,9 @@ MHD_select (struct MHD_Daemon *daemon,
2196 if (EINTR == MHD_socket_errno_) 2206 if (EINTR == MHD_socket_errno_)
2197 return MHD_YES; 2207 return MHD_YES;
2198#if HAVE_MESSAGES 2208#if HAVE_MESSAGES
2199 MHD_DLOG (daemon, "select failed: %s\n", MHD_socket_last_strerr_ ()); 2209 MHD_DLOG (daemon,
2210 "select failed: %s\n",
2211 MHD_socket_last_strerr_ ());
2200#endif 2212#endif
2201 return MHD_NO; 2213 return MHD_NO;
2202 } 2214 }
@@ -2401,7 +2413,9 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2401 if (EINTR == MHD_socket_errno_) 2413 if (EINTR == MHD_socket_errno_)
2402 return MHD_YES; 2414 return MHD_YES;
2403#if HAVE_MESSAGES 2415#if HAVE_MESSAGES
2404 MHD_DLOG (daemon, "poll failed: %s\n", MHD_socket_last_strerr_ ()); 2416 MHD_DLOG (daemon,
2417 "poll failed: %s\n",
2418 MHD_socket_last_strerr_ ());
2405#endif 2419#endif
2406 return MHD_NO; 2420 return MHD_NO;
2407 } 2421 }
@@ -2492,10 +2506,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
2492 &event)) 2506 &event))
2493 { 2507 {
2494#if HAVE_MESSAGES 2508#if HAVE_MESSAGES
2495 if (0 != (daemon->options & MHD_USE_DEBUG)) 2509 MHD_DLOG (daemon,
2496 MHD_DLOG (daemon, 2510 "Call to epoll_ctl failed: %s\n",
2497 "Call to epoll_ctl failed: %s\n", 2511 MHD_socket_last_strerr_ ());
2498 MHD_socket_last_strerr_ ());
2499#endif 2512#endif
2500 return MHD_NO; 2513 return MHD_NO;
2501 } 2514 }
@@ -2544,10 +2557,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
2544 if (EINTR == MHD_socket_errno_) 2557 if (EINTR == MHD_socket_errno_)
2545 return MHD_YES; 2558 return MHD_YES;
2546#if HAVE_MESSAGES 2559#if HAVE_MESSAGES
2547 if (0 != (daemon->options & MHD_USE_DEBUG)) 2560 MHD_DLOG (daemon,
2548 MHD_DLOG (daemon, 2561 "Call to epoll_wait failed: %s\n",
2549 "Call to epoll_wait failed: %s\n", 2562 MHD_socket_last_strerr_ ());
2550 MHD_socket_last_strerr_ ());
2551#endif 2563#endif
2552 return MHD_NO; 2564 return MHD_NO;
2553 } 2565 }
@@ -2994,7 +3006,8 @@ parse_options_va (struct MHD_Daemon *daemon,
2994 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0) 3006 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
2995 { 3007 {
2996#if HAVE_MESSAGES 3008#if HAVE_MESSAGES
2997 MHD_DLOG(daemon, "Error initializing DH parameters\n"); 3009 MHD_DLOG(daemon,
3010 "Error initializing DH parameters\n");
2998#endif 3011#endif
2999 return MHD_NO; 3012 return MHD_NO;
3000 } 3013 }
@@ -3004,7 +3017,8 @@ parse_options_va (struct MHD_Daemon *daemon,
3004 GNUTLS_X509_FMT_PEM) < 0) 3017 GNUTLS_X509_FMT_PEM) < 0)
3005 { 3018 {
3006#if HAVE_MESSAGES 3019#if HAVE_MESSAGES
3007 MHD_DLOG(daemon, "Bad Diffie-Hellman parameters format\n"); 3020 MHD_DLOG(daemon,
3021 "Bad Diffie-Hellman parameters format\n");
3008#endif 3022#endif
3009 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 3023 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
3010 return MHD_NO; 3024 return MHD_NO;
@@ -3028,7 +3042,7 @@ parse_options_va (struct MHD_Daemon *daemon,
3028 ret = gnutls_priority_init (&daemon->priority_cache, 3042 ret = gnutls_priority_init (&daemon->priority_cache,
3029 pstr = va_arg (ap, const char*), 3043 pstr = va_arg (ap, const char*),
3030 NULL); 3044 NULL);
3031 if (ret != GNUTLS_E_SUCCESS) 3045 if (GNUTLS_E_SUCCESS != ret)
3032 { 3046 {
3033#if HAVE_MESSAGES 3047#if HAVE_MESSAGES
3034 MHD_DLOG (daemon, 3048 MHD_DLOG (daemon,
@@ -3084,6 +3098,9 @@ parse_options_va (struct MHD_Daemon *daemon,
3084 daemon->fastopen_queue_size = va_arg (ap, unsigned int); 3098 daemon->fastopen_queue_size = va_arg (ap, unsigned int);
3085 break; 3099 break;
3086#endif 3100#endif
3101 case MHD_OPTION_LISTENING_ADDRESS_REUSE:
3102 daemon->listening_address_reuse = va_arg (ap, unsigned int) ? 1 : -1;
3103 break;
3087 case MHD_OPTION_ARRAY: 3104 case MHD_OPTION_ARRAY:
3088 oa = va_arg (ap, struct MHD_OptionItem*); 3105 oa = va_arg (ap, struct MHD_OptionItem*);
3089 i = 0; 3106 i = 0;
@@ -3109,6 +3126,7 @@ parse_options_va (struct MHD_Daemon *daemon,
3109 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 3126 case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
3110 case MHD_OPTION_THREAD_POOL_SIZE: 3127 case MHD_OPTION_THREAD_POOL_SIZE:
3111 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 3128 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
3129 case MHD_OPTION_LISTENING_ADDRESS_REUSE:
3112 if (MHD_YES != parse_options (daemon, 3130 if (MHD_YES != parse_options (daemon,
3113 servaddr, 3131 servaddr,
3114 opt, 3132 opt,
@@ -3254,10 +3272,9 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3254 if (-1 == daemon->epoll_fd) 3272 if (-1 == daemon->epoll_fd)
3255 { 3273 {
3256#if HAVE_MESSAGES 3274#if HAVE_MESSAGES
3257 if (0 != (daemon->options & MHD_USE_DEBUG)) 3275 MHD_DLOG (daemon,
3258 MHD_DLOG (daemon, 3276 "Call to epoll_create1 failed: %s\n",
3259 "Call to epoll_create1 failed: %s\n", 3277 MHD_socket_last_strerr_ ());
3260 MHD_socket_last_strerr_ ());
3261#endif 3278#endif
3262 return MHD_NO; 3279 return MHD_NO;
3263 } 3280 }
@@ -3274,10 +3291,9 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3274 &event)) 3291 &event))
3275 { 3292 {
3276#if HAVE_MESSAGES 3293#if HAVE_MESSAGES
3277 if (0 != (daemon->options & MHD_USE_DEBUG)) 3294 MHD_DLOG (daemon,
3278 MHD_DLOG (daemon, 3295 "Call to epoll_ctl failed: %s\n",
3279 "Call to epoll_ctl failed: %s\n", 3296 MHD_socket_last_strerr_ ());
3280 MHD_socket_last_strerr_ ());
3281#endif 3297#endif
3282 return MHD_NO; 3298 return MHD_NO;
3283 } 3299 }
@@ -3293,10 +3309,9 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3293 &event)) 3309 &event))
3294 { 3310 {
3295#if HAVE_MESSAGES 3311#if HAVE_MESSAGES
3296 if (0 != (daemon->options & MHD_USE_DEBUG)) 3312 MHD_DLOG (daemon,
3297 MHD_DLOG (daemon, 3313 "Call to epoll_ctl failed: %s\n",
3298 "Call to epoll_ctl failed: %s\n", 3314 MHD_socket_last_strerr_ ());
3299 MHD_socket_last_strerr_ ());
3300#endif 3315#endif
3301 return MHD_NO; 3316 return MHD_NO;
3302 } 3317 }
@@ -3379,6 +3394,7 @@ MHD_start_daemon_va (unsigned int flags,
3379 } 3394 }
3380#endif 3395#endif
3381 daemon->socket_fd = MHD_INVALID_SOCKET; 3396 daemon->socket_fd = MHD_INVALID_SOCKET;
3397 daemon->listening_address_reuse = 0;
3382 daemon->options = (enum MHD_OPTION) flags; 3398 daemon->options = (enum MHD_OPTION) flags;
3383#if WINDOWS 3399#if WINDOWS
3384 /* Winsock is broken with respect to 'shutdown'; 3400 /* Winsock is broken with respect to 'shutdown';
@@ -3553,25 +3569,111 @@ MHD_start_daemon_va (unsigned int flags,
3553 if (MHD_INVALID_SOCKET == socket_fd) 3569 if (MHD_INVALID_SOCKET == socket_fd)
3554 { 3570 {
3555#if HAVE_MESSAGES 3571#if HAVE_MESSAGES
3556 if (0 != (flags & MHD_USE_DEBUG)) 3572 MHD_DLOG (daemon,
3557 MHD_DLOG (daemon, 3573 "Call to socket failed: %s\n",
3558 "Call to socket failed: %s\n", 3574 MHD_socket_last_strerr_ ());
3559 MHD_socket_last_strerr_ ());
3560#endif 3575#endif
3561 goto free_and_fail; 3576 goto free_and_fail;
3562 } 3577 }
3563 if ( (0 > setsockopt (socket_fd, 3578
3564 SOL_SOCKET, 3579 /* Apply the socket options according to listening_address_reuse. */
3565 SO_REUSEADDR, 3580 if (0 == daemon->listening_address_reuse)
3566 (void*)&on, sizeof (on))) && 3581 {
3567 (0 != (flags & MHD_USE_DEBUG)) ) 3582 /* No user requirement, use "traditional" default SO_REUSEADDR,
3568 { 3583 and do not fail if it doesn't work */
3584 if (0 > setsockopt (socket_fd,
3585 SOL_SOCKET,
3586 SO_REUSEADDR,
3587 (void*)&on, sizeof (on)))
3569#if HAVE_MESSAGES 3588#if HAVE_MESSAGES
3570 MHD_DLOG (daemon, 3589 MHD_DLOG (daemon,
3571 "setsockopt failed: %s\n", 3590 "setsockopt failed: %s\n",
3572 MHD_socket_last_strerr_ ()); 3591 MHD_socket_last_strerr_ ());
3573#endif 3592#endif
3574 } 3593 }
3594 else if (daemon->listening_address_reuse > 0)
3595 {
3596 /* User requested to allow reusing listening address:port.
3597 * Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
3598 * Fail if SO_REUSEPORT does not exist or setsockopt fails.
3599 */
3600#ifdef _WIN32
3601 /* SO_REUSEADDR on W32 has the same semantics
3602 as SO_REUSEPORT on BSD/Linux */
3603 if (0 > setsockopt (socket_fd,
3604 SOL_SOCKET,
3605 SO_REUSEADDR,
3606 (void*)&on, sizeof (on)))
3607 {
3608#if HAVE_MESSAGES
3609 MHD_DLOG (daemon,
3610 "setsockopt failed: %s\n",
3611 MHD_socket_last_strerr_ ());
3612#endif
3613 goto free_and_fail;
3614 }
3615#else
3616#ifndef SO_REUSEPORT
3617#ifdef LINUX
3618/* Supported since Linux 3.9, but often not present (or commented out)
3619 in the headers at this time; but 15 is reserved for this and
3620 thus should be safe to use. */
3621#define SO_REUSEPORT 15
3622#endif
3623#endif
3624#ifdef SO_REUSEPORT
3625 if (0 > setsockopt (socket_fd,
3626 SOL_SOCKET,
3627 SO_REUSEPORT,
3628 (void*)&on, sizeof (on)))
3629 {
3630#if HAVE_MESSAGES
3631 MHD_DLOG (daemon,
3632 "setsockopt failed: %s\n",
3633 MHD_socket_last_strerr_ ());
3634#endif
3635 goto free_and_fail;
3636 }
3637#else
3638 /* we're supposed to allow address:port re-use, but
3639 on this platform we cannot; fail hard */
3640#if HAVE_MESSAGES
3641 MHD_DLOG (daemon,
3642 "Cannot allow listening address reuse: SO_REUSEPORT not defined\n");
3643#endif
3644 goto free_and_fail;
3645#endif
3646#endif
3647 }
3648 else /* if (daemon->listening_address_reuse < 0) */
3649 {
3650 /* User requested to disallow reusing listening address:port.
3651 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
3652 * is used. Fail if it does not exist or setsockopt fails.
3653 */
3654#ifdef _WIN32
3655#ifdef SO_EXCLUSIVEADDRUSE
3656 if (0 > setsockopt (socket_fd,
3657 SOL_SOCKET,
3658 SO_EXCLUSIVEADDRUSE,
3659 (void*)&on, sizeof (on)))
3660 {
3661#if HAVE_MESSAGES
3662 MHD_DLOG (daemon,
3663 "setsockopt failed: %s\n",
3664 MHD_socket_last_strerr_ ());
3665#endif
3666 goto free_and_fail;
3667 }
3668#else /* SO_EXCLUSIVEADDRUSE not defined on W32? */
3669#if HAVE_MESSAGES
3670 MHD_DLOG (daemon,
3671 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n");
3672#endif
3673 goto free_and_fail;
3674#endif
3675#endif /* _WIN32 */
3676 }
3575 3677
3576 /* check for user supplied sockaddr */ 3678 /* check for user supplied sockaddr */
3577#if HAVE_INET6 3679#if HAVE_INET6
@@ -3621,28 +3723,24 @@ MHD_start_daemon_va (unsigned int flags,
3621 const char 3723 const char
3622#endif 3724#endif
3623 on = (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK)); 3725 on = (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK));
3624 if ( (0 > setsockopt (socket_fd, 3726 if (0 > setsockopt (socket_fd,
3625 IPPROTO_IPV6, IPV6_V6ONLY, 3727 IPPROTO_IPV6, IPV6_V6ONLY,
3626 &on, sizeof (on))) && 3728 &on, sizeof (on)))
3627 (0 != (flags & MHD_USE_DEBUG)) )
3628 {
3629#if HAVE_MESSAGES 3729#if HAVE_MESSAGES
3630 MHD_DLOG (daemon, 3730 MHD_DLOG (daemon,
3631 "setsockopt failed: %s\n", 3731 "setsockopt failed: %s\n",
3632 MHD_socket_last_strerr_ ()); 3732 MHD_socket_last_strerr_ ());
3633#endif 3733#endif
3634 }
3635#endif 3734#endif
3636#endif 3735#endif
3637 } 3736 }
3638 if (-1 == bind (socket_fd, servaddr, addrlen)) 3737 if (-1 == bind (socket_fd, servaddr, addrlen))
3639 { 3738 {
3640#if HAVE_MESSAGES 3739#if HAVE_MESSAGES
3641 if (0 != (flags & MHD_USE_DEBUG)) 3740 MHD_DLOG (daemon,
3642 MHD_DLOG (daemon, 3741 "Failed to bind to port %u: %s\n",
3643 "Failed to bind to port %u: %s\n", 3742 (unsigned int) port,
3644 (unsigned int) port, 3743 MHD_socket_last_strerr_ ());
3645 MHD_socket_last_strerr_ ());
3646#endif 3744#endif
3647 if (0 != MHD_socket_close_ (socket_fd)) 3745 if (0 != MHD_socket_close_ (socket_fd))
3648 MHD_PANIC ("close failed\n"); 3746 MHD_PANIC ("close failed\n");
@@ -3686,10 +3784,9 @@ MHD_start_daemon_va (unsigned int flags,
3686 if (listen (socket_fd, 32) < 0) 3784 if (listen (socket_fd, 32) < 0)
3687 { 3785 {
3688#if HAVE_MESSAGES 3786#if HAVE_MESSAGES
3689 if (0 != (flags & MHD_USE_DEBUG)) 3787 MHD_DLOG (daemon,
3690 MHD_DLOG (daemon, 3788 "Failed to listen for connections: %s\n",
3691 "Failed to listen for connections: %s\n", 3789 MHD_socket_last_strerr_ ());
3692 MHD_socket_last_strerr_ ());
3693#endif 3790#endif
3694 if (0 != MHD_socket_close_ (socket_fd)) 3791 if (0 != MHD_socket_close_ (socket_fd))
3695 MHD_PANIC ("close failed\n"); 3792 MHD_PANIC ("close failed\n");
@@ -3705,11 +3802,10 @@ MHD_start_daemon_va (unsigned int flags,
3705 (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) ) 3802 (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
3706 { 3803 {
3707#if HAVE_MESSAGES 3804#if HAVE_MESSAGES
3708 if ((flags & MHD_USE_DEBUG) != 0) 3805 MHD_DLOG (daemon,
3709 MHD_DLOG (daemon, 3806 "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
3710 "Socket descriptor larger than FD_SETSIZE: %d > %d\n", 3807 socket_fd,
3711 socket_fd, 3808 FD_SETSIZE);
3712 FD_SETSIZE);
3713#endif 3809#endif
3714 if (0 != MHD_socket_close_ (socket_fd)) 3810 if (0 != MHD_socket_close_ (socket_fd))
3715 MHD_PANIC ("close failed\n"); 3811 MHD_PANIC ("close failed\n");
@@ -4123,7 +4219,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
4123 4219
4124#if DEBUG_CLOSE 4220#if DEBUG_CLOSE
4125#if HAVE_MESSAGES 4221#if HAVE_MESSAGES
4126 MHD_DLOG (daemon, "MHD listen socket shutdown\n"); 4222 MHD_DLOG (daemon,
4223 "MHD listen socket shutdown\n");
4127#endif 4224#endif
4128#endif 4225#endif
4129 4226
diff --git a/src/microhttpd/internal.c b/src/microhttpd/internal.c
index 597457f8..37ba1471 100644
--- a/src/microhttpd/internal.c
+++ b/src/microhttpd/internal.c
@@ -95,7 +95,7 @@ MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...)
95{ 95{
96 va_list va; 96 va_list va;
97 97
98 if ((daemon->options & MHD_USE_DEBUG) == 0) 98 if (0 == (daemon->options & MHD_USE_DEBUG))
99 return; 99 return;
100 va_start (va, format); 100 va_start (va, format);
101 daemon->custom_error_log (daemon->custom_error_log_cls, format, va); 101 daemon->custom_error_log (daemon->custom_error_log_cls, format, va);
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 17798b30..4b25ccb3 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1099,6 +1099,15 @@ struct MHD_Daemon
1099 */ 1099 */
1100 MHD_socket socket_fd; 1100 MHD_socket socket_fd;
1101 1101
1102 /**
1103 * Whether to allow/disallow/ignore reuse of listening address.
1104 * The semantics is the following:
1105 * 0: ignore (user did not ask for neither allow/disallow, use SO_REUSEADDR)
1106 * >0: allow (use SO_REUSEPORT on most platforms, SO_REUSEADDR on Windows)
1107 * <0: disallow (mostly no action, SO_EXCLUSIVEADDRUSE on Windows)
1108 */
1109 int listening_address_reuse;
1110
1102#if EPOLL_SUPPORT 1111#if EPOLL_SUPPORT
1103 /** 1112 /**
1104 * File descriptor associated with our epoll loop. 1113 * File descriptor associated with our epoll loop.