diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index bc26b53f..a8997d87 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -775,6 +775,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
775 | struct MHD_Connection *pos; | 775 | struct MHD_Connection *pos; |
776 | struct MHD_Connection *posn; | 776 | struct MHD_Connection *posn; |
777 | int result = MHD_YES; | 777 | int result = MHD_YES; |
778 | MHD_socket ls; | ||
778 | 779 | ||
779 | if ( (NULL == daemon) || | 780 | if ( (NULL == daemon) || |
780 | (NULL == read_fd_set) || | 781 | (NULL == read_fd_set) || |
@@ -795,8 +796,9 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
795 | fd_setsize) ? MHD_YES : MHD_NO; | 796 | fd_setsize) ? MHD_YES : MHD_NO; |
796 | } | 797 | } |
797 | #endif | 798 | #endif |
798 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | 799 | ls = daemon->socket_fd; |
799 | (! MHD_add_to_fd_set_ (daemon->socket_fd, | 800 | if ( (MHD_INVALID_SOCKET != ls) && |
801 | (! MHD_add_to_fd_set_ (ls, | ||
800 | read_fd_set, | 802 | read_fd_set, |
801 | max_fd, | 803 | max_fd, |
802 | fd_setsize)) ) | 804 | fd_setsize)) ) |
@@ -2222,6 +2224,7 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2222 | gnutls_certificate_server_set_request (connection->tls_session, | 2224 | gnutls_certificate_server_set_request (connection->tls_session, |
2223 | GNUTLS_CERT_REQUEST); | 2225 | GNUTLS_CERT_REQUEST); |
2224 | #else /* ! HTTPS_SUPPORT */ | 2226 | #else /* ! HTTPS_SUPPORT */ |
2227 | eno = EINVAL; | ||
2225 | goto cleanup; | 2228 | goto cleanup; |
2226 | #endif /* ! HTTPS_SUPPORT */ | 2229 | #endif /* ! HTTPS_SUPPORT */ |
2227 | } | 2230 | } |
@@ -2688,7 +2691,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
2688 | /* This could be a common occurance with multiple worker threads */ | 2691 | /* This could be a common occurance with multiple worker threads */ |
2689 | if ( (MHD_SCKT_ERR_IS_ (err, | 2692 | if ( (MHD_SCKT_ERR_IS_ (err, |
2690 | MHD_SCKT_EINVAL_)) && | 2693 | MHD_SCKT_EINVAL_)) && |
2691 | (MHD_INVALID_SOCKET == daemon->socket_fd) ) | 2694 | (MHD_INVALID_SOCKET == fd) ) |
2692 | return MHD_NO; /* can happen during shutdown */ | 2695 | return MHD_NO; /* can happen during shutdown */ |
2693 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) | 2696 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) |
2694 | return MHD_NO; /* do not print error if client just disconnected early */ | 2697 | return MHD_NO; /* do not print error if client just disconnected early */ |
@@ -3105,6 +3108,7 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3105 | struct timeval *tv; | 3108 | struct timeval *tv; |
3106 | MHD_UNSIGNED_LONG_LONG ltimeout; | 3109 | MHD_UNSIGNED_LONG_LONG ltimeout; |
3107 | int err_state; | 3110 | int err_state; |
3111 | MHD_socket ls; | ||
3108 | 3112 | ||
3109 | timeout.tv_sec = 0; | 3113 | timeout.tv_sec = 0; |
3110 | timeout.tv_usec = 0; | 3114 | timeout.tv_usec = 0; |
@@ -3140,8 +3144,8 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3140 | else | 3144 | else |
3141 | { | 3145 | { |
3142 | /* accept only, have one thread per connection */ | 3146 | /* accept only, have one thread per connection */ |
3143 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | 3147 | if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) && |
3144 | (! MHD_add_to_fd_set_ (daemon->socket_fd, | 3148 | (! MHD_add_to_fd_set_ (ls, |
3145 | &rs, | 3149 | &rs, |
3146 | &maxsock, | 3150 | &maxsock, |
3147 | FD_SETSIZE)) ) | 3151 | FD_SETSIZE)) ) |
@@ -3163,9 +3167,9 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3163 | /* fdset limit reached, new connections | 3167 | /* fdset limit reached, new connections |
3164 | cannot be handled. Remove listen socket FD | 3168 | cannot be handled. Remove listen socket FD |
3165 | from fdset and retry to add ITC FD. */ | 3169 | from fdset and retry to add ITC FD. */ |
3166 | if (MHD_INVALID_SOCKET != daemon->socket_fd) | 3170 | if (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) |
3167 | { | 3171 | { |
3168 | FD_CLR (daemon->socket_fd, | 3172 | FD_CLR (ls, |
3169 | &rs); | 3173 | &rs); |
3170 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc), | 3174 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc), |
3171 | &rs, | 3175 | &rs, |
@@ -3189,13 +3193,13 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3189 | the shutdown OR the termination of an existing connection; so | 3193 | the shutdown OR the termination of an existing connection; so |
3190 | only do this optimization if we have a signaling ITC in | 3194 | only do this optimization if we have a signaling ITC in |
3191 | place. */ | 3195 | place. */ |
3192 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | 3196 | if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) && |
3193 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 3197 | (MHD_ITC_IS_VALID_(daemon->itc)) && |
3194 | (0 != (daemon->options & MHD_USE_ITC)) && | 3198 | (0 != (daemon->options & MHD_USE_ITC)) && |
3195 | ( (daemon->connections == daemon->connection_limit) || | 3199 | ( (daemon->connections == daemon->connection_limit) || |
3196 | (daemon->at_limit) ) ) | 3200 | (daemon->at_limit) ) ) |
3197 | { | 3201 | { |
3198 | FD_CLR (daemon->socket_fd, | 3202 | FD_CLR (ls, |
3199 | &rs); | 3203 | &rs); |
3200 | } | 3204 | } |
3201 | tv = NULL; | 3205 | tv = NULL; |
@@ -3287,6 +3291,7 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
3287 | int poll_listen; | 3291 | int poll_listen; |
3288 | int poll_itc_idx; | 3292 | int poll_itc_idx; |
3289 | struct pollfd *p; | 3293 | struct pollfd *p; |
3294 | MHD_socket ls; | ||
3290 | 3295 | ||
3291 | p = MHD_calloc_ ((2 + num_connections), sizeof (struct pollfd)); | 3296 | p = MHD_calloc_ ((2 + num_connections), sizeof (struct pollfd)); |
3292 | if (NULL == p) | 3297 | if (NULL == p) |
@@ -3300,12 +3305,12 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
3300 | } | 3305 | } |
3301 | poll_server = 0; | 3306 | poll_server = 0; |
3302 | poll_listen = -1; | 3307 | poll_listen = -1; |
3303 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | 3308 | if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) && |
3304 | (daemon->connections < daemon->connection_limit) && | 3309 | (daemon->connections < daemon->connection_limit) && |
3305 | (! daemon->at_limit) ) | 3310 | (! daemon->at_limit) ) |
3306 | { | 3311 | { |
3307 | /* only listen if we are not at the connection limit */ | 3312 | /* only listen if we are not at the connection limit */ |
3308 | p[poll_server].fd = daemon->socket_fd; | 3313 | p[poll_server].fd = ls; |
3309 | p[poll_server].events = POLLIN; | 3314 | p[poll_server].events = POLLIN; |
3310 | p[poll_server].revents = 0; | 3315 | p[poll_server].revents = 0; |
3311 | poll_listen = (int) poll_server; | 3316 | poll_listen = (int) poll_server; |
@@ -3503,6 +3508,7 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon, | |||
3503 | unsigned int poll_count; | 3508 | unsigned int poll_count; |
3504 | int poll_listen; | 3509 | int poll_listen; |
3505 | int poll_itc_idx; | 3510 | int poll_itc_idx; |
3511 | MHD_socket ls; | ||
3506 | 3512 | ||
3507 | memset (&p, | 3513 | memset (&p, |
3508 | 0, | 3514 | 0, |
@@ -3510,9 +3516,9 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon, | |||
3510 | poll_count = 0; | 3516 | poll_count = 0; |
3511 | poll_listen = -1; | 3517 | poll_listen = -1; |
3512 | poll_itc_idx = -1; | 3518 | poll_itc_idx = -1; |
3513 | if (MHD_INVALID_SOCKET != daemon->socket_fd) | 3519 | if (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) |
3514 | { | 3520 | { |
3515 | p[poll_count].fd = daemon->socket_fd; | 3521 | p[poll_count].fd = ls; |
3516 | p[poll_count].events = POLLIN; | 3522 | p[poll_count].events = POLLIN; |
3517 | p[poll_count].revents = 0; | 3523 | p[poll_count].revents = 0; |
3518 | poll_listen = poll_count; | 3524 | poll_listen = poll_count; |
@@ -3701,6 +3707,7 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
3701 | MHD_UNSIGNED_LONG_LONG timeout_ll; | 3707 | MHD_UNSIGNED_LONG_LONG timeout_ll; |
3702 | int num_events; | 3708 | int num_events; |
3703 | unsigned int i; | 3709 | unsigned int i; |
3710 | MHD_socket ls; | ||
3704 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 3711 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
3705 | int run_upgraded = MHD_NO; | 3712 | int run_upgraded = MHD_NO; |
3706 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 3713 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
@@ -3709,7 +3716,7 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
3709 | return MHD_NO; /* we're down! */ | 3716 | return MHD_NO; /* we're down! */ |
3710 | if (daemon->shutdown) | 3717 | if (daemon->shutdown) |
3711 | return MHD_NO; | 3718 | return MHD_NO; |
3712 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | 3719 | if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) && |
3713 | (daemon->connections < daemon->connection_limit) && | 3720 | (daemon->connections < daemon->connection_limit) && |
3714 | (MHD_NO == daemon->listen_socket_in_epoll) && | 3721 | (MHD_NO == daemon->listen_socket_in_epoll) && |
3715 | (! daemon->at_limit) ) | 3722 | (! daemon->at_limit) ) |
@@ -3718,7 +3725,7 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
3718 | event.data.ptr = daemon; | 3725 | event.data.ptr = daemon; |
3719 | if (0 != epoll_ctl (daemon->epoll_fd, | 3726 | if (0 != epoll_ctl (daemon->epoll_fd, |
3720 | EPOLL_CTL_ADD, | 3727 | EPOLL_CTL_ADD, |
3721 | daemon->socket_fd, | 3728 | ls, |
3722 | &event)) | 3729 | &event)) |
3723 | { | 3730 | { |
3724 | #ifdef HAVE_MESSAGES | 3731 | #ifdef HAVE_MESSAGES |
@@ -3759,7 +3766,7 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
3759 | for event loop for now */ | 3766 | for event loop for now */ |
3760 | if (0 != epoll_ctl (daemon->epoll_fd, | 3767 | if (0 != epoll_ctl (daemon->epoll_fd, |
3761 | EPOLL_CTL_DEL, | 3768 | EPOLL_CTL_DEL, |
3762 | daemon->socket_fd, | 3769 | ls, |
3763 | NULL)) | 3770 | NULL)) |
3764 | MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); | 3771 | MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); |
3765 | daemon->listen_socket_in_epoll = MHD_NO; | 3772 | daemon->listen_socket_in_epoll = MHD_NO; |
@@ -4141,7 +4148,7 @@ MHD_start_daemon (unsigned int flags, | |||
4141 | * returned socket; however, if MHD is run using threads (anything but | 4148 | * returned socket; however, if MHD is run using threads (anything but |
4142 | * external select mode), socket will be removed from existing threads | 4149 | * external select mode), socket will be removed from existing threads |
4143 | * with some delay and it must not be closed while it's in use. To make | 4150 | * with some delay and it must not be closed while it's in use. To make |
4144 | * sure that socket is not used anymore, call #MHD_stop_daemon. | 4151 | * sure that the socket is not used anymore, call #MHD_stop_daemon. |
4145 | * | 4152 | * |
4146 | * Note that some thread modes require the caller to have passed | 4153 | * Note that some thread modes require the caller to have passed |
4147 | * #MHD_USE_ITC when using this API. If this daemon is | 4154 | * #MHD_USE_ITC when using this API. If this daemon is |
@@ -4196,6 +4203,9 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon) | |||
4196 | MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); | 4203 | MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); |
4197 | } | 4204 | } |
4198 | } | 4205 | } |
4206 | /* FIXME: This creates a race with the rest of the code. | ||
4207 | We may be adding the FD to the epoll-set concurrently | ||
4208 | in another thread! So we DO need to lock (yuck yuck). */ | ||
4199 | daemon->socket_fd = MHD_INVALID_SOCKET; | 4209 | daemon->socket_fd = MHD_INVALID_SOCKET; |
4200 | #ifdef EPOLL_SUPPORT | 4210 | #ifdef EPOLL_SUPPORT |
4201 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | 4211 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && |
@@ -4698,6 +4708,7 @@ static int | |||
4698 | setup_epoll_to_listen (struct MHD_Daemon *daemon) | 4708 | setup_epoll_to_listen (struct MHD_Daemon *daemon) |
4699 | { | 4709 | { |
4700 | struct epoll_event event; | 4710 | struct epoll_event event; |
4711 | MHD_socket ls; | ||
4701 | 4712 | ||
4702 | daemon->epoll_fd = setup_epoll_fd (daemon); | 4713 | daemon->epoll_fd = setup_epoll_fd (daemon); |
4703 | if (-1 == daemon->epoll_fd) | 4714 | if (-1 == daemon->epoll_fd) |
@@ -4710,13 +4721,13 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) | |||
4710 | return MHD_NO; | 4721 | return MHD_NO; |
4711 | } | 4722 | } |
4712 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 4723 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
4713 | if (MHD_INVALID_SOCKET == daemon->socket_fd) | 4724 | if (MHD_INVALID_SOCKET == (ls = daemon->socket_fd)) |
4714 | return MHD_YES; /* non-listening daemon */ | 4725 | return MHD_YES; /* non-listening daemon */ |
4715 | event.events = EPOLLIN; | 4726 | event.events = EPOLLIN; |
4716 | event.data.ptr = daemon; | 4727 | event.data.ptr = daemon; |
4717 | if (0 != epoll_ctl (daemon->epoll_fd, | 4728 | if (0 != epoll_ctl (daemon->epoll_fd, |
4718 | EPOLL_CTL_ADD, | 4729 | EPOLL_CTL_ADD, |
4719 | daemon->socket_fd, | 4730 | ls, |
4720 | &event)) | 4731 | &event)) |
4721 | { | 4732 | { |
4722 | #ifdef HAVE_MESSAGES | 4733 | #ifdef HAVE_MESSAGES |