diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 62cd3ce8..08709c80 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -883,6 +883,61 @@ call_handlers (struct MHD_Connection *con, | |||
883 | 883 | ||
884 | #if HTTPS_SUPPORT | 884 | #if HTTPS_SUPPORT |
885 | /** | 885 | /** |
886 | * This function finishes the process of closing the | ||
887 | * connection associated with the @a urh. It should | ||
888 | * be called if the `was_closed` flag is set and the | ||
889 | * buffer has been drained. | ||
890 | * | ||
891 | * @param urh handle to the upgraded response we are finished with | ||
892 | */ | ||
893 | static void | ||
894 | finish_upgrade_close (struct MHD_UpgradeResponseHandle *urh) | ||
895 | { | ||
896 | struct MHD_Connection *connection = urh->connection; | ||
897 | struct MHD_Daemon *daemon = connection->daemon; | ||
898 | |||
899 | DLL_remove (daemon->urh_head, | ||
900 | daemon->urh_tail, | ||
901 | urh); | ||
902 | if (0 != (daemon->options & MHD_USE_EPOLL)) | ||
903 | { | ||
904 | /* epoll documentation suggests that closing a FD | ||
905 | automatically removes it from the epoll set; however, | ||
906 | this is not true as if we fail to do manually remove it, | ||
907 | we are still seeing an event for this fd in epoll, | ||
908 | causing grief (use-after-free...) --- at least on my | ||
909 | system. */ | ||
910 | if (0 != epoll_ctl (daemon->epoll_upgrade_fd, | ||
911 | EPOLL_CTL_DEL, | ||
912 | connection->socket_fd, | ||
913 | NULL)) | ||
914 | MHD_PANIC ("Failed to remove FD from epoll set\n"); | ||
915 | } | ||
916 | if (MHD_INVALID_SOCKET != urh->mhd.socket) | ||
917 | { | ||
918 | /* epoll documentation suggests that closing a FD | ||
919 | automatically removes it from the epoll set; however, | ||
920 | this is not true as if we fail to do manually remove it, | ||
921 | we are still seeing an event for this fd in epoll, | ||
922 | causing grief (use-after-free...) --- at least on my | ||
923 | system. */ | ||
924 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | ||
925 | (0 != epoll_ctl (daemon->epoll_upgrade_fd, | ||
926 | EPOLL_CTL_DEL, | ||
927 | urh->mhd.socket, | ||
928 | NULL)) ) | ||
929 | MHD_PANIC ("Failed to remove FD from epoll set\n"); | ||
930 | if (0 != MHD_socket_close_ (urh->mhd.socket)) | ||
931 | MHD_PANIC ("close failed\n"); | ||
932 | } | ||
933 | MHD_resume_connection (connection); | ||
934 | MHD_connection_close_ (connection, | ||
935 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | ||
936 | free (urh); | ||
937 | } | ||
938 | |||
939 | |||
940 | /** | ||
886 | * Performs bi-directional forwarding on upgraded HTTPS connections | 941 | * Performs bi-directional forwarding on upgraded HTTPS connections |
887 | * based on the readyness state stored in the @a urh handle. | 942 | * based on the readyness state stored in the @a urh handle. |
888 | * | 943 | * |
@@ -891,6 +946,8 @@ call_handlers (struct MHD_Connection *con, | |||
891 | static void | 946 | static void |
892 | process_urh (struct MHD_UpgradeResponseHandle *urh) | 947 | process_urh (struct MHD_UpgradeResponseHandle *urh) |
893 | { | 948 | { |
949 | int fin_read; | ||
950 | |||
894 | /* handle reading from TLS client and writing to application */ | 951 | /* handle reading from TLS client and writing to application */ |
895 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) && | 952 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) && |
896 | (urh->in_buffer_off < urh->in_buffer_size) ) | 953 | (urh->in_buffer_off < urh->in_buffer_size) ) |
@@ -957,7 +1014,10 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
957 | { | 1014 | { |
958 | urh->out_buffer_off += res; | 1015 | urh->out_buffer_off += res; |
959 | } | 1016 | } |
1017 | fin_read = (0 == res); | ||
960 | } | 1018 | } |
1019 | else | ||
1020 | fin_read = 0; | ||
961 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && | 1021 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && |
962 | (urh->out_buffer_off > 0) ) | 1022 | (urh->out_buffer_off > 0) ) |
963 | { | 1023 | { |
@@ -986,6 +1046,10 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
986 | } | 1046 | } |
987 | } | 1047 | } |
988 | } | 1048 | } |
1049 | if ( (fin_read) && | ||
1050 | (0 == urh->out_buffer_off) && | ||
1051 | (MHD_YES == urh->was_closed) ) | ||
1052 | finish_upgrade_close (urh); | ||
989 | } | 1053 | } |
990 | #endif | 1054 | #endif |
991 | 1055 | ||