diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-10-24 15:18:26 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-11-01 20:51:01 +0300 |
commit | 384cb2ab655970311ef89993810f7b62ad55b189 (patch) | |
tree | 2ca0d63f40e816aa7d2b198b29fc340875d073d8 | |
parent | 47f1d52e799227322c83d3114d3a6b7b54d2e5dd (diff) | |
download | libmicrohttpd-384cb2ab655970311ef89993810f7b62ad55b189.tar.gz libmicrohttpd-384cb2ab655970311ef89993810f7b62ad55b189.zip |
Deduplicated connection's closure code, improved TLS closure.
-rw-r--r-- | src/microhttpd/connection.c | 44 | ||||
-rw-r--r-- | src/microhttpd/connection.h | 10 | ||||
-rw-r--r-- | src/microhttpd/connection_https.c | 20 | ||||
-rw-r--r-- | src/microhttpd/connection_https.h | 12 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 9 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 5 |
6 files changed, 88 insertions, 12 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index d3ccdf26..6b0501e8 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -36,6 +36,9 @@ | |||
36 | #include "mhd_sockets.h" | 36 | #include "mhd_sockets.h" |
37 | #include "mhd_compat.h" | 37 | #include "mhd_compat.h" |
38 | #include "mhd_itc.h" | 38 | #include "mhd_itc.h" |
39 | #ifdef HTTPS_SUPPORT | ||
40 | #include "connection_https.h" | ||
41 | #endif /* HTTPS_SUPPORT */ | ||
39 | 42 | ||
40 | 43 | ||
41 | /** | 44 | /** |
@@ -491,6 +494,41 @@ need_100_continue (struct MHD_Connection *connection) | |||
491 | 494 | ||
492 | 495 | ||
493 | /** | 496 | /** |
497 | * Mark connection as "closed". | ||
498 | * @remark To be called from any thread. | ||
499 | * | ||
500 | * @param connection connection to close | ||
501 | */ | ||
502 | void | ||
503 | MHD_connection_mark_closed_ (struct MHD_Connection *connection) | ||
504 | { | ||
505 | struct MHD_Daemon * const daemon = connection->daemon; | ||
506 | |||
507 | connection->state = MHD_CONNECTION_CLOSED; | ||
508 | connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; | ||
509 | if (0 == (daemon->options & MHD_USE_EPOLL_TURBO)) | ||
510 | { | ||
511 | #ifdef HTTPS_SUPPORT | ||
512 | /* For TLS connection use shutdown of TLS layer | ||
513 | * and do not shutdown TCP socket. This give more | ||
514 | * chances to send TLS closure data to remote side. | ||
515 | * Closure of TLS layer will be interpreted by | ||
516 | * remote side as end of transmission. */ | ||
517 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
518 | { | ||
519 | if (MHD_NO == MHD_tls_connection_shutdown(connection)) | ||
520 | shutdown (connection->socket_fd, | ||
521 | SHUT_WR); | ||
522 | } | ||
523 | else /* Combined with next 'shutdown()'. */ | ||
524 | #endif /* HTTPS_SUPPORT */ | ||
525 | shutdown (connection->socket_fd, | ||
526 | SHUT_WR); | ||
527 | } | ||
528 | } | ||
529 | |||
530 | |||
531 | /** | ||
494 | * Close the given connection and give the | 532 | * Close the given connection and give the |
495 | * specified termination code to the user. | 533 | * specified termination code to the user. |
496 | * @remark To be called only from thread that | 534 | * @remark To be called only from thread that |
@@ -507,11 +545,7 @@ MHD_connection_close_ (struct MHD_Connection *connection, | |||
507 | struct MHD_Response * const resp = connection->response; | 545 | struct MHD_Response * const resp = connection->response; |
508 | 546 | ||
509 | daemon = connection->daemon; | 547 | daemon = connection->daemon; |
510 | if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO)) | 548 | MHD_connection_mark_closed_ (connection); |
511 | shutdown (connection->socket_fd, | ||
512 | SHUT_WR); | ||
513 | connection->state = MHD_CONNECTION_CLOSED; | ||
514 | connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; | ||
515 | if (NULL != resp) | 549 | if (NULL != resp) |
516 | { | 550 | { |
517 | connection->response = NULL; | 551 | connection->response = NULL; |
diff --git a/src/microhttpd/connection.h b/src/microhttpd/connection.h index a962a40c..ecbe2378 100644 --- a/src/microhttpd/connection.h +++ b/src/microhttpd/connection.h | |||
@@ -85,6 +85,16 @@ MHD_connection_handle_idle (struct MHD_Connection *connection); | |||
85 | 85 | ||
86 | 86 | ||
87 | /** | 87 | /** |
88 | * Mark connection as "closed". | ||
89 | * @remark To be called from any thread. | ||
90 | * | ||
91 | * @param connection connection to close | ||
92 | */ | ||
93 | void | ||
94 | MHD_connection_mark_closed_ (struct MHD_Connection *connection); | ||
95 | |||
96 | |||
97 | /** | ||
88 | * Close the given connection and give the | 98 | * Close the given connection and give the |
89 | * specified termination code to the user. | 99 | * specified termination code to the user. |
90 | * @remark To be called only from thread that | 100 | * @remark To be called only from thread that |
diff --git a/src/microhttpd/connection_https.c b/src/microhttpd/connection_https.c index bbfebd22..f1f1f90c 100644 --- a/src/microhttpd/connection_https.c +++ b/src/microhttpd/connection_https.c | |||
@@ -152,8 +152,6 @@ MHD_tls_connection_handle_idle (struct MHD_Connection *connection) | |||
152 | break; | 152 | break; |
153 | /* close connection if necessary */ | 153 | /* close connection if necessary */ |
154 | case MHD_CONNECTION_CLOSED: | 154 | case MHD_CONNECTION_CLOSED: |
155 | gnutls_bye (connection->tls_session, | ||
156 | GNUTLS_SHUT_RDWR); | ||
157 | return MHD_connection_handle_idle (connection); | 155 | return MHD_connection_handle_idle (connection); |
158 | default: | 156 | default: |
159 | if ( (0 != gnutls_record_check_pending (connection->tls_session)) && | 157 | if ( (0 != gnutls_record_check_pending (connection->tls_session)) && |
@@ -183,4 +181,22 @@ MHD_set_https_callbacks (struct MHD_Connection *connection) | |||
183 | connection->idle_handler = &MHD_tls_connection_handle_idle; | 181 | connection->idle_handler = &MHD_tls_connection_handle_idle; |
184 | } | 182 | } |
185 | 183 | ||
184 | |||
185 | /** | ||
186 | * Initiate shutdown of TLS layer of connection. | ||
187 | * | ||
188 | * @param connection to use | ||
189 | * @return #MHD_YES if succeed, #MHD_NO otherwise. | ||
190 | */ | ||
191 | int | ||
192 | MHD_tls_connection_shutdown (struct MHD_Connection *connection) | ||
193 | { | ||
194 | if (MHD_NO != connection->tls_closed) | ||
195 | return MHD_NO; | ||
196 | |||
197 | connection->tls_closed = MHD_YES; | ||
198 | return (GNUTLS_E_SUCCESS == gnutls_bye(connection->tls_session, GNUTLS_SHUT_WR)) ? | ||
199 | MHD_YES : MHD_NO; | ||
200 | } | ||
201 | |||
186 | /* end of connection_https.c */ | 202 | /* end of connection_https.c */ |
diff --git a/src/microhttpd/connection_https.h b/src/microhttpd/connection_https.h index 02ffb52e..23ae685b 100644 --- a/src/microhttpd/connection_https.h +++ b/src/microhttpd/connection_https.h | |||
@@ -37,6 +37,16 @@ | |||
37 | */ | 37 | */ |
38 | void | 38 | void |
39 | MHD_set_https_callbacks (struct MHD_Connection *connection); | 39 | MHD_set_https_callbacks (struct MHD_Connection *connection); |
40 | #endif | 40 | |
41 | |||
42 | /** | ||
43 | * Initiate shutdown of TLS layer of connection. | ||
44 | * | ||
45 | * @param connection to use | ||
46 | * @return #MHD_YES if succeed, #MHD_NO otherwise. | ||
47 | */ | ||
48 | int | ||
49 | MHD_tls_connection_shutdown (struct MHD_Connection *connection); | ||
50 | #endif /* HTTPS_SUPPORT */ | ||
41 | 51 | ||
42 | #endif | 52 | #endif |
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 006e8d54..b192dbfb 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -3569,7 +3569,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
3569 | struct MHD_UpgradeResponseHandle * const urh = ueh->urh; | 3569 | struct MHD_UpgradeResponseHandle * const urh = ueh->urh; |
3570 | 3570 | ||
3571 | /* Each MHD_UpgradeResponseHandle can be processed two times: | 3571 | /* Each MHD_UpgradeResponseHandle can be processed two times: |
3572 | * one for TLS data and one for socketpair data. | 3572 | * one time for TLS data and one time for socketpair data. |
3573 | * If forwarding was finished on first time, second time must | 3573 | * If forwarding was finished on first time, second time must |
3574 | * be skipped as urh must not be used anymore. */ | 3574 | * be skipped as urh must not be used anymore. */ |
3575 | if (MHD_NO != urh->clean_ready) | 3575 | if (MHD_NO != urh->clean_ready) |
@@ -3915,10 +3915,11 @@ close_connection (struct MHD_Connection *pos) | |||
3915 | { | 3915 | { |
3916 | struct MHD_Daemon *daemon = pos->daemon; | 3916 | struct MHD_Daemon *daemon = pos->daemon; |
3917 | 3917 | ||
3918 | pos->state = MHD_CONNECTION_CLOSED; | ||
3919 | pos->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; | ||
3920 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3918 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3921 | return; /* must let thread to the rest */ | 3919 | { |
3920 | MHD_connection_mark_closed_ (pos); | ||
3921 | return; /* must let thread to do the rest */ | ||
3922 | } | ||
3922 | MHD_connection_close_ (pos, | 3923 | MHD_connection_close_ (pos, |
3923 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); | 3924 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); |
3924 | if (pos->connection_timeout == pos->daemon->connection_timeout) | 3925 | if (pos->connection_timeout == pos->daemon->connection_timeout) |
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index bb9974a9..95314d5d 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h | |||
@@ -911,6 +911,11 @@ struct MHD_Connection | |||
911 | * even though the socket is not? | 911 | * even though the socket is not? |
912 | */ | 912 | */ |
913 | int tls_read_ready; | 913 | int tls_read_ready; |
914 | |||
915 | /** | ||
916 | * TLS layer was shut down? | ||
917 | */ | ||
918 | int tls_closed; | ||
914 | #endif | 919 | #endif |
915 | 920 | ||
916 | /** | 921 | /** |