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; }