diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-04-16 17:11:21 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-04-16 17:11:21 +0300 |
commit | 61fa3896442b5629e28d36d4e9e924440e03d873 (patch) | |
tree | d7dfcc192300964e2f6ad161699ff1bedf23ccd2 /src | |
parent | ec591a702237f8a4141d7f85dc0c2923788db45f (diff) | |
download | libmicrohttpd-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.c | 57 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 20 | ||||
-rw-r--r-- | src/microhttpd/mhd_send.c | 71 |
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(). */ |