[master] 89af3f9 Some of the special cases of RST_STREAM

Poul-Henning Kamp phk at FreeBSD.org
Sat Mar 4 10:22:05 CET 2017


commit 89af3f991d01d7b80f2c424171679c5f35a8ce32
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat Mar 4 09:14:29 2017 +0000

    Some of the special cases of RST_STREAM

diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h
index b950dad..3bf6eb0 100644
--- a/bin/varnishd/http2/cache_http2.h
+++ b/bin/varnishd/http2/cache_http2.h
@@ -110,6 +110,7 @@ struct h2_sess {
 	struct vht_table		dectbl[1];
 
 	unsigned			rxf_len;
+	unsigned			rxf_type;
 	unsigned			rxf_flags;
 	unsigned			rxf_stream;
 	uint8_t				*rxf_data;
diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index 602608f..0c1565b 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -352,8 +352,8 @@ h2_do_req(struct worker *wrk, void *priv)
 }
 
 static h2_error
-h2_end_headers(struct worker *wrk, struct h2_sess *h2, struct req *req,
-    struct h2_req *r2)
+h2_end_headers(const struct worker *wrk, const struct h2_sess *h2,
+    struct req *req, struct h2_req *r2)
 {
 	h2_error h2e;
 
@@ -583,6 +583,19 @@ h2_procframe(struct worker *wrk, struct h2_sess *h2)
 	VTAILQ_FOREACH(r2, &h2->streams, list)
 		if (r2->stream == h2->rxf_stream)
 			break;
+
+	if (h2->rxf_type == H2_FRAME_RST_STREAM) {
+		/* Special case RST_STREAM to avoid creating streams */
+		if (h2->rxf_len != 4)
+			return (H2CE_FRAME_SIZE_ERROR);	// rfc7540 6.4
+		if (h2->rxf_stream == 0)
+			return (H2CE_PROTOCOL_ERROR);	// rfc7540 6.4
+		if (h2->rxf_stream > h2->highest_stream)
+			return (H2CE_PROTOCOL_ERROR);	// rfc7540 6.4
+		if (r2 == NULL)
+			return (0);
+	}
+
 	if (r2 == NULL) {
 		if (h2->rxf_stream <= h2->highest_stream)
 			return (H2CE_PROTOCOL_ERROR);	// rfc7540 5.1.1
@@ -591,17 +604,17 @@ h2_procframe(struct worker *wrk, struct h2_sess *h2)
 		AN(r2);
 	}
 
-	if (h2->htc->rxbuf_b[3] >= H2FMAX) {
+	if (h2->rxf_type >= H2FMAX) {
 		h2->bogosity++;
 		VSLb(h2->vsl, SLT_Debug,
-		    "H2: Unknown Frame 0x%02x", h2->htc->rxbuf_b[3]);
+		    "H2: Unknown Frame 0x%02x", h2->rxf_type);
 		return (0);				// rfc7540 4.1
 	}
-	h2f = h2flist + h2->htc->rxbuf_b[3];
+	h2f = h2flist + h2->rxf_type;
 	if (h2f->name == NULL || h2f->func == NULL) {
 		h2->bogosity++;
 		VSLb(h2->vsl, SLT_Debug,
-		    "H2: Unimplemented Frame 0x%02x", h2->htc->rxbuf_b[3]);
+		    "H2: Unimplemented Frame 0x%02x", h2->rxf_type);
 		return (0);				// rfc7540 4.1
 	}
 	if (h2->rxf_flags & ~h2f->flags) {
@@ -652,6 +665,7 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2)
 	}
 
 	h2->rxf_len =  vbe32dec(h2->htc->rxbuf_b) >> 8;
+	h2->rxf_type =  h2->htc->rxbuf_b[3];
 	h2->rxf_flags = h2->htc->rxbuf_b[4];
 	h2->rxf_stream = vbe32dec(h2->htc->rxbuf_b + 5);
 	h2->rxf_data = (void*)(h2->htc->rxbuf_b + 9);
diff --git a/bin/varnishtest/tests/t02003.vtc b/bin/varnishtest/tests/t02003.vtc
index 4d7db98..89f6298 100644
--- a/bin/varnishtest/tests/t02003.vtc
+++ b/bin/varnishtest/tests/t02003.vtc
@@ -10,6 +10,7 @@ varnish v1 -vcl+backend {} -start
 varnish v1 -cliok "param.set feature +http2"
 varnish v1 -cliok "param.set debug +syncvsl"
 
+#######################################################################
 # Test Even stream numbers
 
 client c1 {
@@ -24,6 +25,7 @@ client c1 {
 	stream 0 -wait
 } -run
 
+#######################################################################
 # Test reverse order stream numbers
 
 client c1 {
@@ -41,6 +43,7 @@ client c1 {
 	stream 0 -wait
 } -run
 
+#######################################################################
 # Test WINDOW_UPDATE error conditions
 
 client c1 {
@@ -75,6 +78,7 @@ client c1 {
 	} -run
 } -run
 
+#######################################################################
 # Test PING error conditions
 
 client c1 {
@@ -86,6 +90,7 @@ client c1 {
 	} -run
 } -run
 
+#######################################################################
 # Test PUSH_PROMISE error conditions
 
 client c1 {
@@ -99,3 +104,35 @@ client c1 {
 	} -run
 	stream 0 -wait
 } -run
+
+# Test RST_STREAM error conditions
+
+client c1 {
+	stream 0 {
+		# RST idle stream
+		sendhex "000004 03 00 00000007 00000008"
+		rxgoaway
+		expect goaway.err == PROTOCOL_ERROR
+		expect goaway.laststream == 0
+	} -run
+} -run
+
+client c1 {
+	stream 0 {
+		# RST wrong length
+		sendhex "000005 03 00 00000001 0000000800"
+		rxgoaway
+		expect goaway.err == FRAME_SIZE_ERROR
+		expect goaway.laststream == 0
+	} -run
+} -run
+
+client c1 {
+	stream 0 {
+		# RST stream zero
+		sendhex "000000 03 00 00000000 00000008"
+		rxgoaway
+		expect goaway.err == FRAME_SIZE_ERROR
+		expect goaway.laststream == 0
+	} -run
+} -run



More information about the varnish-commit mailing list