diff options
Diffstat (limited to 'src/lib/connection_add.c')
-rw-r--r-- | src/lib/connection_add.c | 1204 |
1 files changed, 607 insertions, 597 deletions
diff --git a/src/lib/connection_add.c b/src/lib/connection_add.c index cd933d06..aaf04712 100644 --- a/src/lib/connection_add.c +++ b/src/lib/connection_add.c | |||
@@ -53,14 +53,14 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
53 | with the socket; */ | 53 | with the socket; */ |
54 | if ( (NULL != daemon->tls_api) && | 54 | if ( (NULL != daemon->tls_api) && |
55 | (MHD_ELS_POLL != daemon->event_loop_syscall) ) | 55 | (MHD_ELS_POLL != daemon->event_loop_syscall) ) |
56 | { | 56 | { |
57 | MHD_daemon_upgrade_connection_with_select_ (con); | 57 | MHD_daemon_upgrade_connection_with_select_ (con); |
58 | } | 58 | } |
59 | #ifdef HAVE_POLL | 59 | #ifdef HAVE_POLL |
60 | else if (NULL != daemon->tls_api) | 60 | else if (NULL != daemon->tls_api) |
61 | { | 61 | { |
62 | MHD_daemon_upgrade_connection_with_poll_ (con); | 62 | MHD_daemon_upgrade_connection_with_poll_ (con); |
63 | } | 63 | } |
64 | #endif | 64 | #endif |
65 | /* end HTTPS */ | 65 | /* end HTTPS */ |
66 | #endif /* HTTPS_SUPPORT */ | 66 | #endif /* HTTPS_SUPPORT */ |
@@ -111,342 +111,344 @@ thread_main_handle_connection (void *data) | |||
111 | #endif /* ! HAVE_POLL */ | 111 | #endif /* ! HAVE_POLL */ |
112 | bool was_suspended = false; | 112 | bool was_suspended = false; |
113 | 113 | ||
114 | MHD_thread_init_(&con->pid); | 114 | MHD_thread_init_ (&con->pid); |
115 | 115 | ||
116 | while ( (! daemon->shutdown) && | 116 | while ( (! daemon->shutdown) && |
117 | (MHD_REQUEST_CLOSED != con->request.state) ) | 117 | (MHD_REQUEST_CLOSED != con->request.state) ) |
118 | { | 118 | { |
119 | const time_t timeout = daemon->connection_default_timeout; | 119 | const time_t timeout = daemon->connection_default_timeout; |
120 | #ifdef UPGRADE_SUPPORT | 120 | #ifdef UPGRADE_SUPPORT |
121 | struct MHD_UpgradeResponseHandle * const urh = con->request.urh; | 121 | struct MHD_UpgradeResponseHandle *const urh = con->request.urh; |
122 | #else /* ! UPGRADE_SUPPORT */ | 122 | #else /* ! UPGRADE_SUPPORT */ |
123 | static const void * const urh = NULL; | 123 | static const void *const urh = NULL; |
124 | #endif /* ! UPGRADE_SUPPORT */ | 124 | #endif /* ! UPGRADE_SUPPORT */ |
125 | 125 | ||
126 | if ( (con->suspended) && | 126 | if ( (con->suspended) && |
127 | (NULL == urh) ) | 127 | (NULL == urh) ) |
128 | { | ||
129 | /* Connection was suspended, wait for resume. */ | ||
130 | was_suspended = true; | ||
131 | if (! use_poll) | ||
132 | { | ||
133 | FD_ZERO (&rs); | ||
134 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
135 | &rs, | ||
136 | NULL, | ||
137 | FD_SETSIZE)) | ||
128 | { | 138 | { |
129 | /* Connection was suspended, wait for resume. */ | ||
130 | was_suspended = true; | ||
131 | if (! use_poll) | ||
132 | { | ||
133 | FD_ZERO (&rs); | ||
134 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
135 | &rs, | ||
136 | NULL, | ||
137 | FD_SETSIZE)) | ||
138 | { | ||
139 | #ifdef HAVE_MESSAGES | 139 | #ifdef HAVE_MESSAGES |
140 | MHD_DLOG (con->daemon, | 140 | MHD_DLOG (con->daemon, |
141 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 141 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
142 | _("Failed to add FD to fd_set\n")); | 142 | _ ("Failed to add FD to fd_set\n")); |
143 | #endif | 143 | #endif |
144 | goto exit; | 144 | goto exit; |
145 | } | 145 | } |
146 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, | 146 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, |
147 | &rs, | 147 | &rs, |
148 | NULL, | 148 | NULL, |
149 | NULL, | 149 | NULL, |
150 | NULL)) | 150 | NULL)) |
151 | { | 151 | { |
152 | const int err = MHD_socket_get_error_(); | 152 | const int err = MHD_socket_get_error_ (); |
153 | 153 | ||
154 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 154 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
155 | continue; | 155 | continue; |
156 | #ifdef HAVE_MESSAGES | 156 | #ifdef HAVE_MESSAGES |
157 | MHD_DLOG (con->daemon, | 157 | MHD_DLOG (con->daemon, |
158 | MHD_SC_UNEXPECTED_SELECT_ERROR, | 158 | MHD_SC_UNEXPECTED_SELECT_ERROR, |
159 | _("Error during select (%d): `%s'\n"), | 159 | _ ("Error during select (%d): `%s'\n"), |
160 | err, | 160 | err, |
161 | MHD_socket_strerr_ (err)); | 161 | MHD_socket_strerr_ (err)); |
162 | #endif | 162 | #endif |
163 | break; | 163 | break; |
164 | } | 164 | } |
165 | } | 165 | } |
166 | #ifdef HAVE_POLL | 166 | #ifdef HAVE_POLL |
167 | else /* use_poll */ | 167 | else /* use_poll */ |
168 | { | 168 | { |
169 | p[0].events = POLLIN; | 169 | p[0].events = POLLIN; |
170 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); | 170 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); |
171 | p[0].revents = 0; | 171 | p[0].revents = 0; |
172 | if (0 > MHD_sys_poll_ (p, | 172 | if (0 > MHD_sys_poll_ (p, |
173 | 1, | 173 | 1, |
174 | -1)) | 174 | -1)) |
175 | { | 175 | { |
176 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | 176 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
177 | continue; | 177 | continue; |
178 | #ifdef HAVE_MESSAGES | 178 | #ifdef HAVE_MESSAGES |
179 | MHD_DLOG (con->daemon, | 179 | MHD_DLOG (con->daemon, |
180 | MHD_SC_UNEXPECTED_POLL_ERROR, | 180 | MHD_SC_UNEXPECTED_POLL_ERROR, |
181 | _("Error during poll: `%s'\n"), | 181 | _ ("Error during poll: `%s'\n"), |
182 | MHD_socket_last_strerr_ ()); | 182 | MHD_socket_last_strerr_ ()); |
183 | #endif | 183 | #endif |
184 | break; | 184 | break; |
185 | } | 185 | } |
186 | } | 186 | } |
187 | #endif /* HAVE_POLL */ | 187 | #endif /* HAVE_POLL */ |
188 | MHD_itc_clear_ (daemon->itc); | 188 | MHD_itc_clear_ (daemon->itc); |
189 | continue; /* Check again for resume. */ | 189 | continue; /* Check again for resume. */ |
190 | } /* End of "suspended" branch. */ | 190 | } /* End of "suspended" branch. */ |
191 | 191 | ||
192 | if (was_suspended) | 192 | if (was_suspended) |
193 | { | 193 | { |
194 | MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */ | 194 | MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */ |
195 | /* Process response queued during suspend and update states. */ | 195 | /* Process response queued during suspend and update states. */ |
196 | MHD_request_handle_idle_ (&con->request); | 196 | MHD_request_handle_idle_ (&con->request); |
197 | was_suspended = false; | 197 | was_suspended = false; |
198 | } | 198 | } |
199 | 199 | ||
200 | tvp = NULL; | 200 | tvp = NULL; |
201 | 201 | ||
202 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info) | 202 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info) |
203 | #ifdef HTTPS_SUPPORT | 203 | #ifdef HTTPS_SUPPORT |
204 | || ( (con->tls_read_ready) && | 204 | || ( (con->tls_read_ready) && |
205 | (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) ) | 205 | (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) ) |
206 | #endif /* HTTPS_SUPPORT */ | 206 | #endif /* HTTPS_SUPPORT */ |
207 | ) | 207 | ) |
208 | { | 208 | { |
209 | /* do not block: more data may be inside of TLS buffers waiting or | 209 | /* do not block: more data may be inside of TLS buffers waiting or |
210 | * application must provide response data */ | 210 | * application must provide response data */ |
211 | tv.tv_sec = 0; | 211 | tv.tv_sec = 0; |
212 | tv.tv_usec = 0; | 212 | tv.tv_usec = 0; |
213 | tvp = &tv; | 213 | tvp = &tv; |
214 | } | 214 | } |
215 | if ( (NULL == tvp) && | 215 | if ( (NULL == tvp) && |
216 | (timeout > 0) ) | 216 | (timeout > 0) ) |
217 | { | 217 | { |
218 | now = MHD_monotonic_sec_counter(); | 218 | now = MHD_monotonic_sec_counter (); |
219 | if (now - con->last_activity > timeout) | 219 | if (now - con->last_activity > timeout) |
220 | tv.tv_sec = 0; | 220 | tv.tv_sec = 0; |
221 | else | 221 | else |
222 | { | 222 | { |
223 | const time_t seconds_left = timeout - (now - con->last_activity); | 223 | const time_t seconds_left = timeout - (now - con->last_activity); |
224 | #if !defined(_WIN32) || defined(__CYGWIN__) | 224 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
225 | tv.tv_sec = seconds_left; | 225 | tv.tv_sec = seconds_left; |
226 | #else /* _WIN32 && !__CYGWIN__ */ | 226 | #else /* _WIN32 && !__CYGWIN__ */ |
227 | if (seconds_left > TIMEVAL_TV_SEC_MAX) | 227 | if (seconds_left > TIMEVAL_TV_SEC_MAX) |
228 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; | 228 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; |
229 | else | 229 | else |
230 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; | 230 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; |
231 | #endif /* _WIN32 && ! __CYGWIN__ */ | 231 | #endif /* _WIN32 && ! __CYGWIN__ */ |
232 | } | 232 | } |
233 | tv.tv_usec = 0; | 233 | tv.tv_usec = 0; |
234 | tvp = &tv; | 234 | tvp = &tv; |
235 | } | 235 | } |
236 | if (! use_poll) | 236 | if (! use_poll) |
237 | { | 237 | { |
238 | /* use select */ | 238 | /* use select */ |
239 | bool err_state = false; | 239 | bool err_state = false; |
240 | 240 | ||
241 | FD_ZERO (&rs); | 241 | FD_ZERO (&rs); |
242 | FD_ZERO (&ws); | 242 | FD_ZERO (&ws); |
243 | FD_ZERO (&es); | 243 | FD_ZERO (&es); |
244 | maxsock = MHD_INVALID_SOCKET; | 244 | maxsock = MHD_INVALID_SOCKET; |
245 | switch (con->request.event_loop_info) | 245 | switch (con->request.event_loop_info) |
246 | { | 246 | { |
247 | case MHD_EVENT_LOOP_INFO_READ: | 247 | case MHD_EVENT_LOOP_INFO_READ: |
248 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 248 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
249 | &rs, | 249 | &rs, |
250 | &maxsock, | 250 | &maxsock, |
251 | FD_SETSIZE)) | 251 | FD_SETSIZE)) |
252 | err_state = true; | 252 | err_state = true; |
253 | break; | 253 | break; |
254 | case MHD_EVENT_LOOP_INFO_WRITE: | 254 | case MHD_EVENT_LOOP_INFO_WRITE: |
255 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 255 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
256 | &ws, | 256 | &ws, |
257 | &maxsock, | 257 | &maxsock, |
258 | FD_SETSIZE)) | 258 | FD_SETSIZE)) |
259 | err_state = true; | 259 | err_state = true; |
260 | break; | 260 | break; |
261 | case MHD_EVENT_LOOP_INFO_BLOCK: | 261 | case MHD_EVENT_LOOP_INFO_BLOCK: |
262 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 262 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
263 | &es, | 263 | &es, |
264 | &maxsock, | 264 | &maxsock, |
265 | FD_SETSIZE)) | 265 | FD_SETSIZE)) |
266 | err_state = true; | 266 | err_state = true; |
267 | break; | 267 | break; |
268 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 268 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
269 | /* how did we get here!? */ | 269 | /* how did we get here!? */ |
270 | goto exit; | 270 | goto exit; |
271 | } | 271 | } |
272 | #if WINDOWS | 272 | #if WINDOWS |
273 | if (MHD_ITC_IS_VALID_(daemon->itc) ) | 273 | if (MHD_ITC_IS_VALID_ (daemon->itc) ) |
274 | { | 274 | { |
275 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 275 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
276 | &rs, | 276 | &rs, |
277 | &maxsock, | 277 | &maxsock, |
278 | FD_SETSIZE)) | 278 | FD_SETSIZE)) |
279 | err_state = 1; | 279 | err_state = 1; |
280 | } | 280 | } |
281 | #endif | 281 | #endif |
282 | if (err_state) | 282 | if (err_state) |
283 | { | 283 | { |
284 | #ifdef HAVE_MESSAGES | 284 | #ifdef HAVE_MESSAGES |
285 | MHD_DLOG (con->daemon, | 285 | MHD_DLOG (con->daemon, |
286 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 286 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
287 | _("Failed to add FD to fd_set\n")); | 287 | _ ("Failed to add FD to fd_set\n")); |
288 | #endif | 288 | #endif |
289 | goto exit; | 289 | goto exit; |
290 | } | 290 | } |
291 | 291 | ||
292 | num_ready = MHD_SYS_select_ (maxsock + 1, | 292 | num_ready = MHD_SYS_select_ (maxsock + 1, |
293 | &rs, | 293 | &rs, |
294 | &ws, | 294 | &ws, |
295 | &es, | 295 | &es, |
296 | tvp); | 296 | tvp); |
297 | if (num_ready < 0) | 297 | if (num_ready < 0) |
298 | { | 298 | { |
299 | const int err = MHD_socket_get_error_(); | 299 | const int err = MHD_socket_get_error_ (); |
300 | 300 | ||
301 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 301 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
302 | continue; | 302 | continue; |
303 | #ifdef HAVE_MESSAGES | 303 | #ifdef HAVE_MESSAGES |
304 | MHD_DLOG (con->daemon, | 304 | MHD_DLOG (con->daemon, |
305 | MHD_SC_UNEXPECTED_SELECT_ERROR, | 305 | MHD_SC_UNEXPECTED_SELECT_ERROR, |
306 | _("Error during select (%d): `%s'\n"), | 306 | _ ("Error during select (%d): `%s'\n"), |
307 | err, | 307 | err, |
308 | MHD_socket_strerr_ (err)); | 308 | MHD_socket_strerr_ (err)); |
309 | #endif | 309 | #endif |
310 | break; | 310 | break; |
311 | } | 311 | } |
312 | #if WINDOWS | 312 | #if WINDOWS |
313 | /* Clear ITC before other processing so additional | 313 | /* Clear ITC before other processing so additional |
314 | * signals will trigger select() again */ | 314 | * signals will trigger select() again */ |
315 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 315 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
316 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | 316 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), |
317 | &rs)) ) | 317 | &rs)) ) |
318 | MHD_itc_clear_ (daemon->itc); | 318 | MHD_itc_clear_ (daemon->itc); |
319 | #endif | 319 | #endif |
320 | if (MHD_NO == | 320 | if (MHD_NO == |
321 | MHD_connection_call_handlers_ (con, | 321 | MHD_connection_call_handlers_ (con, |
322 | FD_ISSET (con->socket_fd, | 322 | FD_ISSET (con->socket_fd, |
323 | &rs), | 323 | &rs), |
324 | FD_ISSET (con->socket_fd, | 324 | FD_ISSET (con->socket_fd, |
325 | &ws), | 325 | &ws), |
326 | FD_ISSET (con->socket_fd, | 326 | FD_ISSET (con->socket_fd, |
327 | &es)) ) | 327 | &es)) ) |
328 | goto exit; | 328 | goto exit; |
329 | } | 329 | } |
330 | #ifdef HAVE_POLL | 330 | #ifdef HAVE_POLL |
331 | else | 331 | else |
332 | { | 332 | { |
333 | /* use poll */ | 333 | /* use poll */ |
334 | memset (&p, | 334 | memset (&p, |
335 | 0, | 335 | 0, |
336 | sizeof (p)); | 336 | sizeof (p)); |
337 | p[0].fd = con->socket_fd; | 337 | p[0].fd = con->socket_fd; |
338 | switch (con->request.event_loop_info) | 338 | switch (con->request.event_loop_info) |
339 | { | 339 | { |
340 | case MHD_EVENT_LOOP_INFO_READ: | 340 | case MHD_EVENT_LOOP_INFO_READ: |
341 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | 341 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; |
342 | break; | 342 | break; |
343 | case MHD_EVENT_LOOP_INFO_WRITE: | 343 | case MHD_EVENT_LOOP_INFO_WRITE: |
344 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | 344 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; |
345 | break; | 345 | break; |
346 | case MHD_EVENT_LOOP_INFO_BLOCK: | 346 | case MHD_EVENT_LOOP_INFO_BLOCK: |
347 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; | 347 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; |
348 | break; | 348 | break; |
349 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 349 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
350 | /* how did we get here!? */ | 350 | /* how did we get here!? */ |
351 | goto exit; | 351 | goto exit; |
352 | } | 352 | } |
353 | #if WINDOWS | 353 | #if WINDOWS |
354 | extra_slot = 0; | 354 | extra_slot = 0; |
355 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 355 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
356 | { | 356 | { |
357 | p[1].events |= POLLIN; | 357 | p[1].events |= POLLIN; |
358 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); | 358 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); |
359 | p[1].revents = 0; | 359 | p[1].revents = 0; |
360 | extra_slot = 1; | 360 | extra_slot = 1; |
361 | } | 361 | } |
362 | #endif | 362 | #endif |
363 | if (MHD_sys_poll_ (p, | 363 | if (MHD_sys_poll_ (p, |
364 | #if WINDOWS | 364 | #if WINDOWS |
365 | 1 + extra_slot, | 365 | 1 + extra_slot, |
366 | #else | 366 | #else |
367 | 1, | 367 | 1, |
368 | #endif | 368 | #endif |
369 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) | 369 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) |
370 | { | 370 | { |
371 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | 371 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
372 | continue; | 372 | continue; |
373 | #ifdef HAVE_MESSAGES | 373 | #ifdef HAVE_MESSAGES |
374 | MHD_DLOG (con->daemon, | 374 | MHD_DLOG (con->daemon, |
375 | MHD_SC_UNEXPECTED_POLL_ERROR, | 375 | MHD_SC_UNEXPECTED_POLL_ERROR, |
376 | _("Error during poll: `%s'\n"), | 376 | _ ("Error during poll: `%s'\n"), |
377 | MHD_socket_last_strerr_ ()); | 377 | MHD_socket_last_strerr_ ()); |
378 | #endif | 378 | #endif |
379 | break; | 379 | break; |
380 | } | 380 | } |
381 | #if WINDOWS | 381 | #if WINDOWS |
382 | /* Clear ITC before other processing so additional | 382 | /* Clear ITC before other processing so additional |
383 | * signals will trigger poll() again */ | 383 | * signals will trigger poll() again */ |
384 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 384 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
385 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) | 385 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) |
386 | MHD_itc_clear_ (daemon->itc); | 386 | MHD_itc_clear_ (daemon->itc); |
387 | #endif | 387 | #endif |
388 | if (MHD_NO == | 388 | if (MHD_NO == |
389 | MHD_connection_call_handlers_ (con, | 389 | MHD_connection_call_handlers_ (con, |
390 | 0 != (p[0].revents & POLLIN), | 390 | (0 != (p[0].revents & POLLIN)), |
391 | 0 != (p[0].revents & POLLOUT), | 391 | (0 != (p[0].revents & POLLOUT)), |
392 | 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC)))) | 392 | (0 != (p[0].revents & (POLLERR |
393 | goto exit; | 393 | | |
394 | } | 394 | MHD_POLL_REVENTS_ERR_DISC))) )) |
395 | goto exit; | ||
396 | } | ||
395 | #endif | 397 | #endif |
396 | #ifdef UPGRADE_SUPPORT | 398 | #ifdef UPGRADE_SUPPORT |
397 | if (MHD_REQUEST_UPGRADE == con->request.state) | 399 | if (MHD_REQUEST_UPGRADE == con->request.state) |
398 | { | 400 | { |
399 | /* Normal HTTP processing is finished, | 401 | /* Normal HTTP processing is finished, |
400 | * notify application. */ | 402 | * notify application. */ |
401 | if (NULL != con->request.response->termination_cb) | 403 | if (NULL != con->request.response->termination_cb) |
402 | con->request.response->termination_cb | 404 | con->request.response->termination_cb |
403 | (con->request.response->termination_cb_cls, | 405 | (con->request.response->termination_cb_cls, |
404 | MHD_REQUEST_TERMINATED_COMPLETED_OK, | 406 | MHD_REQUEST_TERMINATED_COMPLETED_OK, |
405 | con->request.client_context); | 407 | con->request.client_context); |
406 | thread_main_connection_upgrade (con); | 408 | thread_main_connection_upgrade (con); |
407 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ | 409 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ |
408 | 410 | ||
409 | /* "Upgraded" data will not be used in this thread from this point. */ | 411 | /* "Upgraded" data will not be used in this thread from this point. */ |
410 | con->request.urh->clean_ready = true; | 412 | con->request.urh->clean_ready = true; |
411 | /* If 'urh->was_closed' set to true, connection will be | 413 | /* If 'urh->was_closed' set to true, connection will be |
412 | * moved immediately to cleanup list. Otherwise connection | 414 | * moved immediately to cleanup list. Otherwise connection |
413 | * will stay in suspended list until 'urh' will be marked | 415 | * will stay in suspended list until 'urh' will be marked |
414 | * with 'was_closed' by application. */ | 416 | * with 'was_closed' by application. */ |
415 | MHD_request_resume (&con->request); | 417 | MHD_request_resume (&con->request); |
416 | 418 | ||
417 | /* skip usual clean up */ | 419 | /* skip usual clean up */ |
418 | return (MHD_THRD_RTRN_TYPE_) 0; | 420 | return (MHD_THRD_RTRN_TYPE_) 0; |
419 | } | ||
420 | #endif /* UPGRADE_SUPPORT */ | ||
421 | } | 421 | } |
422 | #endif /* UPGRADE_SUPPORT */ | ||
423 | } | ||
422 | #if DEBUG_CLOSE | 424 | #if DEBUG_CLOSE |
423 | #ifdef HAVE_MESSAGES | 425 | #ifdef HAVE_MESSAGES |
424 | MHD_DLOG (con->daemon, | 426 | MHD_DLOG (con->daemon, |
425 | MHD_SC_THREAD_TERMINATING, | 427 | MHD_SC_THREAD_TERMINATING, |
426 | _("Processing thread terminating. Closing connection\n")); | 428 | _ ("Processing thread terminating. Closing connection\n")); |
427 | #endif | 429 | #endif |
428 | #endif | 430 | #endif |
429 | if (MHD_REQUEST_CLOSED != con->request.state) | 431 | if (MHD_REQUEST_CLOSED != con->request.state) |
430 | MHD_connection_close_ (con, | 432 | MHD_connection_close_ (con, |
431 | (daemon->shutdown) ? | 433 | (daemon->shutdown) ? |
432 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN: | 434 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN : |
433 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 435 | MHD_REQUEST_TERMINATED_WITH_ERROR); |
434 | MHD_request_handle_idle_ (&con->request); | 436 | MHD_request_handle_idle_ (&con->request); |
435 | exit: | 437 | exit: |
436 | if (NULL != con->request.response) | 438 | if (NULL != con->request.response) |
437 | { | 439 | { |
438 | MHD_response_queue_for_destroy (con->request.response); | 440 | MHD_response_queue_for_destroy (con->request.response); |
439 | con->request.response = NULL; | 441 | con->request.response = NULL; |
440 | } | 442 | } |
441 | 443 | ||
442 | if (MHD_INVALID_SOCKET != con->socket_fd) | 444 | if (MHD_INVALID_SOCKET != con->socket_fd) |
443 | { | 445 | { |
444 | shutdown (con->socket_fd, | 446 | shutdown (con->socket_fd, |
445 | SHUT_WR); | 447 | SHUT_WR); |
446 | /* 'socket_fd' can be used in other thread to signal shutdown. | 448 | /* 'socket_fd' can be used in other thread to signal shutdown. |
447 | * To avoid data races, do not close socket here. Daemon will | 449 | * To avoid data races, do not close socket here. Daemon will |
448 | * use more connections only after cleanup anyway. */ | 450 | * use more connections only after cleanup anyway. */ |
449 | } | 451 | } |
450 | return (MHD_THRD_RTRN_TYPE_) 0; | 452 | return (MHD_THRD_RTRN_TYPE_) 0; |
451 | } | 453 | } |
452 | 454 | ||
@@ -469,9 +471,9 @@ recv_param_adapter (struct MHD_Connection *connection, | |||
469 | 471 | ||
470 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || | 472 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || |
471 | (MHD_REQUEST_CLOSED == connection->request.state) ) | 473 | (MHD_REQUEST_CLOSED == connection->request.state) ) |
472 | { | 474 | { |
473 | return MHD_ERR_NOTCONN_; | 475 | return MHD_ERR_NOTCONN_; |
474 | } | 476 | } |
475 | if (i > MHD_SCKT_SEND_MAX_SIZE_) | 477 | if (i > MHD_SCKT_SEND_MAX_SIZE_) |
476 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ | 478 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ |
477 | 479 | ||
@@ -479,25 +481,25 @@ recv_param_adapter (struct MHD_Connection *connection, | |||
479 | other, | 481 | other, |
480 | i); | 482 | i); |
481 | if (0 > ret) | 483 | if (0 > ret) |
484 | { | ||
485 | const int err = MHD_socket_get_error_ (); | ||
486 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
482 | { | 487 | { |
483 | const int err = MHD_socket_get_error_ (); | ||
484 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
485 | { | ||
486 | #ifdef EPOLL_SUPPORT | 488 | #ifdef EPOLL_SUPPORT |
487 | /* Got EAGAIN --- no longer read-ready */ | 489 | /* Got EAGAIN --- no longer read-ready */ |
488 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | 490 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; |
489 | #endif /* EPOLL_SUPPORT */ | 491 | #endif /* EPOLL_SUPPORT */ |
490 | return MHD_ERR_AGAIN_; | 492 | return MHD_ERR_AGAIN_; |
491 | } | ||
492 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
493 | return MHD_ERR_AGAIN_; | ||
494 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
495 | return MHD_ERR_CONNRESET_; | ||
496 | /* Treat any other error as hard error. */ | ||
497 | return MHD_ERR_NOTCONN_; | ||
498 | } | 493 | } |
494 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
495 | return MHD_ERR_AGAIN_; | ||
496 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
497 | return MHD_ERR_CONNRESET_; | ||
498 | /* Treat any other error as hard error. */ | ||
499 | return MHD_ERR_NOTCONN_; | ||
500 | } | ||
499 | #ifdef EPOLL_SUPPORT | 501 | #ifdef EPOLL_SUPPORT |
500 | else if (i > (size_t)ret) | 502 | else if (i > (size_t) ret) |
501 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | 503 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; |
502 | #endif /* EPOLL_SUPPORT */ | 504 | #endif /* EPOLL_SUPPORT */ |
503 | return ret; | 505 | return ret; |
@@ -522,9 +524,9 @@ send_param_adapter (struct MHD_Connection *connection, | |||
522 | 524 | ||
523 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || | 525 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || |
524 | (MHD_REQUEST_CLOSED == connection->request.state) ) | 526 | (MHD_REQUEST_CLOSED == connection->request.state) ) |
525 | { | 527 | { |
526 | return MHD_ERR_NOTCONN_; | 528 | return MHD_ERR_NOTCONN_; |
527 | } | 529 | } |
528 | if (i > MHD_SCKT_SEND_MAX_SIZE_) | 530 | if (i > MHD_SCKT_SEND_MAX_SIZE_) |
529 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ | 531 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ |
530 | 532 | ||
@@ -532,26 +534,26 @@ send_param_adapter (struct MHD_Connection *connection, | |||
532 | other, | 534 | other, |
533 | i); | 535 | i); |
534 | if (0 > ret) | 536 | if (0 > ret) |
535 | { | 537 | { |
536 | const int err = MHD_socket_get_error_(); | 538 | const int err = MHD_socket_get_error_ (); |
537 | 539 | ||
538 | if (MHD_SCKT_ERR_IS_EAGAIN_(err)) | 540 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) |
539 | { | 541 | { |
540 | #ifdef EPOLL_SUPPORT | 542 | #ifdef EPOLL_SUPPORT |
541 | /* EAGAIN --- no longer write-ready */ | 543 | /* EAGAIN --- no longer write-ready */ |
542 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 544 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; |
543 | #endif /* EPOLL_SUPPORT */ | 545 | #endif /* EPOLL_SUPPORT */ |
544 | return MHD_ERR_AGAIN_; | 546 | return MHD_ERR_AGAIN_; |
545 | } | ||
546 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
547 | return MHD_ERR_AGAIN_; | ||
548 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
549 | return MHD_ERR_CONNRESET_; | ||
550 | /* Treat any other error as hard error. */ | ||
551 | return MHD_ERR_NOTCONN_; | ||
552 | } | 547 | } |
548 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
549 | return MHD_ERR_AGAIN_; | ||
550 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
551 | return MHD_ERR_CONNRESET_; | ||
552 | /* Treat any other error as hard error. */ | ||
553 | return MHD_ERR_NOTCONN_; | ||
554 | } | ||
553 | #ifdef EPOLL_SUPPORT | 555 | #ifdef EPOLL_SUPPORT |
554 | else if (i > (size_t)ret) | 556 | else if (i > (size_t) ret) |
555 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 557 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; |
556 | #endif /* EPOLL_SUPPORT */ | 558 | #endif /* EPOLL_SUPPORT */ |
557 | return ret; | 559 | return ret; |
@@ -582,11 +584,11 @@ send_param_adapter (struct MHD_Connection *connection, | |||
582 | */ | 584 | */ |
583 | static enum MHD_StatusCode | 585 | static enum MHD_StatusCode |
584 | internal_add_connection (struct MHD_Daemon *daemon, | 586 | internal_add_connection (struct MHD_Daemon *daemon, |
585 | MHD_socket client_socket, | 587 | MHD_socket client_socket, |
586 | const struct sockaddr *addr, | 588 | const struct sockaddr *addr, |
587 | socklen_t addrlen, | 589 | socklen_t addrlen, |
588 | bool external_add, | 590 | bool external_add, |
589 | bool non_blck) | 591 | bool non_blck) |
590 | { | 592 | { |
591 | enum MHD_StatusCode sc; | 593 | enum MHD_StatusCode sc; |
592 | struct MHD_Connection *connection; | 594 | struct MHD_Connection *connection; |
@@ -594,78 +596,78 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
594 | 596 | ||
595 | /* Direct add to master daemon could happen only with "external" add mode. */ | 597 | /* Direct add to master daemon could happen only with "external" add mode. */ |
596 | mhd_assert ( (NULL == daemon->worker_pool) || | 598 | mhd_assert ( (NULL == daemon->worker_pool) || |
597 | (external_add) ); | 599 | (external_add) ); |
598 | if ( (external_add) && | 600 | if ( (external_add) && |
599 | (NULL != daemon->worker_pool) ) | 601 | (NULL != daemon->worker_pool) ) |
600 | { | 602 | { |
601 | unsigned int i; | 603 | unsigned int i; |
602 | 604 | ||
603 | /* have a pool, try to find a pool with capacity; we use the | 605 | /* have a pool, try to find a pool with capacity; we use the |
604 | socket as the initial offset into the pool for load | 606 | socket as the initial offset into the pool for load |
605 | balancing */ | 607 | balancing */ |
606 | for (i = 0; i < daemon->worker_pool_size; ++i) | 608 | for (i = 0; i < daemon->worker_pool_size; ++i) |
607 | { | 609 | { |
608 | struct MHD_Daemon * const worker = | 610 | struct MHD_Daemon *const worker = |
609 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; | 611 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; |
610 | if (worker->connections < worker->global_connection_limit) | 612 | if (worker->connections < worker->global_connection_limit) |
611 | return internal_add_connection (worker, | 613 | return internal_add_connection (worker, |
612 | client_socket, | 614 | client_socket, |
613 | addr, | 615 | addr, |
614 | addrlen, | 616 | addrlen, |
615 | true, | 617 | true, |
616 | non_blck); | 618 | non_blck); |
617 | } | 619 | } |
618 | /* all pools are at their connection limit, must refuse */ | 620 | /* all pools are at their connection limit, must refuse */ |
619 | MHD_socket_close_chk_ (client_socket); | 621 | MHD_socket_close_chk_ (client_socket); |
620 | #if ENFILE | 622 | #if ENFILE |
621 | errno = ENFILE; | 623 | errno = ENFILE; |
622 | #endif | 624 | #endif |
623 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; | 625 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; |
624 | } | 626 | } |
625 | 627 | ||
626 | if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, | 628 | if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket, |
627 | NULL)) && | 629 | NULL)) && |
628 | (MHD_ELS_SELECT == daemon->event_loop_syscall) ) | 630 | (MHD_ELS_SELECT == daemon->event_loop_syscall) ) |
629 | { | 631 | { |
630 | #ifdef HAVE_MESSAGES | 632 | #ifdef HAVE_MESSAGES |
631 | MHD_DLOG (daemon, | 633 | MHD_DLOG (daemon, |
632 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 634 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
633 | _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), | 635 | _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), |
634 | (int) client_socket, | 636 | (int) client_socket, |
635 | (int) FD_SETSIZE); | 637 | (int) FD_SETSIZE); |
636 | #endif | 638 | #endif |
637 | MHD_socket_close_chk_ (client_socket); | 639 | MHD_socket_close_chk_ (client_socket); |
638 | #if EINVAL | 640 | #if EINVAL |
639 | errno = EINVAL; | 641 | errno = EINVAL; |
640 | #endif | 642 | #endif |
641 | return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 643 | return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
642 | } | 644 | } |
643 | 645 | ||
644 | #ifdef MHD_socket_nosignal_ | 646 | #ifdef MHD_socket_nosignal_ |
645 | if (! MHD_socket_nosignal_ (client_socket)) | 647 | if (! MHD_socket_nosignal_ (client_socket)) |
646 | { | 648 | { |
647 | #ifdef HAVE_MESSAGES | 649 | #ifdef HAVE_MESSAGES |
648 | MHD_DLOG (daemon, | 650 | MHD_DLOG (daemon, |
649 | MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED, | 651 | MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED, |
650 | _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), | 652 | _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), |
651 | MHD_socket_last_strerr_()); | 653 | MHD_socket_last_strerr_ ()); |
652 | #endif | 654 | #endif |
653 | #ifndef MSG_NOSIGNAL | 655 | #ifndef MSG_NOSIGNAL |
654 | /* Cannot use socket as it can produce SIGPIPE. */ | 656 | /* Cannot use socket as it can produce SIGPIPE. */ |
655 | #ifdef ENOTSOCK | 657 | #ifdef ENOTSOCK |
656 | errno = ENOTSOCK; | 658 | errno = ENOTSOCK; |
657 | #endif /* ENOTSOCK */ | 659 | #endif /* ENOTSOCK */ |
658 | return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED; | 660 | return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED; |
659 | #endif /* ! MSG_NOSIGNAL */ | 661 | #endif /* ! MSG_NOSIGNAL */ |
660 | } | 662 | } |
661 | #endif /* MHD_socket_nosignal_ */ | 663 | #endif /* MHD_socket_nosignal_ */ |
662 | 664 | ||
663 | 665 | ||
664 | #ifdef HAVE_MESSAGES | 666 | #ifdef HAVE_MESSAGES |
665 | #if DEBUG_CONNECT | 667 | #if DEBUG_CONNECT |
666 | MHD_DLOG (daemon, | 668 | MHD_DLOG (daemon, |
667 | MHD_SC_CONNECTION_ACCEPTED, | 669 | MHD_SC_CONNECTION_ACCEPTED, |
668 | _("Accepted connection on socket %d\n"), | 670 | _ ("Accepted connection on socket %d\n"), |
669 | client_socket); | 671 | client_socket); |
670 | #endif | 672 | #endif |
671 | #endif | 673 | #endif |
@@ -673,82 +675,83 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
673 | (MHD_NO == MHD_ip_limit_add (daemon, | 675 | (MHD_NO == MHD_ip_limit_add (daemon, |
674 | addr, | 676 | addr, |
675 | addrlen)) ) | 677 | addrlen)) ) |
676 | { | 678 | { |
677 | /* above connection limit - reject */ | 679 | /* above connection limit - reject */ |
678 | #ifdef HAVE_MESSAGES | 680 | #ifdef HAVE_MESSAGES |
679 | MHD_DLOG (daemon, | 681 | MHD_DLOG (daemon, |
680 | MHD_SC_LIMIT_CONNECTIONS_REACHED, | 682 | MHD_SC_LIMIT_CONNECTIONS_REACHED, |
681 | _("Server reached connection limit. Closing inbound connection.\n")); | 683 | _ ( |
684 | "Server reached connection limit. Closing inbound connection.\n")); | ||
682 | #endif | 685 | #endif |
683 | MHD_socket_close_chk_ (client_socket); | 686 | MHD_socket_close_chk_ (client_socket); |
684 | #if ENFILE | 687 | #if ENFILE |
685 | errno = ENFILE; | 688 | errno = ENFILE; |
686 | #endif | 689 | #endif |
687 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; | 690 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; |
688 | } | 691 | } |
689 | 692 | ||
690 | /* apply connection acceptance policy if present */ | 693 | /* apply connection acceptance policy if present */ |
691 | if ( (NULL != daemon->accept_policy_cb) && | 694 | if ( (NULL != daemon->accept_policy_cb) && |
692 | (MHD_NO == | 695 | (MHD_NO == |
693 | daemon->accept_policy_cb (daemon->accept_policy_cb_cls, | 696 | daemon->accept_policy_cb (daemon->accept_policy_cb_cls, |
694 | addr, | 697 | addr, |
695 | addrlen)) ) | 698 | addrlen)) ) |
696 | { | 699 | { |
697 | #if DEBUG_CLOSE | 700 | #if DEBUG_CLOSE |
698 | #ifdef HAVE_MESSAGES | 701 | #ifdef HAVE_MESSAGES |
699 | MHD_DLOG (daemon, | 702 | MHD_DLOG (daemon, |
700 | MHD_SC_ACCEPT_POLICY_REJECTED, | 703 | MHD_SC_ACCEPT_POLICY_REJECTED, |
701 | _("Connection rejected by application. Closing connection.\n")); | 704 | _ ("Connection rejected by application. Closing connection.\n")); |
702 | #endif | 705 | #endif |
703 | #endif | 706 | #endif |
704 | MHD_socket_close_chk_ (client_socket); | 707 | MHD_socket_close_chk_ (client_socket); |
705 | MHD_ip_limit_del (daemon, | 708 | MHD_ip_limit_del (daemon, |
706 | addr, | 709 | addr, |
707 | addrlen); | 710 | addrlen); |
708 | #if EACCESS | 711 | #if EACCESS |
709 | errno = EACCESS; | 712 | errno = EACCESS; |
710 | #endif | 713 | #endif |
711 | return MHD_SC_ACCEPT_POLICY_REJECTED; | 714 | return MHD_SC_ACCEPT_POLICY_REJECTED; |
712 | } | 715 | } |
713 | 716 | ||
714 | if (NULL == | 717 | if (NULL == |
715 | (connection = MHD_calloc_ (1, | 718 | (connection = MHD_calloc_ (1, |
716 | sizeof (struct MHD_Connection)))) | 719 | sizeof (struct MHD_Connection)))) |
717 | { | 720 | { |
718 | eno = errno; | 721 | eno = errno; |
719 | #ifdef HAVE_MESSAGES | 722 | #ifdef HAVE_MESSAGES |
720 | MHD_DLOG (daemon, | 723 | MHD_DLOG (daemon, |
721 | MHD_SC_CONNECTION_MALLOC_FAILURE, | 724 | MHD_SC_CONNECTION_MALLOC_FAILURE, |
722 | "Error allocating memory: %s\n", | 725 | "Error allocating memory: %s\n", |
723 | MHD_strerror_ (errno)); | 726 | MHD_strerror_ (errno)); |
724 | #endif | 727 | #endif |
725 | MHD_socket_close_chk_ (client_socket); | 728 | MHD_socket_close_chk_ (client_socket); |
726 | MHD_ip_limit_del (daemon, | 729 | MHD_ip_limit_del (daemon, |
727 | addr, | 730 | addr, |
728 | addrlen); | 731 | addrlen); |
729 | errno = eno; | 732 | errno = eno; |
730 | return MHD_SC_CONNECTION_MALLOC_FAILURE; | 733 | return MHD_SC_CONNECTION_MALLOC_FAILURE; |
731 | } | 734 | } |
732 | connection->pool | 735 | connection->pool |
733 | = MHD_pool_create (daemon->connection_memory_limit_b); | 736 | = MHD_pool_create (daemon->connection_memory_limit_b); |
734 | if (NULL == connection->pool) | 737 | if (NULL == connection->pool) |
735 | { | 738 | { |
736 | #ifdef HAVE_MESSAGES | 739 | #ifdef HAVE_MESSAGES |
737 | MHD_DLOG (daemon, | 740 | MHD_DLOG (daemon, |
738 | MHD_SC_POOL_MALLOC_FAILURE, | 741 | MHD_SC_POOL_MALLOC_FAILURE, |
739 | _("Error allocating memory: %s\n"), | 742 | _ ("Error allocating memory: %s\n"), |
740 | MHD_strerror_ (errno)); | 743 | MHD_strerror_ (errno)); |
741 | #endif | 744 | #endif |
742 | MHD_socket_close_chk_ (client_socket); | 745 | MHD_socket_close_chk_ (client_socket); |
743 | MHD_ip_limit_del (daemon, | 746 | MHD_ip_limit_del (daemon, |
744 | addr, | 747 | addr, |
745 | addrlen); | 748 | addrlen); |
746 | free (connection); | 749 | free (connection); |
747 | #if ENOMEM | 750 | #if ENOMEM |
748 | errno = ENOMEM; | 751 | errno = ENOMEM; |
749 | #endif | 752 | #endif |
750 | return MHD_SC_POOL_MALLOC_FAILURE; | 753 | return MHD_SC_POOL_MALLOC_FAILURE; |
751 | } | 754 | } |
752 | 755 | ||
753 | connection->connection_timeout = daemon->connection_default_timeout; | 756 | connection->connection_timeout = daemon->connection_default_timeout; |
754 | memcpy (&connection->addr, | 757 | memcpy (&connection->addr, |
@@ -758,148 +761,151 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
758 | connection->socket_fd = client_socket; | 761 | connection->socket_fd = client_socket; |
759 | connection->sk_nonblck = non_blck; | 762 | connection->sk_nonblck = non_blck; |
760 | connection->daemon = daemon; | 763 | connection->daemon = daemon; |
761 | connection->last_activity = MHD_monotonic_sec_counter(); | 764 | connection->last_activity = MHD_monotonic_sec_counter (); |
762 | 765 | ||
763 | #ifdef HTTPS_SUPPORT | 766 | #ifdef HTTPS_SUPPORT |
764 | if (NULL != daemon->tls_api) | 767 | if (NULL != daemon->tls_api) |
768 | { | ||
769 | connection->tls_cs | ||
770 | = daemon->tls_api->setup_connection (daemon->tls_api->cls, | ||
771 | NULL /* FIXME */); | ||
772 | if (NULL == connection->tls_cs) | ||
765 | { | 773 | { |
766 | connection->tls_cs | 774 | eno = EINVAL; |
767 | = daemon->tls_api->setup_connection (daemon->tls_api->cls, | 775 | sc = -1; // FIXME! |
768 | NULL /* FIXME */); | 776 | goto cleanup; |
769 | if (NULL == connection->tls_cs) | ||
770 | { | ||
771 | eno = EINVAL; | ||
772 | sc = -1; // FIXME! | ||
773 | goto cleanup; | ||
774 | } | ||
775 | } | 777 | } |
778 | } | ||
776 | else | 779 | else |
777 | #endif /* ! HTTPS_SUPPORT */ | 780 | #endif /* ! HTTPS_SUPPORT */ |
778 | { | 781 | { |
779 | /* set default connection handlers */ | 782 | /* set default connection handlers */ |
780 | connection->recv_cls = &recv_param_adapter; | 783 | connection->recv_cls = &recv_param_adapter; |
781 | connection->send_cls = &send_param_adapter; | 784 | connection->send_cls = &send_param_adapter; |
782 | } | 785 | } |
783 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 786 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
784 | /* Firm check under lock. */ | 787 | /* Firm check under lock. */ |
785 | if (daemon->connections >= daemon->global_connection_limit) | 788 | if (daemon->connections >= daemon->global_connection_limit) |
786 | { | 789 | { |
787 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 790 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
788 | /* above connection limit - reject */ | 791 | /* above connection limit - reject */ |
789 | #ifdef HAVE_MESSAGES | 792 | #ifdef HAVE_MESSAGES |
790 | MHD_DLOG (daemon, | 793 | MHD_DLOG (daemon, |
791 | MHD_SC_LIMIT_CONNECTIONS_REACHED, | 794 | MHD_SC_LIMIT_CONNECTIONS_REACHED, |
792 | _("Server reached connection limit. Closing inbound connection.\n")); | 795 | _ ( |
796 | "Server reached connection limit. Closing inbound connection.\n")); | ||
793 | #endif | 797 | #endif |
794 | #if ENFILE | 798 | #if ENFILE |
795 | eno = ENFILE; | 799 | eno = ENFILE; |
796 | #endif | 800 | #endif |
797 | sc = MHD_SC_LIMIT_CONNECTIONS_REACHED; | 801 | sc = MHD_SC_LIMIT_CONNECTIONS_REACHED; |
798 | goto cleanup; | 802 | goto cleanup; |
799 | } | 803 | } |
800 | daemon->connections++; | 804 | daemon->connections++; |
801 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 805 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) |
802 | { | 806 | { |
803 | XDLL_insert (daemon->normal_timeout_head, | 807 | XDLL_insert (daemon->normal_timeout_head, |
804 | daemon->normal_timeout_tail, | 808 | daemon->normal_timeout_tail, |
805 | connection); | 809 | connection); |
806 | } | 810 | } |
807 | DLL_insert (daemon->connections_head, | 811 | DLL_insert (daemon->connections_head, |
808 | daemon->connections_tail, | 812 | daemon->connections_tail, |
809 | connection); | 813 | connection); |
810 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 814 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
811 | 815 | ||
812 | if (NULL != daemon->notify_connection_cb) | 816 | if (NULL != daemon->notify_connection_cb) |
813 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, | 817 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, |
814 | connection, | 818 | connection, |
815 | MHD_CONNECTION_NOTIFY_STARTED); | 819 | MHD_CONNECTION_NOTIFY_STARTED); |
816 | 820 | ||
817 | /* attempt to create handler thread */ | 821 | /* attempt to create handler thread */ |
818 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 822 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
823 | { | ||
824 | if (! MHD_create_named_thread_ (&connection->pid, | ||
825 | "MHD-connection", | ||
826 | daemon->thread_stack_limit_b, | ||
827 | &thread_main_handle_connection, | ||
828 | connection)) | ||
819 | { | 829 | { |
820 | if (! MHD_create_named_thread_ (&connection->pid, | 830 | eno = errno; |
821 | "MHD-connection", | ||
822 | daemon->thread_stack_limit_b, | ||
823 | &thread_main_handle_connection, | ||
824 | connection)) | ||
825 | { | ||
826 | eno = errno; | ||
827 | #ifdef HAVE_MESSAGES | 831 | #ifdef HAVE_MESSAGES |
828 | MHD_DLOG (daemon, | 832 | MHD_DLOG (daemon, |
829 | MHD_SC_THREAD_LAUNCH_FAILURE, | 833 | MHD_SC_THREAD_LAUNCH_FAILURE, |
830 | "Failed to create a thread: %s\n", | 834 | "Failed to create a thread: %s\n", |
831 | MHD_strerror_ (eno)); | 835 | MHD_strerror_ (eno)); |
832 | #endif | 836 | #endif |
833 | sc = MHD_SC_THREAD_LAUNCH_FAILURE; | 837 | sc = MHD_SC_THREAD_LAUNCH_FAILURE; |
834 | goto cleanup; | 838 | goto cleanup; |
835 | } | ||
836 | } | 839 | } |
840 | } | ||
837 | else | 841 | else |
838 | { | 842 | { |
839 | connection->pid = daemon->pid; | 843 | connection->pid = daemon->pid; |
840 | } | 844 | } |
841 | #ifdef EPOLL_SUPPORT | 845 | #ifdef EPOLL_SUPPORT |
842 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) | 846 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) |
843 | { | 847 | { |
844 | if ( (! daemon->enable_turbo) || | 848 | if ( (! daemon->enable_turbo) || |
845 | (external_add)) | 849 | (external_add)) |
846 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ | 850 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ |
847 | struct epoll_event event; | 851 | struct epoll_event event; |
848 | 852 | ||
849 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; | 853 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; |
850 | event.data.ptr = connection; | 854 | event.data.ptr = connection; |
851 | if (0 != epoll_ctl (daemon->epoll_fd, | 855 | if (0 != epoll_ctl (daemon->epoll_fd, |
852 | EPOLL_CTL_ADD, | 856 | EPOLL_CTL_ADD, |
853 | client_socket, | 857 | client_socket, |
854 | &event)) | 858 | &event)) |
855 | { | 859 | { |
856 | eno = errno; | 860 | eno = errno; |
857 | #ifdef HAVE_MESSAGES | 861 | #ifdef HAVE_MESSAGES |
858 | MHD_DLOG (daemon, | 862 | MHD_DLOG (daemon, |
859 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 863 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
860 | _("Call to epoll_ctl failed: %s\n"), | 864 | _ ("Call to epoll_ctl failed: %s\n"), |
861 | MHD_socket_last_strerr_ ()); | 865 | MHD_socket_last_strerr_ ()); |
862 | #endif | 866 | #endif |
863 | sc = MHD_SC_EPOLL_CTL_ADD_FAILED; | 867 | sc = MHD_SC_EPOLL_CTL_ADD_FAILED; |
864 | goto cleanup; | 868 | goto cleanup; |
865 | } | 869 | } |
866 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; | 870 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; |
867 | } | 871 | } |
868 | else | 872 | else |
869 | { | 873 | { |
870 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY | 874 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY |
871 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; | 875 | | MHD_EPOLL_STATE_WRITE_READY |
872 | EDLL_insert (daemon->eready_head, | 876 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; |
873 | daemon->eready_tail, | 877 | EDLL_insert (daemon->eready_head, |
874 | connection); | 878 | daemon->eready_tail, |
875 | } | 879 | connection); |
876 | } | 880 | } |
881 | } | ||
877 | else /* This 'else' is combined with next 'if'. */ | 882 | else /* This 'else' is combined with next 'if'. */ |
878 | #endif | 883 | #endif |
879 | if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && | 884 | if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && |
880 | (external_add) && | 885 | (external_add) && |
881 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 886 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
882 | (! MHD_itc_activate_ (daemon->itc, | 887 | (! MHD_itc_activate_ (daemon->itc, |
883 | "n")) ) | 888 | "n")) ) |
884 | { | 889 | { |
885 | #ifdef HAVE_MESSAGES | 890 | #ifdef HAVE_MESSAGES |
886 | MHD_DLOG (daemon, | 891 | MHD_DLOG (daemon, |
887 | MHD_SC_ITC_USE_FAILED, | 892 | MHD_SC_ITC_USE_FAILED, |
888 | _("Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).")); | 893 | _ ( |
894 | "Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).")); | ||
889 | #endif | 895 | #endif |
890 | } | 896 | } |
891 | return MHD_SC_OK; | 897 | return MHD_SC_OK; |
892 | 898 | ||
893 | cleanup: | 899 | cleanup: |
894 | if (NULL != daemon->notify_connection_cb) | 900 | if (NULL != daemon->notify_connection_cb) |
895 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, | 901 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, |
896 | connection, | 902 | connection, |
897 | MHD_CONNECTION_NOTIFY_CLOSED); | 903 | MHD_CONNECTION_NOTIFY_CLOSED); |
898 | #ifdef HTTPS_SUPPORT | 904 | #ifdef HTTPS_SUPPORT |
899 | if ( (NULL != daemon->tls_api) && | 905 | if ( (NULL != daemon->tls_api) && |
900 | (NULL != connection->tls_cs) ) | 906 | (NULL != connection->tls_cs) ) |
901 | daemon->tls_api->teardown_connection (daemon->tls_api->cls, | 907 | daemon->tls_api->teardown_connection (daemon->tls_api->cls, |
902 | connection->tls_cs); | 908 | connection->tls_cs); |
903 | #endif /* HTTPS_SUPPORT */ | 909 | #endif /* HTTPS_SUPPORT */ |
904 | MHD_socket_close_chk_ (client_socket); | 910 | MHD_socket_close_chk_ (client_socket); |
905 | MHD_ip_limit_del (daemon, | 911 | MHD_ip_limit_del (daemon, |
@@ -907,14 +913,14 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
907 | addrlen); | 913 | addrlen); |
908 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 914 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
909 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 915 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) |
910 | { | 916 | { |
911 | XDLL_remove (daemon->normal_timeout_head, | 917 | XDLL_remove (daemon->normal_timeout_head, |
912 | daemon->normal_timeout_tail, | 918 | daemon->normal_timeout_tail, |
913 | connection); | 919 | connection); |
914 | } | 920 | } |
915 | DLL_remove (daemon->connections_head, | 921 | DLL_remove (daemon->connections_head, |
916 | daemon->connections_tail, | 922 | daemon->connections_tail, |
917 | connection); | 923 | connection); |
918 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 924 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
919 | MHD_pool_destroy (connection->pool); | 925 | MHD_pool_destroy (connection->pool); |
920 | free (connection); | 926 | free (connection); |
@@ -954,42 +960,42 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
954 | */ | 960 | */ |
955 | enum MHD_StatusCode | 961 | enum MHD_StatusCode |
956 | MHD_daemon_add_connection (struct MHD_Daemon *daemon, | 962 | MHD_daemon_add_connection (struct MHD_Daemon *daemon, |
957 | MHD_socket client_socket, | 963 | MHD_socket client_socket, |
958 | const struct sockaddr *addr, | 964 | const struct sockaddr *addr, |
959 | socklen_t addrlen) | 965 | socklen_t addrlen) |
960 | { | 966 | { |
961 | bool sk_nonbl; | 967 | bool sk_nonbl; |
962 | 968 | ||
963 | if (! MHD_socket_nonblocking_ (client_socket)) | 969 | if (! MHD_socket_nonblocking_ (client_socket)) |
964 | { | 970 | { |
965 | #ifdef HAVE_MESSAGES | 971 | #ifdef HAVE_MESSAGES |
966 | MHD_DLOG (daemon, | 972 | MHD_DLOG (daemon, |
967 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, | 973 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, |
968 | _("Failed to set nonblocking mode on new client socket: %s\n"), | 974 | _ ("Failed to set nonblocking mode on new client socket: %s\n"), |
969 | MHD_socket_last_strerr_()); | 975 | MHD_socket_last_strerr_ ()); |
970 | #endif | 976 | #endif |
971 | sk_nonbl = false; | 977 | sk_nonbl = false; |
972 | } | 978 | } |
973 | else | 979 | else |
974 | { | 980 | { |
975 | sk_nonbl = true; | 981 | sk_nonbl = true; |
976 | } | 982 | } |
977 | 983 | ||
978 | if ( (daemon->enable_turbo) && | 984 | if ( (daemon->enable_turbo) && |
979 | (! MHD_socket_noninheritable_ (client_socket)) ) | 985 | (! MHD_socket_noninheritable_ (client_socket)) ) |
980 | { | 986 | { |
981 | #ifdef HAVE_MESSAGES | 987 | #ifdef HAVE_MESSAGES |
982 | MHD_DLOG (daemon, | 988 | MHD_DLOG (daemon, |
983 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, | 989 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, |
984 | _("Failed to set noninheritable mode on new client socket.\n")); | 990 | _ ("Failed to set noninheritable mode on new client socket.\n")); |
985 | #endif | 991 | #endif |
986 | } | 992 | } |
987 | return internal_add_connection (daemon, | 993 | return internal_add_connection (daemon, |
988 | client_socket, | 994 | client_socket, |
989 | addr, | 995 | addr, |
990 | addrlen, | 996 | addrlen, |
991 | true, | 997 | true, |
992 | sk_nonbl); | 998 | sk_nonbl); |
993 | } | 999 | } |
994 | 1000 | ||
995 | 1001 | ||
@@ -1033,94 +1039,98 @@ MHD_accept_connection_ (struct MHD_Daemon *daemon) | |||
1033 | #endif /* ! USE_ACCEPT4 */ | 1039 | #endif /* ! USE_ACCEPT4 */ |
1034 | if ( (MHD_INVALID_SOCKET == s) || | 1040 | if ( (MHD_INVALID_SOCKET == s) || |
1035 | (addrlen <= 0) ) | 1041 | (addrlen <= 0) ) |
1036 | { | 1042 | { |
1037 | const int err = MHD_socket_get_error_ (); | 1043 | const int err = MHD_socket_get_error_ (); |
1038 | 1044 | ||
1039 | /* This could be a common occurance with multiple worker threads */ | 1045 | /* This could be a common occurance with multiple worker threads */ |
1040 | if (MHD_SCKT_ERR_IS_ (err, | 1046 | if (MHD_SCKT_ERR_IS_ (err, |
1041 | MHD_SCKT_EINVAL_)) | 1047 | MHD_SCKT_EINVAL_)) |
1042 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */ | 1048 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */ |
1043 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) | 1049 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err)) |
1044 | return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */ | 1050 | return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */ |
1045 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ) | 1051 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ) |
1046 | return MHD_SC_ACCEPT_FAILED_EAGAIN; | 1052 | return MHD_SC_ACCEPT_FAILED_EAGAIN; |
1047 | if (MHD_INVALID_SOCKET != s) | 1053 | if (MHD_INVALID_SOCKET != s) |
1048 | { | 1054 | { |
1049 | MHD_socket_close_chk_ (s); | 1055 | MHD_socket_close_chk_ (s); |
1050 | } | 1056 | } |
1051 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) | 1057 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) |
1052 | { | 1058 | { |
1053 | /* system/process out of resources */ | 1059 | /* system/process out of resources */ |
1054 | if (0 == daemon->connections) | 1060 | if (0 == daemon->connections) |
1055 | { | 1061 | { |
1056 | #ifdef HAVE_MESSAGES | 1062 | #ifdef HAVE_MESSAGES |
1057 | /* Not setting 'at_limit' flag, as there is no way it | 1063 | /* Not setting 'at_limit' flag, as there is no way it |
1058 | would ever be cleared. Instead trying to produce | 1064 | would ever be cleared. Instead trying to produce |
1059 | bit fat ugly warning. */ | 1065 | bit fat ugly warning. */ |
1060 | MHD_DLOG (daemon, | 1066 | MHD_DLOG (daemon, |
1061 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY, | 1067 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY, |
1062 | _("Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); | 1068 | _ ( |
1069 | "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); | ||
1063 | #endif | 1070 | #endif |
1064 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY; | 1071 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY; |
1065 | } | 1072 | } |
1066 | else | 1073 | else |
1067 | { | 1074 | { |
1068 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 1075 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
1069 | daemon->at_limit = true; | 1076 | daemon->at_limit = true; |
1070 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 1077 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
1071 | #ifdef HAVE_MESSAGES | 1078 | #ifdef HAVE_MESSAGES |
1072 | MHD_DLOG (daemon, | 1079 | MHD_DLOG (daemon, |
1073 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED, | 1080 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED, |
1074 | _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), | 1081 | _ ( |
1075 | (unsigned int) daemon->connections); | 1082 | "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), |
1083 | (unsigned int) daemon->connections); | ||
1076 | #endif | 1084 | #endif |
1077 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED; | 1085 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED; |
1078 | } | 1086 | } |
1079 | } | 1087 | } |
1080 | #ifdef HAVE_MESSAGES | 1088 | #ifdef HAVE_MESSAGES |
1081 | MHD_DLOG (daemon, | 1089 | MHD_DLOG (daemon, |
1082 | MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY, | 1090 | MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY, |
1083 | _("Error accepting connection: %s\n"), | 1091 | _ ("Error accepting connection: %s\n"), |
1084 | MHD_socket_strerr_(err)); | 1092 | MHD_socket_strerr_ (err)); |
1085 | #endif | 1093 | #endif |
1086 | return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY; | 1094 | return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY; |
1087 | } | 1095 | } |
1088 | #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) | 1096 | #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK) |
1089 | if (! MHD_socket_nonblocking_ (s)) | 1097 | if (! MHD_socket_nonblocking_ (s)) |
1090 | { | 1098 | { |
1091 | #ifdef HAVE_MESSAGES | 1099 | #ifdef HAVE_MESSAGES |
1092 | MHD_DLOG (daemon, | 1100 | MHD_DLOG (daemon, |
1093 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, | 1101 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, |
1094 | _("Failed to set nonblocking mode on incoming connection socket: %s\n"), | 1102 | _ ( |
1095 | MHD_socket_last_strerr_()); | 1103 | "Failed to set nonblocking mode on incoming connection socket: %s\n"), |
1104 | MHD_socket_last_strerr_ ()); | ||
1096 | #endif | 1105 | #endif |
1097 | } | 1106 | } |
1098 | else | 1107 | else |
1099 | sk_nonbl = true; | 1108 | sk_nonbl = true; |
1100 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ | 1109 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ |
1101 | #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) | 1110 | #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC) |
1102 | if (! MHD_socket_noninheritable_ (s)) | 1111 | if (! MHD_socket_noninheritable_ (s)) |
1103 | { | 1112 | { |
1104 | #ifdef HAVE_MESSAGES | 1113 | #ifdef HAVE_MESSAGES |
1105 | MHD_DLOG (daemon, | 1114 | MHD_DLOG (daemon, |
1106 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, | 1115 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, |
1107 | _("Failed to set noninheritable mode on incoming connection socket.\n")); | 1116 | _ ( |
1117 | "Failed to set noninheritable mode on incoming connection socket.\n")); | ||
1108 | #endif | 1118 | #endif |
1109 | } | 1119 | } |
1110 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ | 1120 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ |
1111 | #ifdef HAVE_MESSAGES | 1121 | #ifdef HAVE_MESSAGES |
1112 | #if DEBUG_CONNECT | 1122 | #if DEBUG_CONNECT |
1113 | MHD_DLOG (daemon, | 1123 | MHD_DLOG (daemon, |
1114 | MHD_SC_CONNECTION_ACCEPTED, | 1124 | MHD_SC_CONNECTION_ACCEPTED, |
1115 | _("Accepted connection on socket %d\n"), | 1125 | _ ("Accepted connection on socket %d\n"), |
1116 | s); | 1126 | s); |
1117 | #endif | 1127 | #endif |
1118 | #endif | 1128 | #endif |
1119 | return internal_add_connection (daemon, | 1129 | return internal_add_connection (daemon, |
1120 | s, | 1130 | s, |
1121 | addr, | 1131 | addr, |
1122 | addrlen, | 1132 | addrlen, |
1123 | false, | 1133 | false, |
1124 | sk_nonbl); | 1134 | sk_nonbl); |
1125 | } | 1135 | } |
1126 | 1136 | ||