aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c392
1 files changed, 303 insertions, 89 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index a25fe358..2fb87ed4 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -626,11 +626,15 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
626 fd_set *except_fd_set, 626 fd_set *except_fd_set,
627 MHD_socket *max_fd) 627 MHD_socket *max_fd)
628{ 628{
629 return MHD_get_fdset2(daemon, read_fd_set, 629 return MHD_get_fdset2 (daemon,
630 write_fd_set, except_fd_set, 630 read_fd_set,
631 max_fd, _MHD_SYS_DEFAULT_FD_SETSIZE); 631 write_fd_set,
632 except_fd_set,
633 max_fd,
634 _MHD_SYS_DEFAULT_FD_SETSIZE);
632} 635}
633 636
637
634/** 638/**
635 * Obtain the `select()` sets for this daemon. 639 * Obtain the `select()` sets for this daemon.
636 * Daemon's FDs will be added to fd_sets. To get only 640 * Daemon's FDs will be added to fd_sets. To get only
@@ -729,25 +733,25 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
729 } 733 }
730 for (urh = daemon->urh_head; NULL != urh; urh = urh->next) 734 for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
731 { 735 {
732 if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) && 736 if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
733 (! MHD_add_to_fd_set_ (urh->mhd_socket, 737 (! MHD_add_to_fd_set_ (urh->mhd.socket,
734 read_fd_set, 738 read_fd_set,
735 max_fd, 739 max_fd,
736 fd_setsize)) ) 740 fd_setsize)) )
737 result = MHD_NO; 741 result = MHD_NO;
738 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) && 742 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
739 (! MHD_add_to_fd_set_ (urh->mhd_socket, 743 (! MHD_add_to_fd_set_ (urh->mhd.socket,
740 write_fd_set, 744 write_fd_set,
741 max_fd, 745 max_fd,
742 fd_setsize)) ) 746 fd_setsize)) )
743 result = MHD_NO; 747 result = MHD_NO;
744 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) && 748 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) &&
745 (! MHD_add_to_fd_set_ (urh->connection->socket_fd, 749 (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
746 read_fd_set, 750 read_fd_set,
747 max_fd, 751 max_fd,
748 fd_setsize)) ) 752 fd_setsize)) )
749 result = MHD_NO; 753 result = MHD_NO;
750 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) && 754 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
751 (! MHD_add_to_fd_set_ (urh->connection->socket_fd, 755 (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
752 write_fd_set, 756 write_fd_set,
753 max_fd, 757 max_fd,
@@ -2175,7 +2179,7 @@ static void
2175process_urh (struct MHD_UpgradeResponseHandle *urh) 2179process_urh (struct MHD_UpgradeResponseHandle *urh)
2176{ 2180{
2177 /* handle reading from TLS client and writing to application */ 2181 /* handle reading from TLS client and writing to application */
2178 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) && 2182 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) &&
2179 (urh->in_buffer_off < urh->in_buffer_size) ) 2183 (urh->in_buffer_off < urh->in_buffer_size) )
2180 { 2184 {
2181 ssize_t res; 2185 ssize_t res;
@@ -2186,25 +2190,25 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
2186 if ( (GNUTLS_E_AGAIN == res) || 2190 if ( (GNUTLS_E_AGAIN == res) ||
2187 (GNUTLS_E_INTERRUPTED == res) ) 2191 (GNUTLS_E_INTERRUPTED == res) )
2188 { 2192 {
2189 urh->celi_client &= ~MHD_EPOLL_STATE_READ_READY; 2193 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
2190 } 2194 }
2191 else if (res > 0) 2195 else if (res > 0)
2192 { 2196 {
2193 urh->in_buffer_off += res; 2197 urh->in_buffer_off += res;
2194 } 2198 }
2195 } 2199 }
2196 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) && 2200 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
2197 (urh->in_buffer_off > 0) ) 2201 (urh->in_buffer_off > 0) )
2198 { 2202 {
2199 size_t res; 2203 size_t res;
2200 2204
2201 res = write (urh->mhd_socket, 2205 res = write (urh->mhd.socket,
2202 urh->in_buffer, 2206 urh->in_buffer,
2203 urh->in_buffer_off); 2207 urh->in_buffer_off);
2204 if (-1 == res) 2208 if (-1 == res)
2205 { 2209 {
2206 /* FIXME: differenciate by errno? */ 2210 /* FIXME: differenciate by errno? */
2207 urh->celi_mhd &= ~MHD_EPOLL_STATE_WRITE_READY; 2211 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
2208 } 2212 }
2209 else 2213 else
2210 { 2214 {
@@ -2223,25 +2227,25 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
2223 } 2227 }
2224 2228
2225 /* handle reading from application and writing to HTTPS client */ 2229 /* handle reading from application and writing to HTTPS client */
2226 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) && 2230 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
2227 (urh->out_buffer_off < urh->out_buffer_size) ) 2231 (urh->out_buffer_off < urh->out_buffer_size) )
2228 { 2232 {
2229 size_t res; 2233 size_t res;
2230 2234
2231 res = read (urh->mhd_socket, 2235 res = read (urh->mhd.socket,
2232 &urh->out_buffer[urh->out_buffer_off], 2236 &urh->out_buffer[urh->out_buffer_off],
2233 urh->out_buffer_size - urh->out_buffer_off); 2237 urh->out_buffer_size - urh->out_buffer_off);
2234 if (-1 == res) 2238 if (-1 == res)
2235 { 2239 {
2236 /* FIXME: differenciate by errno? */ 2240 /* FIXME: differenciate by errno? */
2237 urh->celi_mhd &= ~MHD_EPOLL_STATE_READ_READY; 2241 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
2238 } 2242 }
2239 else 2243 else
2240 { 2244 {
2241 urh->out_buffer_off += res; 2245 urh->out_buffer_off += res;
2242 } 2246 }
2243 } 2247 }
2244 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) && 2248 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
2245 (urh->out_buffer_off > 0) ) 2249 (urh->out_buffer_off > 0) )
2246 { 2250 {
2247 ssize_t res; 2251 ssize_t res;
@@ -2252,7 +2256,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
2252 if ( (GNUTLS_E_AGAIN == res) || 2256 if ( (GNUTLS_E_AGAIN == res) ||
2253 (GNUTLS_E_INTERRUPTED == res) ) 2257 (GNUTLS_E_INTERRUPTED == res) )
2254 { 2258 {
2255 urh->celi_client &= ~MHD_EPOLL_STATE_WRITE_READY; 2259 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
2256 } 2260 }
2257 else if (res > 0) 2261 else if (res > 0)
2258 { 2262 {
@@ -2359,13 +2363,13 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
2359 { 2363 {
2360 /* update urh state based on select() output */ 2364 /* update urh state based on select() output */
2361 if (FD_ISSET (urh->connection->socket_fd, read_fd_set)) 2365 if (FD_ISSET (urh->connection->socket_fd, read_fd_set))
2362 urh->celi_client |= MHD_EPOLL_STATE_READ_READY; 2366 urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
2363 if (FD_ISSET (urh->connection->socket_fd, write_fd_set)) 2367 if (FD_ISSET (urh->connection->socket_fd, write_fd_set))
2364 urh->celi_client |= MHD_EPOLL_STATE_WRITE_READY; 2368 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
2365 if (FD_ISSET (urh->mhd_socket, read_fd_set)) 2369 if (FD_ISSET (urh->mhd.socket, read_fd_set))
2366 urh->celi_mhd |= MHD_EPOLL_STATE_READ_READY; 2370 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
2367 if (FD_ISSET (urh->mhd_socket, write_fd_set)) 2371 if (FD_ISSET (urh->mhd.socket, write_fd_set))
2368 urh->celi_mhd |= MHD_EPOLL_STATE_WRITE_READY; 2372 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
2369 /* call generic forwarding function for passing data */ 2373 /* call generic forwarding function for passing data */
2370 process_urh (urh); 2374 process_urh (urh);
2371 } 2375 }
@@ -2632,15 +2636,15 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2632 for (urh = daemon->urh_head; NULL != urh; urh = urh->next) 2636 for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
2633 { 2637 {
2634 p[poll_server+i].fd = urh->connection->socket_fd; 2638 p[poll_server+i].fd = urh->connection->socket_fd;
2635 if (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) 2639 if (0 == (MHD_EPOLL_STATE_READ_READY & urh->app.celi))
2636 p[poll_server+i].events |= POLLIN; 2640 p[poll_server+i].events |= POLLIN;
2637 if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) 2641 if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi))
2638 p[poll_server+i].events |= POLLOUT; 2642 p[poll_server+i].events |= POLLOUT;
2639 i++; 2643 i++;
2640 p[poll_server+i].fd = urh->mhd_socket; 2644 p[poll_server+i].fd = urh->mhd.socket;
2641 if (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) 2645 if (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi))
2642 p[poll_server+i].events |= POLLIN; 2646 p[poll_server+i].events |= POLLIN;
2643 if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) 2647 if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi))
2644 p[poll_server+i].events |= POLLOUT; 2648 p[poll_server+i].events |= POLLOUT;
2645 i++; 2649 i++;
2646 } 2650 }
@@ -2701,11 +2705,11 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2701 if (p[poll_server+i].fd != urh->connection->socket_fd) 2705 if (p[poll_server+i].fd != urh->connection->socket_fd)
2702 continue; /* fd mismatch, something else happened, retry later ... */ 2706 continue; /* fd mismatch, something else happened, retry later ... */
2703 if (0 != (p[poll_server+i].revents & POLLIN)) 2707 if (0 != (p[poll_server+i].revents & POLLIN))
2704 urh->celi_client |= MHD_EPOLL_STATE_READ_READY; 2708 urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
2705 if (0 != (p[poll_server+i].revents & POLLOUT)) 2709 if (0 != (p[poll_server+i].revents & POLLOUT))
2706 urh->celi_client |= MHD_EPOLL_STATE_WRITE_READY; 2710 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
2707 i++; 2711 i++;
2708 if (p[poll_server+i].fd != urh->mhd_socket) 2712 if (p[poll_server+i].fd != urh->mhd.socket)
2709 { 2713 {
2710 /* fd mismatch, something else happened, retry later ... */ 2714 /* fd mismatch, something else happened, retry later ... */
2711 /* may still be able to do something based on updates 2715 /* may still be able to do something based on updates
@@ -2714,9 +2718,9 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2714 continue; 2718 continue;
2715 } 2719 }
2716 if (0 != (p[poll_server+i].revents & POLLIN)) 2720 if (0 != (p[poll_server+i].revents & POLLIN))
2717 urh->celi_mhd |= MHD_EPOLL_STATE_READ_READY; 2721 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
2718 if (0 != (p[poll_server+i].revents & POLLOUT)) 2722 if (0 != (p[poll_server+i].revents & POLLOUT))
2719 urh->celi_mhd |= MHD_EPOLL_STATE_WRITE_READY; 2723 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
2720 i++; 2724 i++;
2721 process_urh (urh); 2725 process_urh (urh);
2722 } 2726 }
@@ -2832,6 +2836,136 @@ MHD_poll (struct MHD_Daemon *daemon,
2832#define MAX_EVENTS 128 2836#define MAX_EVENTS 128
2833 2837
2834 2838
2839#if HTTPS_SUPPORT
2840
2841/**
2842 * Do epoll()-based processing for TLS connections that have been
2843 * upgraded. This requires a separate epoll() invocation as we
2844 * cannot use the `struct MHD_Connection` data structures for
2845 * the `union epoll_data` in this case.
2846 */
2847static int
2848run_epoll_for_upgrade (struct MHD_Daemon *daemon)
2849{
2850 struct epoll_event events[MAX_EVENTS];
2851 int num_events;
2852 unsigned int i;
2853
2854 num_events = MAX_EVENTS;
2855 while (MAX_EVENTS == num_events)
2856 {
2857 /* update event masks */
2858 num_events = epoll_wait (daemon->epoll_upgrade_fd,
2859 events,
2860 MAX_EVENTS,
2861 0);
2862 if (-1 == num_events)
2863 {
2864 const int err = MHD_socket_get_error_ ();
2865 if (MHD_SCKT_ERR_IS_EINTR_ (err))
2866 return MHD_YES;
2867#ifdef HAVE_MESSAGES
2868 MHD_DLOG (daemon,
2869 "Call to epoll_wait failed: %s\n",
2870 MHD_socket_strerr_ (err));
2871#endif
2872 return MHD_NO;
2873 }
2874 for (i=0;i<(unsigned int) num_events;i++)
2875 {
2876 struct UpgradeEpollHandle *ueh = events[i].data.ptr;
2877 struct MHD_UpgradeResponseHandle *urh = ueh->urh;
2878 struct epoll_event event;
2879 int fd;
2880
2881 /* Update our state based on what is ready according to epoll() */
2882 if (0 != (events[i].events & EPOLLIN))
2883 ueh->celi |= MHD_EPOLL_STATE_READ_READY;
2884 if (0 != (events[i].events & EPOLLOUT))
2885 ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
2886
2887 /* shuffle data based on buffers and FD readyness */
2888 process_urh (urh);
2889
2890 /* if we drained the IO buffer, re-add to epoll() to wait for more! */
2891 if (0 == (ueh->celi & MHD_EPOLL_STATE_READ_READY))
2892 {
2893 event.events = EPOLLIN;
2894 event.data.ptr = ueh;
2895 fd = (ueh == &urh->mhd) ? ueh->socket : urh->connection->socket_fd;
2896 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
2897 EPOLL_CTL_ADD,
2898 fd,
2899 &event))
2900 {
2901 MHD_socket myfd;
2902
2903 /* Handle error by closing OUR socket; with some
2904 luck, this should tricker the application to fail
2905 to read, and then the application should close
2906 the connection completely. */
2907
2908 /* epoll documentation suggests that closing a FD
2909 automatically removes it from the epoll set;
2910 however, this is not true as if we fail to do
2911 manually remove it, we are still seeing an event
2912 for this fd in epoll, causing grief
2913 (use-after-free...) --- at least on my system. */
2914 myfd = urh->mhd.socket;
2915 if ( (fd != myfd) &&
2916 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
2917 EPOLL_CTL_DEL,
2918 urh->mhd.socket,
2919 NULL)) )
2920 MHD_PANIC ("Failed to remove FD from epoll set\n");
2921 urh->mhd.socket = MHD_INVALID_SOCKET;
2922 MHD_socket_close_ (myfd);
2923 continue;
2924 }
2925 }
2926 if (0 == (ueh->celi & MHD_EPOLL_STATE_WRITE_READY))
2927 {
2928 event.events = EPOLLOUT;
2929 event.data.ptr = ueh;
2930 fd = (ueh == &ueh->urh->mhd) ? ueh->socket : ueh->urh->connection->socket_fd;
2931 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
2932 EPOLL_CTL_ADD,
2933 fd,
2934 &event))
2935 {
2936 MHD_socket myfd;
2937
2938 /* Handle error by closing OUR socket; with some
2939 luck, this should tricker the application to fail
2940 to read, and then the application should close
2941 the connection completely. */
2942
2943 /* epoll documentation suggests that closing a FD
2944 automatically removes it from the epoll set;
2945 however, this is not true as if we fail to do
2946 manually remove it, we are still seeing an event
2947 for this fd in epoll, causing grief
2948 (use-after-free...) --- at least on my system. */
2949 myfd = urh->mhd.socket;
2950 if ( (fd != myfd) &&
2951 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
2952 EPOLL_CTL_DEL,
2953 urh->mhd.socket,
2954 NULL)) )
2955 MHD_PANIC ("Failed to remove FD from epoll set\n");
2956
2957 urh->mhd.socket = MHD_INVALID_SOCKET;
2958 MHD_socket_close_ (myfd);
2959 continue;
2960 }
2961 }
2962 }
2963 }
2964 return MHD_YES;
2965}
2966#endif
2967
2968
2835/** 2969/**
2836 * Do epoll()-based processing (this function is allowed to 2970 * Do epoll()-based processing (this function is allowed to
2837 * block if @a may_block is set to #MHD_YES). 2971 * block if @a may_block is set to #MHD_YES).
@@ -2844,6 +2978,9 @@ static int
2844MHD_epoll (struct MHD_Daemon *daemon, 2978MHD_epoll (struct MHD_Daemon *daemon,
2845 int may_block) 2979 int may_block)
2846{ 2980{
2981#if HTTPS_SUPPORT
2982 static const char *upgrade_marker = "upgrade_ptr";
2983#endif
2847 struct MHD_Connection *pos; 2984 struct MHD_Connection *pos;
2848 struct MHD_Connection *next; 2985 struct MHD_Connection *next;
2849 struct epoll_event events[MAX_EVENTS]; 2986 struct epoll_event events[MAX_EVENTS];
@@ -2879,6 +3016,27 @@ MHD_epoll (struct MHD_Daemon *daemon,
2879 } 3016 }
2880 daemon->listen_socket_in_epoll = MHD_YES; 3017 daemon->listen_socket_in_epoll = MHD_YES;
2881 } 3018 }
3019#if HTTPS_SUPPORT
3020 if ( (MHD_NO == daemon->upgrade_fd_in_epoll) &&
3021 (MHD_INVALID_SOCKET != daemon->epoll_upgrade_fd) )
3022 {
3023 event.events = EPOLLIN | EPOLLOUT;
3024 event.data.ptr = (void *) upgrade_marker;
3025 if (0 != epoll_ctl (daemon->epoll_fd,
3026 EPOLL_CTL_ADD,
3027 daemon->epoll_upgrade_fd,
3028 &event))
3029 {
3030#ifdef HAVE_MESSAGES
3031 MHD_DLOG (daemon,
3032 "Call to epoll_ctl failed: %s\n",
3033 MHD_socket_last_strerr_ ());
3034#endif
3035 return MHD_NO;
3036 }
3037 daemon->upgrade_fd_in_epoll = MHD_YES;
3038 }
3039#endif
2882 if ( ( (MHD_YES == daemon->listen_socket_in_epoll) && 3040 if ( ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2883 (daemon->connections == daemon->connection_limit) ) || 3041 (daemon->connections == daemon->connection_limit) ) ||
2884 (MHD_YES == daemon->at_limit) ) 3042 (MHD_YES == daemon->at_limit) )
@@ -2917,7 +3075,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
2917 { 3075 {
2918 /* update event masks */ 3076 /* update event masks */
2919 num_events = epoll_wait (daemon->epoll_fd, 3077 num_events = epoll_wait (daemon->epoll_fd,
2920 events, MAX_EVENTS, timeout_ms); 3078 events,
3079 MAX_EVENTS,
3080 timeout_ms);
2921 if (-1 == num_events) 3081 if (-1 == num_events)
2922 { 3082 {
2923 const int err = MHD_socket_get_error_ (); 3083 const int err = MHD_socket_get_error_ ();
@@ -2932,8 +3092,25 @@ MHD_epoll (struct MHD_Daemon *daemon,
2932 } 3092 }
2933 for (i=0;i<(unsigned int) num_events;i++) 3093 for (i=0;i<(unsigned int) num_events;i++)
2934 { 3094 {
3095 /* First, check for the values of `ptr` that would indicate
3096 that this event is not about a normal connection. */
2935 if (NULL == events[i].data.ptr) 3097 if (NULL == events[i].data.ptr)
2936 continue; /* shutdown signal! */ 3098 continue; /* shutdown signal! */
3099#if HTTPS_SUPPORT
3100 if (upgrade_marker == events[i].data.ptr)
3101 {
3102 /* activity on an upgraded connection, we process
3103 those in a separate epoll() */
3104 daemon->upgrade_fd_in_epoll = MHD_NO;
3105 run_epoll_for_upgrade (daemon);
3106 continue;
3107 }
3108#endif
3109 /* UGH: we're storing pointers and fds in the same union
3110 here; incredibly ugly and somewhat risky, even though a
3111 pointer with the same numeric value as the wpipe[0] can
3112 be expected to be rare... FIXME (a construction similar
3113 to what we did with the `upgrade_marker` should do) */
2937 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && 3114 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2938 (daemon->wpipe[0] == events[i].data.fd) ) 3115 (daemon->wpipe[0] == events[i].data.fd) )
2939 { 3116 {
@@ -2942,39 +3119,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
2942 MHD_pipe_drain_ (daemon->wpipe[0]); 3119 MHD_pipe_drain_ (daemon->wpipe[0]);
2943 continue; 3120 continue;
2944 } 3121 }
2945 if (daemon != events[i].data.ptr) 3122 if (daemon == events[i].data.ptr)
2946 {
2947 /* this is an event relating to a 'normal' connection,
2948 remember the event and if appropriate mark the
2949 connection as 'eready'. */
2950 pos = events[i].data.ptr;
2951 if (0 != (events[i].events & EPOLLIN))
2952 {
2953 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
2954 if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
2955 (pos->read_buffer_size > pos->read_buffer_offset) ) &&
2956 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2957 {
2958 EDLL_insert (daemon->eready_head,
2959 daemon->eready_tail,
2960 pos);
2961 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2962 }
2963 }
2964 if (0 != (events[i].events & EPOLLOUT))
2965 {
2966 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
2967 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
2968 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2969 {
2970 EDLL_insert (daemon->eready_head,
2971 daemon->eready_tail,
2972 pos);
2973 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2974 }
2975 }
2976 }
2977 else /* must be listen socket */
2978 { 3123 {
2979 /* run 'accept' until it fails or we are not allowed to take 3124 /* run 'accept' until it fails or we are not allowed to take
2980 on more connections */ 3125 on more connections */
@@ -2984,8 +3129,39 @@ MHD_epoll (struct MHD_Daemon *daemon,
2984 (series_length < 128) && 3129 (series_length < 128) &&
2985 (MHD_NO == daemon->at_limit) ) 3130 (MHD_NO == daemon->at_limit) )
2986 series_length++; 3131 series_length++;
3132 continue;
2987 } 3133 }
2988 } 3134 /* this is an event relating to a 'normal' connection,
3135 remember the event and if appropriate mark the
3136 connection as 'eready'. */
3137 pos = events[i].data.ptr;
3138 /* normal processing: update read/write data */
3139 if (0 != (events[i].events & EPOLLIN))
3140 {
3141 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
3142 if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
3143 (pos->read_buffer_size > pos->read_buffer_offset) ) &&
3144 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
3145 {
3146 EDLL_insert (daemon->eready_head,
3147 daemon->eready_tail,
3148 pos);
3149 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
3150 }
3151 }
3152 if (0 != (events[i].events & EPOLLOUT))
3153 {
3154 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
3155 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
3156 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
3157 {
3158 EDLL_insert (daemon->eready_head,
3159 daemon->eready_tail,
3160 pos);
3161 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
3162 }
3163 }
3164 }
2989 } 3165 }
2990 3166
2991 /* we handle resumes here because we may have ready connections 3167 /* we handle resumes here because we may have ready connections
@@ -3426,8 +3602,8 @@ parse_options_va (struct MHD_Daemon *daemon,
3426 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0) 3602 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
3427 { 3603 {
3428#ifdef HAVE_MESSAGES 3604#ifdef HAVE_MESSAGES
3429 MHD_DLOG(daemon, 3605 MHD_DLOG (daemon,
3430 "Error initializing DH parameters\n"); 3606 "Error initializing DH parameters\n");
3431#endif 3607#endif
3432 return MHD_NO; 3608 return MHD_NO;
3433 } 3609 }
@@ -3437,8 +3613,8 @@ parse_options_va (struct MHD_Daemon *daemon,
3437 GNUTLS_X509_FMT_PEM) < 0) 3613 GNUTLS_X509_FMT_PEM) < 0)
3438 { 3614 {
3439#ifdef HAVE_MESSAGES 3615#ifdef HAVE_MESSAGES
3440 MHD_DLOG(daemon, 3616 MHD_DLOG (daemon,
3441 "Bad Diffie-Hellman parameters format\n"); 3617 "Bad Diffie-Hellman parameters format\n");
3442#endif 3618#endif
3443 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 3619 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
3444 return MHD_NO; 3620 return MHD_NO;
@@ -3652,34 +3828,27 @@ parse_options_va (struct MHD_Daemon *daemon,
3652 3828
3653 3829
3654#ifdef EPOLL_SUPPORT 3830#ifdef EPOLL_SUPPORT
3655/**
3656 * Setup epoll() FD for the daemon and initialize it to listen
3657 * on the listen FD.
3658 *
3659 * @param daemon daemon to initialize for epoll()
3660 * @return #MHD_YES on success, #MHD_NO on failure
3661 */
3662static int 3831static int
3663setup_epoll_to_listen (struct MHD_Daemon *daemon) 3832setup_epoll_fd (struct MHD_Daemon *daemon)
3664{ 3833{
3665 struct epoll_event event; 3834 int fd;
3666 3835
3667#ifdef USE_EPOLL_CREATE1 3836#ifdef USE_EPOLL_CREATE1
3668 daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC); 3837 fd = epoll_create1 (EPOLL_CLOEXEC);
3669#else /* ! USE_EPOLL_CREATE1 */ 3838#else /* ! USE_EPOLL_CREATE1 */
3670 daemon->epoll_fd = epoll_create (MAX_EVENTS); 3839 fd = epoll_create (MAX_EVENTS);
3671#endif /* ! USE_EPOLL_CREATE1 */ 3840#endif /* ! USE_EPOLL_CREATE1 */
3672 if (-1 == daemon->epoll_fd) 3841 if (MHD_INVALID_SOCKET == fd)
3673 { 3842 {
3674#ifdef HAVE_MESSAGES 3843#ifdef HAVE_MESSAGES
3675 MHD_DLOG (daemon, 3844 MHD_DLOG (daemon,
3676 "Call to epoll_create1 failed: %s\n", 3845 "Call to epoll_create1 failed: %s\n",
3677 MHD_socket_last_strerr_ ()); 3846 MHD_socket_last_strerr_ ());
3678#endif 3847#endif
3679 return MHD_NO; 3848 return MHD_INVALID_SOCKET;
3680 } 3849 }
3681#if !defined(USE_EPOLL_CREATE1) 3850#if !defined(USE_EPOLL_CREATE1)
3682 if (!MHD_socket_noninheritable_ (daemon->epoll_fd)) 3851 if (! MHD_socket_noninheritable_ (fd))
3683 { 3852 {
3684#ifdef HAVE_MESSAGES 3853#ifdef HAVE_MESSAGES
3685 MHD_DLOG (daemon, 3854 MHD_DLOG (daemon,
@@ -3687,6 +3856,33 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3687#endif 3856#endif
3688 } 3857 }
3689#endif /* ! USE_EPOLL_CREATE1 */ 3858#endif /* ! USE_EPOLL_CREATE1 */
3859 return fd;
3860}
3861
3862
3863/**
3864 * Setup epoll() FD for the daemon and initialize it to listen
3865 * on the listen FD.
3866 *
3867 * @param daemon daemon to initialize for epoll()
3868 * @return #MHD_YES on success, #MHD_NO on failure
3869 */
3870static int
3871setup_epoll_to_listen (struct MHD_Daemon *daemon)
3872{
3873 struct epoll_event event;
3874
3875 daemon->epoll_fd = setup_epoll_fd (daemon);
3876 if (MHD_INVALID_SOCKET == daemon->epoll_fd)
3877 return MHD_NO;
3878#if HTTPS_SUPPORT
3879 if (MHD_USE_TLS_EPOLL_UPGRADE == (MHD_USE_TLS_EPOLL_UPGRADE & daemon->options))
3880 {
3881 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
3882 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
3883 return MHD_NO;
3884 }
3885#endif
3690 if (MHD_INVALID_SOCKET == daemon->socket_fd) 3886 if (MHD_INVALID_SOCKET == daemon->socket_fd)
3691 return MHD_YES; /* non-listening daemon */ 3887 return MHD_YES; /* non-listening daemon */
3692 event.events = EPOLLIN; 3888 event.events = EPOLLIN;
@@ -3788,6 +3984,9 @@ MHD_start_daemon_va (unsigned int flags,
3788 memset (daemon, 0, sizeof (struct MHD_Daemon)); 3984 memset (daemon, 0, sizeof (struct MHD_Daemon));
3789#ifdef EPOLL_SUPPORT 3985#ifdef EPOLL_SUPPORT
3790 daemon->epoll_fd = -1; 3986 daemon->epoll_fd = -1;
3987#if HTTPS_SUPPORT
3988 daemon->epoll_upgrade_fd = -1;
3989#endif
3791#endif 3990#endif
3792 /* try to open listen socket */ 3991 /* try to open listen socket */
3793#if HTTPS_SUPPORT 3992#if HTTPS_SUPPORT
@@ -3842,7 +4041,7 @@ MHD_start_daemon_va (unsigned int flags,
3842 free (daemon); 4041 free (daemon);
3843 return NULL; 4042 return NULL;
3844 } 4043 }
3845 if (!MHD_itc_nonblocking_(daemon->wpipe[0])) 4044 if (! MHD_itc_nonblocking_(daemon->wpipe[0]))
3846 { 4045 {
3847#ifdef HAVE_MESSAGES 4046#ifdef HAVE_MESSAGES
3848 MHD_DLOG (daemon, 4047 MHD_DLOG (daemon,
@@ -4482,6 +4681,10 @@ thread_failed:
4482#ifdef EPOLL_SUPPORT 4681#ifdef EPOLL_SUPPORT
4483 if (-1 != daemon->epoll_fd) 4682 if (-1 != daemon->epoll_fd)
4484 close (daemon->epoll_fd); 4683 close (daemon->epoll_fd);
4684#if HTTPS_SUPPORT
4685 if (-1 != daemon->epoll_upgrade_fd)
4686 close (daemon->epoll_upgrade_fd);
4687#endif
4485#endif 4688#endif
4486#ifdef DAUTH_SUPPORT 4689#ifdef DAUTH_SUPPORT
4487 free (daemon->nnc); 4690 free (daemon->nnc);
@@ -4710,6 +4913,11 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
4710 if ( (-1 != daemon->worker_pool[i].epoll_fd) && 4913 if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
4711 (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) ) 4914 (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) )
4712 MHD_PANIC ("close failed\n"); 4915 MHD_PANIC ("close failed\n");
4916#if HTTPS_SUPPORT
4917 if ( (-1 != daemon->worker_pool[i].epoll_upgrade_fd) &&
4918 (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_upgrade_fd)) )
4919 MHD_PANIC ("close failed\n");
4920#endif
4713#endif 4921#endif
4714 /* Individual pipes are always used */ 4922 /* Individual pipes are always used */
4715 if (1) 4923 if (1)
@@ -4762,6 +4970,12 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
4762 (-1 != daemon->epoll_fd) && 4970 (-1 != daemon->epoll_fd) &&
4763 (0 != MHD_socket_close_ (daemon->epoll_fd)) ) 4971 (0 != MHD_socket_close_ (daemon->epoll_fd)) )
4764 MHD_PANIC ("close failed\n"); 4972 MHD_PANIC ("close failed\n");
4973#if HTTPS_SUPPORT
4974 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4975 (-1 != daemon->epoll_upgrade_fd) &&
4976 (0 != MHD_socket_close_ (daemon->epoll_upgrade_fd)) )
4977 MHD_PANIC ("close failed\n");
4978#endif
4765#endif 4979#endif
4766 4980
4767#ifdef DAUTH_SUPPORT 4981#ifdef DAUTH_SUPPORT