118 lines
3.8 KiB
Diff
118 lines
3.8 KiB
Diff
diff --git a/mod_http2/h2_mplx.c b/mod_http2/h2_mplx.c
|
|
index e512e22..d5ffdbd 100644
|
|
--- a/mod_http2/h2_mplx.c
|
|
+++ b/mod_http2/h2_mplx.c
|
|
@@ -868,102 +868,6 @@ void h2_mplx_task_done(h2_mplx *m, h2_task *task, h2_task **ptask)
|
|
* h2_mplx DoS protection
|
|
******************************************************************************/
|
|
|
|
-static int timed_out_busy_iter(void *data, void *val)
|
|
-{
|
|
- stream_iter_ctx *ctx = data;
|
|
- h2_stream *stream = val;
|
|
- if (h2_task_has_started(stream->task) && !stream->task->worker_done
|
|
- && (ctx->now - stream->task->started_at) > stream->task->timeout) {
|
|
- /* timed out stream occupying a worker, found */
|
|
- ctx->stream = stream;
|
|
- return 0;
|
|
- }
|
|
- return 1;
|
|
-}
|
|
-
|
|
-static h2_stream *get_timed_out_busy_stream(h2_mplx *m)
|
|
-{
|
|
- stream_iter_ctx ctx;
|
|
- ctx.m = m;
|
|
- ctx.stream = NULL;
|
|
- ctx.now = apr_time_now();
|
|
- h2_ihash_iter(m->streams, timed_out_busy_iter, &ctx);
|
|
- return ctx.stream;
|
|
-}
|
|
-
|
|
-static int latest_repeatable_unsubmitted_iter(void *data, void *val)
|
|
-{
|
|
- stream_iter_ctx *ctx = data;
|
|
- h2_stream *stream = val;
|
|
-
|
|
- if (!stream->task) goto leave;
|
|
- if (!h2_task_has_started(stream->task) || stream->task->worker_done) goto leave;
|
|
- if (h2_stream_is_ready(stream)) goto leave;
|
|
- if (stream->task->redo) {
|
|
- ++ctx->count;
|
|
- goto leave;
|
|
- }
|
|
- if (h2_task_can_redo(stream->task)) {
|
|
- /* this task occupies a worker, the response has not been submitted
|
|
- * yet, not been cancelled and it is a repeatable request
|
|
- * -> we could redo it later */
|
|
- if (!ctx->stream
|
|
- || (ctx->stream->task->started_at < stream->task->started_at)) {
|
|
- /* we did not have one or this one was started later */
|
|
- ctx->stream = stream;
|
|
- }
|
|
- }
|
|
-leave:
|
|
- return 1;
|
|
-}
|
|
-
|
|
-static apr_status_t assess_task_to_throttle(h2_task **ptask, h2_mplx *m)
|
|
-{
|
|
- stream_iter_ctx ctx;
|
|
-
|
|
- /* count the running tasks already marked for redo and get one that could
|
|
- * be throttled */
|
|
- *ptask = NULL;
|
|
- ctx.m = m;
|
|
- ctx.stream = NULL;
|
|
- ctx.count = 0;
|
|
- h2_ihash_iter(m->streams, latest_repeatable_unsubmitted_iter, &ctx);
|
|
- if (m->tasks_active - ctx.count > m->limit_active) {
|
|
- /* we are above the limit of running tasks, accounting for the ones
|
|
- * already throttled. */
|
|
- if (ctx.stream && ctx.stream->task) {
|
|
- *ptask = ctx.stream->task;
|
|
- return APR_EAGAIN;
|
|
- }
|
|
- /* above limit, be seeing no candidate for easy throttling */
|
|
- if (get_timed_out_busy_stream(m)) {
|
|
- /* Too many busy workers, unable to cancel enough streams
|
|
- * and with a busy, timed out stream, we tell the client
|
|
- * to go away... */
|
|
- return APR_TIMEUP;
|
|
- }
|
|
- }
|
|
- return APR_SUCCESS;
|
|
-}
|
|
-
|
|
-static apr_status_t unschedule_slow_tasks(h2_mplx *m)
|
|
-{
|
|
- h2_task *task;
|
|
- apr_status_t rv;
|
|
-
|
|
- /* Try to get rid of streams that occupy workers. Look for safe requests
|
|
- * that are repeatable. If none found, fail the connection.
|
|
- */
|
|
- while (APR_EAGAIN == (rv = assess_task_to_throttle(&task, m))) {
|
|
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
|
|
- "h2_mplx(%s): unschedule, resetting task for redo later",
|
|
- task->id);
|
|
- task->redo = 1;
|
|
- h2_task_rst(task, H2_ERR_CANCEL);
|
|
- }
|
|
- return rv;
|
|
-}
|
|
-
|
|
static apr_status_t mplx_be_happy(h2_mplx *m, h2_task *task)
|
|
{
|
|
apr_time_t now;
|
|
@@ -1013,9 +917,6 @@ static apr_status_t mplx_be_annoyed(h2_mplx *m)
|
|
m->id, m->limit_active);
|
|
}
|
|
|
|
- if (m->tasks_active > m->limit_active) {
|
|
- status = unschedule_slow_tasks(m);
|
|
- }
|
|
return status;
|
|
}
|
|
|