aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-04-16 17:11:21 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-04-16 17:11:21 +0300
commit61fa3896442b5629e28d36d4e9e924440e03d873 (patch)
treed7dfcc192300964e2f6ad161699ff1bedf23ccd2 /src
parentec591a702237f8a4141d7f85dc0c2923788db45f (diff)
downloadlibmicrohttpd-61fa3896442b5629e28d36d4e9e924440e03d873.tar.gz
libmicrohttpd-61fa3896442b5629e28d36d4e9e924440e03d873.zip
Fixes and improvements for 6c751386a2e06d35b6d072c064bd581ddd561c52
Fixed build on platforms without epoll, saved one sys-call for externally added connections.
Diffstat (limited to 'src')
-rw-r--r--src/microhttpd/daemon.c57
-rw-r--r--src/microhttpd/internal.h20
-rw-r--r--src/microhttpd/mhd_send.c71
3 files changed, 84 insertions, 64 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index fde1703d..294ed722 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -2376,7 +2376,7 @@ psk_gnutls_adapter (gnutls_session_t session,
2376 * @param non_blck indicate that socket in non-blocking mode 2376 * @param non_blck indicate that socket in non-blocking mode
2377 * @param sk_spipe_supprs indicate that the @a client_socket has 2377 * @param sk_spipe_supprs indicate that the @a client_socket has
2378 * set SIGPIPE suppression 2378 * set SIGPIPE suppression
2379 * @param sk_is_unix true if this is a UNIX domain socket (AF_UNIX) 2379 * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
2380 * @return pointer to the connection on success, NULL if this daemon could 2380 * @return pointer to the connection on success, NULL if this daemon could
2381 * not handle the connection (i.e. malloc failed, etc). 2381 * not handle the connection (i.e. malloc failed, etc).
2382 * The socket will be closed in case of error; 'errno' is 2382 * The socket will be closed in case of error; 'errno' is
@@ -2390,7 +2390,7 @@ new_connection_prepare_ (struct MHD_Daemon *daemon,
2390 bool external_add, 2390 bool external_add,
2391 bool non_blck, 2391 bool non_blck,
2392 bool sk_spipe_supprs, 2392 bool sk_spipe_supprs,
2393 bool sk_is_unix) 2393 enum MHD_tristate sk_is_nonip)
2394{ 2394{
2395 struct MHD_Connection *connection; 2395 struct MHD_Connection *connection;
2396 int eno = 0; 2396 int eno = 0;
@@ -2492,7 +2492,7 @@ new_connection_prepare_ (struct MHD_Daemon *daemon,
2492 connection->addr_len = addrlen; 2492 connection->addr_len = addrlen;
2493 connection->socket_fd = client_socket; 2493 connection->socket_fd = client_socket;
2494 connection->sk_nonblck = non_blck; 2494 connection->sk_nonblck = non_blck;
2495 connection->is_unix = sk_is_unix; 2495 connection->is_nonip = sk_is_nonip;
2496 connection->sk_spipe_suppress = sk_spipe_supprs; 2496 connection->sk_spipe_suppress = sk_spipe_supprs;
2497 connection->daemon = daemon; 2497 connection->daemon = daemon;
2498 connection->last_activity = MHD_monotonic_sec_counter (); 2498 connection->last_activity = MHD_monotonic_sec_counter ();
@@ -2863,7 +2863,7 @@ cleanup:
2863 * @param non_blck indicate that socket in non-blocking mode 2863 * @param non_blck indicate that socket in non-blocking mode
2864 * @param sk_spipe_supprs indicate that the @a client_socket has 2864 * @param sk_spipe_supprs indicate that the @a client_socket has
2865 * set SIGPIPE suppression 2865 * set SIGPIPE suppression
2866 * @param sk_is_unix true if this is a UNIX domain socket (AF_UNIX) 2866 * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
2867 * @return #MHD_YES on success, #MHD_NO if this daemon could 2867 * @return #MHD_YES on success, #MHD_NO if this daemon could
2868 * not handle the connection (i.e. malloc failed, etc). 2868 * not handle the connection (i.e. malloc failed, etc).
2869 * The socket will be closed in any case; 'errno' is 2869 * The socket will be closed in any case; 'errno' is
@@ -2877,7 +2877,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
2877 bool external_add, 2877 bool external_add,
2878 bool non_blck, 2878 bool non_blck,
2879 bool sk_spipe_supprs, 2879 bool sk_spipe_supprs,
2880 bool sk_is_unix) 2880 enum MHD_tristate sk_is_nonip)
2881{ 2881{
2882 struct MHD_Connection *connection; 2882 struct MHD_Connection *connection;
2883 2883
@@ -2923,7 +2923,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
2923 external_add, 2923 external_add,
2924 non_blck, 2924 non_blck,
2925 sk_spipe_supprs, 2925 sk_spipe_supprs,
2926 sk_is_unix); 2926 sk_is_nonip);
2927 if (NULL == connection) 2927 if (NULL == connection)
2928 return MHD_NO; 2928 return MHD_NO;
2929 2929
@@ -3348,7 +3348,6 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3348{ 3348{
3349 bool sk_nonbl; 3349 bool sk_nonbl;
3350 bool sk_spipe_supprs; 3350 bool sk_spipe_supprs;
3351 bool sk_is_unix = false;
3352 3351
3353 /* NOT thread safe with internal thread. TODO: fix thread safety. */ 3352 /* NOT thread safe with internal thread. TODO: fix thread safety. */
3354 if ((0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) && 3353 if ((0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
@@ -3419,20 +3418,6 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3419 _ ("Failed to set noninheritable mode on new client socket.\n")); 3418 _ ("Failed to set noninheritable mode on new client socket.\n"));
3420#endif 3419#endif
3421 } 3420 }
3422#ifdef SO_DOMAIN
3423 {
3424 int af;
3425 socklen_t len = sizeof (af);
3426
3427 if ( (0 == getsockopt (daemon->listen_fd,
3428 SOL_SOCKET,
3429 SO_DOMAIN,
3430 &af,
3431 &len)) &&
3432 (AF_UNIX == af) )
3433 sk_is_unix = true;
3434 }
3435#endif
3436 3421
3437#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3422#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3438 if (NULL != daemon->worker_pool) 3423 if (NULL != daemon->worker_pool)
@@ -3453,7 +3438,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3453 true, 3438 true,
3454 sk_nonbl, 3439 sk_nonbl,
3455 sk_spipe_supprs, 3440 sk_spipe_supprs,
3456 sk_is_unix); 3441 _MHD_UNKNOWN);
3457 } 3442 }
3458 /* all pools are at their connection limit, must refuse */ 3443 /* all pools are at their connection limit, must refuse */
3459 MHD_socket_close_chk_ (client_socket); 3444 MHD_socket_close_chk_ (client_socket);
@@ -3471,7 +3456,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
3471 true, 3456 true,
3472 sk_nonbl, 3457 sk_nonbl,
3473 sk_spipe_supprs, 3458 sk_spipe_supprs,
3474 sk_is_unix); 3459 _MHD_UNKNOWN);
3475} 3460}
3476 3461
3477 3462
@@ -5840,20 +5825,25 @@ parse_options_va (struct MHD_Daemon *daemon,
5840 { 5825 {
5841 daemon->listen_fd = va_arg (ap, 5826 daemon->listen_fd = va_arg (ap,
5842 MHD_socket); 5827 MHD_socket);
5843#ifdef SO_DOMAIN 5828#if defined(SO_DOMAIN) && defined(AF_UNIX)
5844 { 5829 {
5845 int af; 5830 int af;
5846 socklen_t len = sizeof (af); 5831 socklen_t len = sizeof (af);
5847 5832
5848 if ( (0 == getsockopt (daemon->listen_fd, 5833 if (0 == getsockopt (daemon->listen_fd,
5849 SOL_SOCKET, 5834 SOL_SOCKET,
5850 SO_DOMAIN, 5835 SO_DOMAIN,
5851 &af, 5836 &af,
5852 &len)) && 5837 &len))
5853 (AF_UNIX == af) ) 5838 {
5854 daemon->listen_is_unix = true; 5839 daemon->listen_is_unix = (AF_UNIX == af) ? _MHD_YES : MHD_NO;
5840 }
5841 else
5842 daemon->listen_is_unix = _MHD_UNKNOWN;
5855 } 5843 }
5856#endif 5844#else /* ! SO_DOMAIN || ! AF_UNIX */
5845 daemon->listen_is_unix = _MHD_UNKNOWN;
5846#endif /* ! SO_DOMAIN || ! AF_UNIX */
5857 } 5847 }
5858 break; 5848 break;
5859 case MHD_OPTION_EXTERNAL_LOGGER: 5849 case MHD_OPTION_EXTERNAL_LOGGER:
@@ -6342,6 +6332,7 @@ MHD_start_daemon_va (unsigned int flags,
6342 } 6332 }
6343#endif /* HTTPS_SUPPORT */ 6333#endif /* HTTPS_SUPPORT */
6344 daemon->listen_fd = MHD_INVALID_SOCKET; 6334 daemon->listen_fd = MHD_INVALID_SOCKET;
6335 daemon->listen_is_unix = _MHD_NO;
6345 daemon->listening_address_reuse = 0; 6336 daemon->listening_address_reuse = 0;
6346 daemon->options = *pflags; 6337 daemon->options = *pflags;
6347 pflags = &daemon->options; 6338 pflags = &daemon->options;
@@ -6722,6 +6713,8 @@ MHD_start_daemon_va (unsigned int flags,
6722 servaddr = (struct sockaddr *) &servaddr4; 6713 servaddr = (struct sockaddr *) &servaddr4;
6723 } 6714 }
6724 } 6715 }
6716 else
6717 daemon->listen_is_unix = _MHD_UNKNOWN;
6725 daemon->listen_fd = listen_fd; 6718 daemon->listen_fd = listen_fd;
6726 if (0 != (*pflags & MHD_USE_IPv6)) 6719 if (0 != (*pflags & MHD_USE_IPv6))
6727 { 6720 {
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index c939d3e2..fe71e9ab 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -174,7 +174,9 @@ enum MHD_tristate
174{ 174{
175 _MHD_UNKNOWN = -1, /**< State is not yet checked nor set */ 175 _MHD_UNKNOWN = -1, /**< State is not yet checked nor set */
176 _MHD_OFF = false, /**< State is "off" / "disabled" */ 176 _MHD_OFF = false, /**< State is "off" / "disabled" */
177 _MHD_ON = true /**< State is "on" / "enabled" */ 177 _MHD_NO = false, /**< State is "off" / "disabled" */
178 _MHD_ON = true, /**< State is "on" / "enabled" */
179 _MHD_YES = true /**< State is "on" / "enabled" */
178}; 180};
179 181
180 182
@@ -994,9 +996,10 @@ struct MHD_Connection
994 MHD_socket socket_fd; 996 MHD_socket socket_fd;
995 997
996 /** 998 /**
997 * true if #socket_fd is a UNIX domain socket, false (TCP) otherwise. 999 * true if @e socket_fd is not TCP/IP (a UNIX domain socket, a pipe),
1000 * false (TCP/IP) otherwise.
998 */ 1001 */
999 bool is_unix; 1002 enum MHD_tristate is_nonip;
1000 1003
1001 /** 1004 /**
1002 * true if #socket_fd is non-blocking, false otherwise. 1005 * true if #socket_fd is non-blocking, false otherwise.
@@ -1444,6 +1447,11 @@ struct MHD_Daemon
1444 */ 1447 */
1445 struct MHD_Connection *cleanup_tail; 1448 struct MHD_Connection *cleanup_tail;
1446 1449
1450 /**
1451 * _MHD_YES if the @e listen_fd socket is a UNIX domain socket.
1452 */
1453 enum MHD_tristate listen_is_unix;
1454
1447#ifdef EPOLL_SUPPORT 1455#ifdef EPOLL_SUPPORT
1448 /** 1456 /**
1449 * Head of EDLL of connections ready for processing (in epoll mode). 1457 * Head of EDLL of connections ready for processing (in epoll mode).
@@ -1469,12 +1477,6 @@ struct MHD_Daemon
1469 */ 1477 */
1470 bool listen_socket_in_epoll; 1478 bool listen_socket_in_epoll;
1471 1479
1472 /**
1473 * true if the @e listen_fd socket is a UNIX domain socket,
1474 * false if not.
1475 */
1476 bool listen_is_unix;
1477
1478#ifdef UPGRADE_SUPPORT 1480#ifdef UPGRADE_SUPPORT
1479#ifdef HTTPS_SUPPORT 1481#ifdef HTTPS_SUPPORT
1480 /** 1482 /**
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c
index e8ae35d2..7637773e 100644
--- a/src/microhttpd/mhd_send.c
+++ b/src/microhttpd/mhd_send.c
@@ -174,6 +174,9 @@ MHD_connection_set_nodelay_state_ (struct MHD_Connection *connection,
174 const MHD_SCKT_OPT_BOOL_ on_val = 1; 174 const MHD_SCKT_OPT_BOOL_ on_val = 1;
175 int err_code; 175 int err_code;
176 176
177 if (_MHD_YES == connection->is_nonip)
178 return true;
179
177 if (0 == setsockopt (connection->socket_fd, 180 if (0 == setsockopt (connection->socket_fd,
178 IPPROTO_TCP, 181 IPPROTO_TCP,
179 TCP_NODELAY, 182 TCP_NODELAY,
@@ -186,18 +189,29 @@ MHD_connection_set_nodelay_state_ (struct MHD_Connection *connection,
186 err_code = MHD_socket_get_error_ (); 189 err_code = MHD_socket_get_error_ ();
187 switch (err_code) 190 switch (err_code)
188 { 191 {
189 case ENOTSOCK: 192 case EINVAL:
190 /* FIXME: Could be we are talking to a pipe, maybe remember this 193 case ENOPROTOOPT:
191 and avoid all setsockopt() in the future? */ 194 case ENOTSOCK:
195 if (_MHD_NO == connection->is_nonip)
196 {
197#ifdef HAVE_MESSAGES
198 MHD_DLOG (connection->daemon,
199 _ ("Setting %s option to %s state failed "
200 "for TCP/IP socket %d: %s\n"),
201 "TCP_NODELAY",
202 nodelay_state ? _ ("ON") : _ ("OFF"),
203 (int) connection->socket_fd,
204 MHD_socket_strerr_ (err_code));
205#endif /* HAVE_MESSAGES */
206 }
207 else
208 connection->is_nonip = _MHD_YES;
192 break; 209 break;
193 case EBADF: 210 case EBADF:
194 /* FIXME: should we die hard here? */
195 case EINVAL:
196 /* FIXME: optlen invalid, should at least log this, maybe die */
197 case EFAULT: 211 case EFAULT:
198 /* wopsie, should at least log this, FIXME: maybe die */ 212 /* Hard errors, something is wrong. Too tricky to
199 case ENOPROTOOPT: 213 * break connection here, just log the message.
200 /* optlen unknown, should at least log this */ 214 * Shound't really happen too often. */
201 default: 215 default:
202#ifdef HAVE_MESSAGES 216#ifdef HAVE_MESSAGES
203 MHD_DLOG (connection->daemon, 217 MHD_DLOG (connection->daemon,
@@ -230,7 +244,7 @@ connection_set_cork_state_ (struct MHD_Connection *connection,
230 const MHD_SCKT_OPT_BOOL_ on_val = 1; 244 const MHD_SCKT_OPT_BOOL_ on_val = 1;
231 int err_code; 245 int err_code;
232 246
233 if (connection->is_unix) 247 if (_MHD_YES == connection->is_nonip)
234 return true; 248 return true;
235 if (0 == setsockopt (connection->socket_fd, 249 if (0 == setsockopt (connection->socket_fd,
236 IPPROTO_TCP, 250 IPPROTO_TCP,
@@ -244,18 +258,29 @@ connection_set_cork_state_ (struct MHD_Connection *connection,
244 err_code = MHD_socket_get_error_ (); 258 err_code = MHD_socket_get_error_ ();
245 switch (err_code) 259 switch (err_code)
246 { 260 {
247 case ENOTSOCK: 261 case EINVAL:
248 /* FIXME: Could be we are talking to a pipe, maybe remember this 262 case ENOPROTOOPT:
249 and avoid all setsockopt() in the future? */ 263 case ENOTSOCK:
264 if (_MHD_NO == connection->is_nonip)
265 {
266#ifdef HAVE_MESSAGES
267 MHD_DLOG (connection->daemon,
268 _ ("Setting %s option to %s state failed "
269 "for TCP/IP socket %d: %s\n"),
270 "TCP_NODELAY",
271 nodelay_state ? _ ("ON") : _ ("OFF"),
272 (int) connection->socket_fd,
273 MHD_socket_strerr_ (err_code));
274#endif /* HAVE_MESSAGES */
275 }
276 else
277 connection->is_nonip = _MHD_YES;
250 break; 278 break;
251 case EBADF: 279 case EBADF:
252 /* FIXME: should we die hard here? */
253 case EINVAL:
254 /* FIXME: optlen invalid, should at least log this, maybe die */
255 case EFAULT: 280 case EFAULT:
256 /* wopsie, should at least log this, FIXME: maybe die */ 281 /* Hard errors, something is wrong. Too tricky to
257 case ENOPROTOOPT: 282 * break connection here, just log the message.
258 /* optlen unknown, should at least log this */ 283 * Shound't really happen too often. */
259 default: 284 default:
260#ifdef HAVE_MESSAGES 285#ifdef HAVE_MESSAGES
261 MHD_DLOG (connection->daemon, 286 MHD_DLOG (connection->daemon,
@@ -295,7 +320,7 @@ pre_send_setopt (struct MHD_Connection *connection,
295 * Final piece is indicated by push_data == true. */ 320 * Final piece is indicated by push_data == true. */
296 const bool buffer_data = (! push_data); 321 const bool buffer_data = (! push_data);
297 322
298 if (connection->is_unix) 323 if (_MHD_YES == connection->is_nonip)
299 return; 324 return;
300 /* The goal is to minimise the total number of additional sys-calls 325 /* The goal is to minimise the total number of additional sys-calls
301 * before and after send(). 326 * before and after send().
@@ -519,8 +544,8 @@ zero_send_ (struct MHD_Connection *connection)
519{ 544{
520 int dummy; 545 int dummy;
521 546
522 if (connection->is_unix) 547 if (_MHD_YES == connection->is_nonip)
523 return; 548 return false;
524 mhd_assert (_MHD_OFF == connection->sk_corked); 549 mhd_assert (_MHD_OFF == connection->sk_corked);
525 mhd_assert (_MHD_ON == connection->sk_nodelay); 550 mhd_assert (_MHD_ON == connection->sk_nodelay);
526 dummy = 0; /* Mute compiler and analyzer warnings */ 551 dummy = 0; /* Mute compiler and analyzer warnings */
@@ -556,7 +581,7 @@ post_send_setopt (struct MHD_Connection *connection,
556 * Final piece is indicated by push_data == true. */ 581 * Final piece is indicated by push_data == true. */
557 const bool buffer_data = (! push_data); 582 const bool buffer_data = (! push_data);
558 583
559 if (connection->is_unix) 584 if (_MHD_YES == connection->is_nonip)
560 return; 585 return;
561 if (buffer_data) 586 if (buffer_data)
562 return; /* Nothing to do after send(). */ 587 return; /* Nothing to do after send(). */