aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2020-12-21 13:28:32 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2020-12-21 13:28:32 +0300
commit7c735289338a3cd9bfd7afa4131153a9d113b7ea (patch)
tree5ac20ba23cd36aaed7406494574ffd35242c7b1c
parent70201b593e8746b576418b81ee081c6fec9103f3 (diff)
downloadlibmicrohttpd-7c735289338a3cd9bfd7afa4131153a9d113b7ea.tar.gz
libmicrohttpd-7c735289338a3cd9bfd7afa4131153a9d113b7ea.zip
Fixed: avoided SIGPIPE if possiible
Added blocking of SIGPIPE on daemon threads. Added tracking of SIGPIPE suppressions on sockets. Added fallback to normal send() instead of sendfile() and writev() if SIGPIPE is not blocked.
-rw-r--r--configure.ac22
-rw-r--r--src/microhttpd/connection.c6
-rw-r--r--src/microhttpd/daemon.c144
-rw-r--r--src/microhttpd/internal.h10
-rw-r--r--src/microhttpd/mhd_send.c16
-rw-r--r--src/microhttpd/mhd_sockets.h18
6 files changed, 182 insertions, 34 deletions
diff --git a/configure.ac b/configure.ac
index 456650c5..2011dc30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -556,11 +556,30 @@ AS_CASE([[$with_threads]],
556) 556)
557 557
558# Check for posix threads support, regardless of configure parameters as 558# Check for posix threads support, regardless of configure parameters as
559# testsuite use only posix threads. 559# testsuite uses only posix threads.
560AX_PTHREAD( 560AX_PTHREAD(
561 [ 561 [
562 mhd_have_posix_threads='yes' 562 mhd_have_posix_threads='yes'
563 AC_DEFINE([[HAVE_PTHREAD_H]],[[1]],[Define to 1 if you have the <pthread.h> header file.]) 563 AC_DEFINE([[HAVE_PTHREAD_H]],[[1]],[Define to 1 if you have the <pthread.h> header file.])
564 AC_CACHE_CHECK([[whether pthread_sigmask(3) is available]],
565 [[mhd_cv_func_pthread_sigmask]], [dnl
566 save_LIBS="$LIBS"
567 save_CFLAGS="$CFLAGS"
568 LIBS="$PTHREAD_LIBS $LIBS"
569 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
570 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]],
571 [[
572 sigset_t nset, oset;
573 sigemptyset (&nset);
574 sigaddset (&nset, SIGPIPE);
575 if (0 != pthread_sigmask(SIG_BLOCK, &nset, &oset)) return 1;
576 ]])],
577 [[mhd_cv_func_pthread_sigmask="yes"]],[[mhd_cv_func_pthread_sigmask="no"]])
578 LIBS="${save_LIBS}"
579 CFLAGS="${save_CFLAGS}"
580 ])
581 AS_VAR_IF([mhd_cv_func_pthread_sigmask],["yes"],
582 [AC_DEFINE([[HAVE_PTHREAD_SIGMASK]],[[1]],[Define to 1 if you have the pthread_sigmask(3) function.])])
564 ],[[mhd_have_posix_threads='no']]) 583 ],[[mhd_have_posix_threads='no']])
565AM_CONDITIONAL([HAVE_POSIX_THREADS],[test "x$mhd_have_posix_threads" = "xyes"]) 584AM_CONDITIONAL([HAVE_POSIX_THREADS],[test "x$mhd_have_posix_threads" = "xyes"])
566 585
@@ -966,6 +985,7 @@ AC_CHECK_HEADERS_ONCE([fcntl.h math.h errno.h limits.h stdio.h locale.h sys/stat
966AC_CHECK_HEADERS([sys/types.h sys/time.h sys/msg.h time.h sys/mman.h sys/ioctl.h \ 985AC_CHECK_HEADERS([sys/types.h sys/time.h sys/msg.h time.h sys/mman.h sys/ioctl.h \
967 sys/socket.h sys/select.h netdb.h netinet/in.h netinet/ip.h netinet/tcp.h arpa/inet.h \ 986 sys/socket.h sys/select.h netdb.h netinet/in.h netinet/ip.h netinet/tcp.h arpa/inet.h \
968 endian.h machine/endian.h sys/endian.h sys/param.h sys/machine.h sys/byteorder.h machine/param.h sys/isa_defs.h \ 987 endian.h machine/endian.h sys/endian.h sys/param.h sys/machine.h sys/byteorder.h machine/param.h sys/isa_defs.h \
988 signal.h \
969 inttypes.h stddef.h unistd.h \ 989 inttypes.h stddef.h unistd.h \
970 sockLib.h inetLib.h net/if.h], [], [], [AC_INCLUDES_DEFAULT]) 990 sockLib.h inetLib.h net/if.h], [], [], [AC_INCLUDES_DEFAULT])
971 991
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 65431f96..7562ba52 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -3964,7 +3964,11 @@ MHD_queue_response (struct MHD_Connection *connection,
3964#if defined(_MHD_HAVE_SENDFILE) 3964#if defined(_MHD_HAVE_SENDFILE)
3965 if ( (response->fd == -1) || 3965 if ( (response->fd == -1) ||
3966 (response->is_pipe) || 3966 (response->is_pipe) ||
3967 (0 != (connection->daemon->options & MHD_USE_TLS)) ) 3967 (0 != (connection->daemon->options & MHD_USE_TLS))
3968#if ! defined(MHD_WINSOCK_SOCKETS) && defined(HAVE_SEND_SIGPIPE_SUPPRESS)
3969 || (! daemon->sigpipe_blocked && ! connection->sk_spipe_suppress)
3970#endif /* ! MHD_WINSOCK_SOCKETS && ! HAVE_SEND_SIGPIPE_SUPPRESS */
3971 )
3968 connection->resp_sender = MHD_resp_sender_std; 3972 connection->resp_sender = MHD_resp_sender_std;
3969 else 3973 else
3970 connection->resp_sender = MHD_resp_sender_sendfile; 3974 connection->resp_sender = MHD_resp_sender_sendfile;
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 81c9d22d..e308eec4 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -64,6 +64,12 @@
64#include <windows.h> 64#include <windows.h>
65#endif 65#endif
66 66
67#ifdef MHD_USE_POSIX_THREADS
68#ifdef HAVE_SIGNAL_H
69#include <signal.h>
70#endif /* HAVE_SIGNAL_H */
71#endif /* MHD_USE_POSIX_THREADS */
72
67/** 73/**
68 * Default connection limit. 74 * Default connection limit.
69 */ 75 */
@@ -2359,6 +2365,8 @@ psk_gnutls_adapter (gnutls_session_t session,
2359 * @param addrlen number of bytes in @a addr 2365 * @param addrlen number of bytes in @a addr
2360 * @param external_add indicate that socket has been added externally 2366 * @param external_add indicate that socket has been added externally
2361 * @param non_blck indicate that socket in non-blocking mode 2367 * @param non_blck indicate that socket in non-blocking mode
2368 * @param sk_spipe_supprs indicate that the @a client_socket has
2369 * set SIGPIPE suppression
2362 * @return pointer to the connection on success, NULL if this daemon could 2370 * @return pointer to the connection on success, NULL if this daemon could
2363 * not handle the connection (i.e. malloc failed, etc). 2371 * not handle the connection (i.e. malloc failed, etc).
2364 * The socket will be closed in case of error; 'errno' is 2372 * The socket will be closed in case of error; 'errno' is
@@ -2370,30 +2378,12 @@ new_connection_prepare_ (struct MHD_Daemon *daemon,
2370 const struct sockaddr *addr, 2378 const struct sockaddr *addr,
2371 socklen_t addrlen, 2379 socklen_t addrlen,
2372 bool external_add, 2380 bool external_add,
2373 bool non_blck) 2381 bool non_blck,
2382 bool sk_spipe_supprs)
2374{ 2383{
2375 struct MHD_Connection *connection; 2384 struct MHD_Connection *connection;
2376 int eno = 0; 2385 int eno = 0;
2377 2386
2378#ifdef MHD_socket_nosignal_
2379 if (! MHD_socket_nosignal_ (client_socket))
2380 {
2381#ifdef HAVE_MESSAGES
2382 MHD_DLOG (daemon,
2383 _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2384 MHD_socket_last_strerr_ ());
2385#endif
2386#ifndef MSG_NOSIGNAL
2387 /* Cannot use socket as it can produce SIGPIPE. */
2388#ifdef ENOTSOCK
2389 errno = ENOTSOCK;
2390#endif /* ENOTSOCK */
2391 return NULL;
2392#endif /* ! MSG_NOSIGNAL */
2393 }
2394#endif /* MHD_socket_nosignal_ */
2395
2396
2397#ifdef HAVE_MESSAGES 2387#ifdef HAVE_MESSAGES
2398#if _MHD_DEBUG_CONNECT 2388#if _MHD_DEBUG_CONNECT
2399 MHD_DLOG (daemon, 2389 MHD_DLOG (daemon,
@@ -2491,6 +2481,7 @@ new_connection_prepare_ (struct MHD_Daemon *daemon,
2491 connection->addr_len = addrlen; 2481 connection->addr_len = addrlen;
2492 connection->socket_fd = client_socket; 2482 connection->socket_fd = client_socket;
2493 connection->sk_nonblck = non_blck; 2483 connection->sk_nonblck = non_blck;
2484 connection->sk_spipe_suppress = sk_spipe_supprs;
2494 connection->daemon = daemon; 2485 connection->daemon = daemon;
2495 connection->last_activity = MHD_monotonic_sec_counter (); 2486 connection->last_activity = MHD_monotonic_sec_counter ();
2496 2487
@@ -2852,6 +2843,8 @@ cleanup:
2852 * @param external_add perform additional operations needed due 2843 * @param external_add perform additional operations needed due
2853 * to the application calling us directly 2844 * to the application calling us directly
2854 * @param non_blck indicate that socket in non-blocking mode 2845 * @param non_blck indicate that socket in non-blocking mode
2846 * @param sk_spipe_supprs indicate that the @a client_socket has
2847 * set SIGPIPE suppression
2855 * @return #MHD_YES on success, #MHD_NO if this daemon could 2848 * @return #MHD_YES on success, #MHD_NO if this daemon could
2856 * not handle the connection (i.e. malloc failed, etc). 2849 * not handle the connection (i.e. malloc failed, etc).
2857 * The socket will be closed in any case; 'errno' is 2850 * The socket will be closed in any case; 'errno' is
@@ -2863,7 +2856,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2863 const struct sockaddr *addr, 2856 const struct sockaddr *addr,
2864 socklen_t addrlen, 2857 socklen_t addrlen,
2865 bool external_add, 2858 bool external_add,
2866 bool non_blck) 2859 bool non_blck,
2860 bool sk_spipe_supprs)
2867{ 2861{
2868 struct MHD_Connection *connection; 2862 struct MHD_Connection *connection;
2869 2863
@@ -2904,7 +2898,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
2904 } 2898 }
2905 2899
2906 connection = new_connection_prepare_ (daemon, client_socket, addr, addrlen, 2900 connection = new_connection_prepare_ (daemon, client_socket, addr, addrlen,
2907 external_add, non_blck); 2901 external_add, non_blck,
2902 sk_spipe_supprs);
2908 if (NULL == connection) 2903 if (NULL == connection)
2909 return MHD_NO; 2904 return MHD_NO;
2910 2905
@@ -3327,6 +3322,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3327 socklen_t addrlen) 3322 socklen_t addrlen)
3328{ 3323{
3329 bool sk_nonbl; 3324 bool sk_nonbl;
3325 bool sk_spipe_supprs;
3330 3326
3331 /* NOT thread safe with internal thread. TODO: fix thread safety. */ 3327 /* NOT thread safe with internal thread. TODO: fix thread safety. */
3332 if ((0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) && 3328 if ((0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
@@ -3357,6 +3353,38 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3357 else 3353 else
3358 sk_nonbl = true; 3354 sk_nonbl = true;
3359 3355
3356#ifndef MHD_WINSOCK_SOCKETS
3357 sk_spipe_supprs = false;
3358#else /* MHD_WINSOCK_SOCKETS */
3359 sk_spipe_supprs = true; /* Nothing to suppress on W32 */
3360#endif /* MHD_WINSOCK_SOCKETS */
3361#if defined(MHD_socket_nosignal_)
3362 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s))
3363 {
3364#ifdef HAVE_MESSAGES
3365 MHD_DLOG (daemon,
3366 _ (
3367 "Failed to suppress SIGPIPE on new client socket: %s\n"),
3368 MHD_socket_last_strerr_ ());
3369#else /* ! HAVE_MESSAGES */
3370 (void) 0; /* Mute compiler warning */
3371#endif /* ! HAVE_MESSAGES */
3372#ifndef MSG_NOSIGNAL
3373 /* Application expects that SIGPIPE will be suppressed,
3374 * but suppression failed and SIGPIPE cannot be suppressed with send(). */
3375 if (! daemon->sigpipe_blocked)
3376 {
3377 int err = MHD_socket_get_error_ ();
3378 MHD_socket_close_ (s);
3379 MHD_socket_fset_error_ (err);
3380 return MHD_NO;
3381 }
3382#endif /* MSG_NOSIGNAL */
3383 }
3384 else
3385 sk_spipe_supprs = true;
3386#endif /* MHD_socket_nosignal_ */
3387
3360 if ( (0 != (daemon->options & MHD_USE_TURBO)) && 3388 if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
3361 (! MHD_socket_noninheritable_ (client_socket)) ) 3389 (! MHD_socket_noninheritable_ (client_socket)) )
3362 { 3390 {
@@ -3383,7 +3411,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3383 addr, 3411 addr,
3384 addrlen, 3412 addrlen,
3385 true, 3413 true,
3386 sk_nonbl); 3414 sk_nonbl,
3415 sk_spipe_supprs);
3387 } 3416 }
3388 /* all pools are at their connection limit, must refuse */ 3417 /* all pools are at their connection limit, must refuse */
3389 MHD_socket_close_chk_ (client_socket); 3418 MHD_socket_close_chk_ (client_socket);
@@ -3399,7 +3428,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3399 addr, 3428 addr,
3400 addrlen, 3429 addrlen,
3401 true, 3430 true,
3402 sk_nonbl); 3431 sk_nonbl,
3432 sk_spipe_supprs);
3403} 3433}
3404 3434
3405 3435
@@ -3430,6 +3460,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
3430 MHD_socket s; 3460 MHD_socket s;
3431 MHD_socket fd; 3461 MHD_socket fd;
3432 bool sk_nonbl; 3462 bool sk_nonbl;
3463 bool sk_spipe_supprs;
3433 3464
3434 mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ 3465 mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
3435 MHD_thread_ID_match_current_ (daemon->pid) ); 3466 MHD_thread_ID_match_current_ (daemon->pid) );
@@ -3448,11 +3479,21 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
3448 SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO 3479 SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO
3449 | SOCK_NOSIGPIPE_OR_ZERO); 3480 | SOCK_NOSIGPIPE_OR_ZERO);
3450 sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0); 3481 sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0);
3482#ifndef MHD_WINSOCK_SOCKETS
3483 sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0);
3484#else /* MHD_WINSOCK_SOCKETS */
3485 sk_spipe_supprs = true; /* Nothing to suppress on W32 */
3486#endif /* MHD_WINSOCK_SOCKETS */
3451#else /* ! USE_ACCEPT4 */ 3487#else /* ! USE_ACCEPT4 */
3452 s = accept (fd, 3488 s = accept (fd,
3453 addr, 3489 addr,
3454 &addrlen); 3490 &addrlen);
3455 sk_nonbl = false; 3491 sk_nonbl = false;
3492#ifndef MHD_WINSOCK_SOCKETS
3493 sk_spipe_supprs = false;
3494#else /* MHD_WINSOCK_SOCKETS */
3495 sk_spipe_supprs = true; /* Nothing to suppress on W32 */
3496#endif /* MHD_WINSOCK_SOCKETS */
3456#endif /* ! USE_ACCEPT4 */ 3497#endif /* ! USE_ACCEPT4 */
3457 if ( (MHD_INVALID_SOCKET == s) || 3498 if ( (MHD_INVALID_SOCKET == s) ||
3458 (addrlen <= 0) ) 3499 (addrlen <= 0) )
@@ -3531,6 +3572,30 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
3531#endif 3572#endif
3532 } 3573 }
3533#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ 3574#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
3575#if defined(MHD_socket_nosignal_)
3576 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s))
3577 {
3578#ifdef HAVE_MESSAGES
3579 MHD_DLOG (daemon,
3580 _ (
3581 "Failed to suppress SIGPIPE on incoming connection socket: %s\n"),
3582 MHD_socket_last_strerr_ ());
3583#else /* ! HAVE_MESSAGES */
3584 (void) 0; /* Mute compiler warning */
3585#endif /* ! HAVE_MESSAGES */
3586#ifndef MSG_NOSIGNAL
3587 /* Application expects that SIGPIPE will be suppressed,
3588 * but suppression failed and SIGPIPE cannot be suppressed with send(). */
3589 if (! daemon->sigpipe_blocked)
3590 {
3591 MHD_socket_close_ (s);
3592 return MHD_NO;
3593 }
3594#endif /* MSG_NOSIGNAL */
3595 }
3596 else
3597 sk_spipe_supprs = true;
3598#endif /* MHD_socket_nosignal_ */
3534#ifdef HAVE_MESSAGES 3599#ifdef HAVE_MESSAGES
3535#if _MHD_DEBUG_CONNECT 3600#if _MHD_DEBUG_CONNECT
3536 MHD_DLOG (daemon, 3601 MHD_DLOG (daemon,
@@ -3543,7 +3608,8 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
3543 addr, 3608 addr,
3544 addrlen, 3609 addrlen,
3545 false, 3610 false,
3546 sk_nonbl); 3611 sk_nonbl,
3612 sk_spipe_supprs);
3547 return MHD_YES; 3613 return MHD_YES;
3548} 3614}
3549 3615
@@ -5022,8 +5088,29 @@ static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
5022MHD_polling_thread (void *cls) 5088MHD_polling_thread (void *cls)
5023{ 5089{
5024 struct MHD_Daemon *daemon = cls; 5090 struct MHD_Daemon *daemon = cls;
5091#ifdef HAVE_PTHREAD_SIGMASK
5092 sigset_t s_mask;
5093 int err;
5094#endif /* HAVE_PTHREAD_SIGMASK */
5025 5095
5026 MHD_thread_init_ (&(daemon->pid)); 5096 MHD_thread_init_ (&(daemon->pid));
5097#ifdef HAVE_PTHREAD_SIGMASK
5098 if ((0 == sigemptyset (&s_mask)) &&
5099 (0 == sigaddset (&s_mask, SIGPIPE)))
5100 {
5101 err = pthread_sigmask (SIG_BLOCK, &s_mask, NULL);
5102 }
5103 else
5104 err = errno;
5105 if (0 == err)
5106 daemon->sigpipe_blocked = true;
5107#ifdef HAVE_MESSAGES
5108 else
5109 MHD_DLOG (daemon,
5110 _ ("Failed to block SIGPIPE on daemon thread: %s\n"),
5111 MHD_strerror_ (errno));
5112#endif /* HAVE_MESSAGES */
5113#endif /* HAVE_PTHREAD_SIGMASK */
5027 while (! daemon->shutdown) 5114 while (! daemon->shutdown)
5028 { 5115 {
5029 if (0 != (daemon->options & MHD_USE_POLL)) 5116 if (0 != (daemon->options & MHD_USE_POLL))
@@ -6116,6 +6203,13 @@ MHD_start_daemon_va (unsigned int flags,
6116 daemon->custom_error_log = &MHD_default_logger_; 6203 daemon->custom_error_log = &MHD_default_logger_;
6117 daemon->custom_error_log_cls = stderr; 6204 daemon->custom_error_log_cls = stderr;
6118#endif 6205#endif
6206#ifndef MHD_WINSOCK_SOCKETS
6207 daemon->sigpipe_blocked = false;
6208#else /* MHD_WINSOCK_SOCKETS */
6209 /* There is no SIGPIPE on W32, nothing to block. */
6210 daemon->sigpipe_blocked = true;
6211#endif /* _WIN32 && ! __CYGWIN__ */
6212
6119 if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) && 6213 if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
6120 (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) ) 6214 (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
6121 { 6215 {
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index a92f46f2..1c2496d8 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -929,6 +929,11 @@ struct MHD_Connection
929 bool sk_nonblck; 929 bool sk_nonblck;
930 930
931 /** 931 /**
932 * true if connection socket has set SIGPIPE suppression
933 */
934 bool sk_spipe_suppress;
935
936 /**
932 * Tracks TCP_CORK / TCP_NOPUSH of the connection socket. 937 * Tracks TCP_CORK / TCP_NOPUSH of the connection socket.
933 */ 938 */
934 enum MHD_tristate sk_corked; 939 enum MHD_tristate sk_corked;
@@ -1697,6 +1702,11 @@ struct MHD_Daemon
1697 */ 1702 */
1698 int strict_for_client; 1703 int strict_for_client;
1699 1704
1705 /**
1706 * True if SIGPIPE is blocked
1707 */
1708 bool sigpipe_blocked;
1709
1700#ifdef HTTPS_SUPPORT 1710#ifdef HTTPS_SUPPORT
1701#ifdef UPGRADE_SUPPORT 1711#ifdef UPGRADE_SUPPORT
1702 /** 1712 /**
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c
index 38a8a499..d7129337 100644
--- a/src/microhttpd/mhd_send.c
+++ b/src/microhttpd/mhd_send.c
@@ -815,11 +815,19 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
815 uint32_t vec_sent; 815 uint32_t vec_sent;
816 int err; 816 int err;
817#endif /* _WIN32 */ 817#endif /* _WIN32 */
818 bool no_vec; /* Is vector-send() disallowed? */
819
820 no_vec = false;
818#ifdef HTTPS_SUPPORT 821#ifdef HTTPS_SUPPORT
819 const bool no_vec = (connection->daemon->options & MHD_USE_TLS); 822 no_vec = no_vec || (connection->daemon->options & MHD_USE_TLS);
820#else /* ! HTTPS_SUPPORT */ 823#endif /* HTTPS_SUPPORT */
821 const bool no_vec = false; 824#if ! defined(MHD_WINSOCK_SOCKETS) && \
822#endif /* ! HTTPS_SUPPORT */ 825 (! defined(HAVE_SENDMSG) || ! defined(MSG_NOSIGNAL)) && \
826 defined(HAVE_SEND_SIGPIPE_SUPPRESS)
827 no_vec = no_vec || (! connection->daemon->sigpipe_blocked &&
828 ! connection->sk_spipe_suppress);
829#endif /* !MHD_WINSOCK_SOCKETS && (!HAVE_SENDMSG || ! MSG_NOSIGNAL)
830 && !HAVE_SEND_SIGPIPE_SUPPRESS */
823#endif /* _MHD_USE_SEND_VEC */ 831#endif /* _MHD_USE_SEND_VEC */
824 832
825 mhd_assert ( (NULL != body) || (0 == body_size) ); 833 mhd_assert ( (NULL != body) || (0 == body_size) );
diff --git a/src/microhttpd/mhd_sockets.h b/src/microhttpd/mhd_sockets.h
index e8cabc19..fbdb2f11 100644
--- a/src/microhttpd/mhd_sockets.h
+++ b/src/microhttpd/mhd_sockets.h
@@ -924,9 +924,20 @@ static const int _MHD_socket_int_one = 1;
924#define MHD_socket_nosignal_(sock) \ 924#define MHD_socket_nosignal_(sock) \
925 (! setsockopt ((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one, \ 925 (! setsockopt ((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one, \
926 sizeof(_MHD_socket_int_one))) 926 sizeof(_MHD_socket_int_one)))
927#elif defined(MHD_POSIX_SOCKETS) && defined(SOCK_NOSIGPIPE) && \ 927#endif /* SOL_SOCKET && SO_NOSIGPIPE */
928 defined(SOCK_CLOEXEC) 928
929#endif 929
930#if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \
931 defined(MSG_NOSIGNAL)
932/**
933 * Indicate that SIGPIPE can be suppressed for normal send() by flags
934 * or socket options.
935 * If this macro is undefined, MHD cannot suppress SIGPIPE for normal
936 * processing so sendfile() or writev() calls is not avoided.
937 */
938#define HAVE_SEND_SIGPIPE_SUPPRESS 1
939#endif /* MHD_WINSOCK_SOCKETS || MHD_socket_nosignal_ || MSG_NOSIGNAL */
940
930 941
931/** 942/**
932 * Create a listen socket, with noninheritable flag if possible. 943 * Create a listen socket, with noninheritable flag if possible.
@@ -937,4 +948,5 @@ static const int _MHD_socket_int_one = 1;
937MHD_socket 948MHD_socket
938MHD_socket_create_listen_ (int pf); 949MHD_socket_create_listen_ (int pf);
939 950
951
940#endif /* ! MHD_SOCKETS_H */ 952#endif /* ! MHD_SOCKETS_H */