Commit ee7930ed authored by Dridi Boukelmoune's avatar Dridi Boukelmoune Committed by Simon Stridsberg

http2_proto: Enforce session timeouts in h2_sweep()

The new meaning for h2->sess->t_idle is now the time since the last
complete frame, except before the first frame where it corresponds to
the creation of the session.

Conflicts:
	bin/varnishd/http2/cache_http2_proto.c
parent cd48ced7
...@@ -1357,14 +1357,20 @@ h2_stream_tmo_unlocked(struct h2_sess *h2, const struct h2_req *r2) ...@@ -1357,14 +1357,20 @@ h2_stream_tmo_unlocked(struct h2_sess *h2, const struct h2_req *r2)
* This is the janitorial task of cleaning up any closed & refused * This is the janitorial task of cleaning up any closed & refused
* streams, and checking if the session is timed out. * streams, and checking if the session is timed out.
*/ */
static int static h2_error
h2_sweep(struct worker *wrk, struct h2_sess *h2) h2_sweep(struct worker *wrk, struct h2_sess *h2)
{ {
int tmo = 0;
struct h2_req *r2, *r22; struct h2_req *r2, *r22;
h2_error h2e = NULL, tmo;
vtim_real now;
ASSERT_RXTHR(h2); ASSERT_RXTHR(h2);
now = VTIM_real();
if (h2e == NULL && h2->open_streams == 0 &&
h2->sess->t_idle + cache_param->timeout_idle < now)
h2e = H2CE_NO_ERROR;
h2->do_sweep = 0; h2->do_sweep = 0;
VTAILQ_FOREACH_SAFE(r2, &h2->streams, list, r22) { VTAILQ_FOREACH_SAFE(r2, &h2->streams, list, r22) {
if (r2 == h2->req0) { if (r2 == h2->req0) {
...@@ -1388,10 +1394,9 @@ h2_sweep(struct worker *wrk, struct h2_sess *h2) ...@@ -1388,10 +1394,9 @@ h2_sweep(struct worker *wrk, struct h2_sess *h2)
/* FALLTHROUGH */ /* FALLTHROUGH */
case H2_S_CLOS_LOC: case H2_S_CLOS_LOC:
case H2_S_OPEN: case H2_S_OPEN:
if (h2_stream_tmo_unlocked(h2, r2)) { tmo = h2_stream_tmo_unlocked(h2, r2);
tmo = 1; if (h2e == NULL)
continue; h2e = tmo;
}
break; break;
case H2_S_IDLE: case H2_S_IDLE:
/* Current code make this unreachable: h2_new_req is /* Current code make this unreachable: h2_new_req is
...@@ -1403,9 +1408,7 @@ h2_sweep(struct worker *wrk, struct h2_sess *h2) ...@@ -1403,9 +1408,7 @@ h2_sweep(struct worker *wrk, struct h2_sess *h2)
break; break;
} }
} }
if (tmo) return (h2e);
return (0);
return (h2->refcnt > 1);
} }
...@@ -1437,30 +1440,30 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2) ...@@ -1437,30 +1440,30 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2)
return (0); return (0);
VTCP_blocking(*h2->htc->rfd); VTCP_blocking(*h2->htc->rfd);
h2->sess->t_idle = VTIM_real(); hs = HTC_RxStuff(h2->htc, h2_frame_complete, NULL, NULL, NAN,
hs = HTC_RxStuff(h2->htc, h2_frame_complete, VTIM_real() + 0.5, NAN, h2->local_settings.max_frame_size + 9);
NULL, NULL, NAN,
h2->sess->t_idle + SESS_TMO(h2->sess, timeout_idle), h2e = NULL;
NAN, h2->local_settings.max_frame_size + 9);
switch (hs) { switch (hs) {
case HTC_S_COMPLETE: case HTC_S_COMPLETE:
h2->sess->t_idle = VTIM_real();
if (h2->do_sweep)
h2e = h2_sweep(wrk, h2);
break; break;
case HTC_S_TIMEOUT: case HTC_S_TIMEOUT:
if (h2_sweep(wrk, h2)) h2e = h2_sweep(wrk, h2);
return (1); break;
/* FALLTHROUGH */
default: default:
/* XXX: HTC_S_OVERFLOW / FRAME_SIZE_ERROR handling */ h2e = H2CE_ENHANCE_YOUR_CALM;
Lck_Lock(&h2->sess->mtx); }
VSLb(h2->vsl, SLT_Debug, "H2: No frame (hs=%d)", hs);
h2->error = H2CE_NO_ERROR; if (h2e != NULL && h2e->connection) {
Lck_Unlock(&h2->sess->mtx); h2->error = h2e;
return (0); return (0);
} }
if (h2->do_sweep) if (hs != HTC_S_COMPLETE)
(void)h2_sweep(wrk, h2); return (1);
h2->rxf_len = vbe32dec(h2->htc->rxbuf_b) >> 8; h2->rxf_len = vbe32dec(h2->htc->rxbuf_b) >> 8;
h2->rxf_type = h2->htc->rxbuf_b[3]; h2->rxf_type = h2->htc->rxbuf_b[3];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment