[master] 6358f4a Try to push H2 into even weirder corners.

Poul-Henning Kamp phk at FreeBSD.org
Thu Mar 23 22:21:06 CET 2017


commit 6358f4a81edec4065b3bfeaeea54583d70336eb5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Mar 23 21:19:46 2017 +0000

    Try to push H2 into even weirder corners.

diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index 33aea63..6683752 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -177,12 +177,14 @@ h2_del_req(struct worker *wrk, struct h2_req *r2)
 	/* XXX: PRIORITY reshuffle */
 	VTAILQ_REMOVE(&h2->streams, r2, list);
 	Lck_Unlock(&sp->mtx);
+	AZ(r2->req->ws->r);
 	Req_Cleanup(sp, wrk, r2->req);
 	Req_Release(r2->req);
 	if (r)
 		return;
 	/* All streams gone, including stream #0, clean up */
 	req = h2->srq;
+	AZ(req->ws->r);
 	Req_Cleanup(sp, wrk, req);
 	Req_Release(req);
 	SES_Delete(sp, SC_RX_JUNK, NAN);
@@ -271,15 +273,21 @@ h2_rx_rst_stream(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
 {
 	(void)wrk;
 
+	AN(r2);
 	if (h2->rxf_len != 4)			// rfc7540,l,2003,2004
 		return (H2CE_FRAME_SIZE_ERROR);
-	if (r2 == NULL)
-		return (0);
 	Lck_Lock(&h2->sess->mtx);
 	r2->error = h2_streamerror(vbe32dec(h2->rxf_data));
+VSLb(h2->vsl, SLT_Debug, "H2RST %u %d %s", r2->stream, r2->state, r2->error->name);
 	if (r2->wrk != NULL)
-		AZ(pthread_cond_signal(&r2->wrk->cond));
+		AZ(pthread_cond_signal(h2->cond));
+	if (r2->state != H2_S_IDLE) {
+		r2->state = H2_S_CLOSED;
+		r2 = NULL;
+	}
 	Lck_Unlock(&h2->sess->mtx);
+	if (r2 != NULL)
+		h2_del_req(wrk, r2);
 	return (0);
 }
 
@@ -620,7 +628,9 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp)
 	Lck_Lock(&h2->sess->mtx);
 	while (h2->mailcall != r2 && h2->error == 0 && r2->error == 0)
 		AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0));
-	if (h2->mailcall == r2) {
+	if (h2->error || r2->error) {
+		retval = VFP_ERROR;
+	} else {
 		assert(h2->mailcall == r2);
 		if (l > h2->rxf_len)
 			l = h2->rxf_len;
@@ -636,8 +646,6 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp)
 		}
 		h2->mailcall = NULL;
 		AZ(pthread_cond_broadcast(h2->cond));
-	} else {
-		retval = VFP_ERROR;
 	}
 	Lck_Unlock(&h2->sess->mtx);
 	return (retval);
diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c
index 18b2adf..69fc12f 100644
--- a/bin/varnishd/http2/cache_http2_session.c
+++ b/bin/varnishd/http2/cache_http2_session.c
@@ -313,7 +313,7 @@ h2_new_session(struct worker *wrk, void *arg)
 	AN(h2->error);
 	/* Delete all idle streams */
 	Lck_Lock(&sp->mtx);
-	VSLb(h2->vsl, SLT_Debug, "H2 CLEANUP %p", h2->error);
+	VSLb(h2->vsl, SLT_Debug, "H2 CLEANUP %s", h2->error->name);
 	VTAILQ_FOREACH(r2, &h2->streams, list) {
 		if (r2->error == 0)
 			r2->error = h2->error;
diff --git a/bin/varnishtest/tests/t02007.vtc b/bin/varnishtest/tests/t02007.vtc
index a3d44be..b168535 100644
--- a/bin/varnishtest/tests/t02007.vtc
+++ b/bin/varnishtest/tests/t02007.vtc
@@ -4,6 +4,19 @@ server s1 {
 	rxreq
 	expect req.proto == HTTP/1.1
 	txresp -hdr "Content-Type: text/plain" -hdrlen Foo 100 -bodylen 100
+
+	non_fatal
+	close
+	accept
+	rxreq
+	expect req.url == /3
+	expect req.proto == HTTP/1.1
+	txresp -hdr "Content-Type: text/plain" -hdrlen Foo 50 -bodylen 50
+
+	close
+	accept
+	rxreq
+	expect req.url == /5
 } -start
 
 varnish v1 -vcl+backend {} -cliok "param.set feature +http2" -start
@@ -40,3 +53,36 @@ client c1 {
 	} -run
 } -run
 
+varnish v1 -vsl_catchup
+
+client c1 {
+	stream 3 {
+		txreq \
+			-req POST \
+			-url /3 \
+			-hdr content-type text/plain \
+			-nostrend
+		delay .2
+		txdata \
+			-nostrend \
+			-data request
+		delay .2
+		txrst -err 0x333
+	} -run
+	delay 2
+
+	stream 5 {
+		txreq \
+			-req POST \
+			-url /5 \
+			-hdr content-type text/plain \
+			-nostrend
+		delay .2
+		txdata \
+			-nostrend \
+			-data request
+		delay .2
+	} -run
+} -run
+
+varnish v1 -vsl_catchup



More information about the varnish-commit mailing list