[master] a1eb3da Due to the incompetent H2 protocol design, we also need to keep track of which per-frame flags only get sent on the last frame of a continued frame-sequence.

Poul-Henning Kamp phk at FreeBSD.org
Mon Mar 6 16:07:06 CET 2017


commit a1eb3dad0a1bf343249aded1096691c7c1497e46
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Mar 6 11:29:33 2017 +0000

    Due to the incompetent H2 protocol design, we also need to keep track of
    which per-frame flags only get sent on the last frame of a
    continued frame-sequence.

diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h
index 4f9b3b0..041bced 100644
--- a/bin/varnishd/http2/cache_http2.h
+++ b/bin/varnishd/http2/cache_http2.h
@@ -59,6 +59,7 @@ struct h2_frame_s {
 	h2_error	act_sidle;
 	int		respect_window;
 	h2_frame	continuation;
+	uint8_t		final_flags;
 };
 
 
diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c
index 076cc1d..75fcc43 100644
--- a/bin/varnishd/http2/cache_http2_send.c
+++ b/bin/varnishd/http2/cache_http2_send.c
@@ -102,6 +102,7 @@ H2_Send(struct worker *wrk, struct h2_req *r2, int flush,
 	struct h2_sess *h2;
 	uint32_t mfs, tf;
 	const char *p;
+	uint8_t final_flags;
 
 	(void)flush;
 
@@ -126,14 +127,20 @@ H2_Send(struct worker *wrk, struct h2_req *r2, int flush,
 		AN(ptr);
 		AN(len);
 		p = ptr;
+		final_flags = ftyp->final_flags & flags;
+		flags &= ~ftyp->final_flags;
 		do {
 			AN(ftyp->continuation);
 			tf = mfs;
-			if (tf > len)
+			if (tf > len) {
 				tf = len;
-			retval = H2_Send_Frame(wrk, h2, ftyp,
-			    tf == len ? flags : 0,
-			    tf, r2->stream, p);
+				retval = H2_Send_Frame(wrk, h2, ftyp,
+				    flags, tf, r2->stream, p);
+				flags = 0;
+			} else {
+				retval = H2_Send_Frame(wrk, h2, ftyp,
+				    final_flags, tf, r2->stream, p);
+			}
 			p += tf;
 			len -= tf;
 			ftyp = ftyp->continuation;
diff --git a/include/tbl/h2_frames.h b/include/tbl/h2_frames.h
index c8eb31f..039937d 100644
--- a/include/tbl/h2_frames.h
+++ b/include/tbl/h2_frames.h
@@ -37,26 +37,30 @@
  *	rx_stream-idle
  *	tx_flow-control			// rfc7540,l,1265,1270
  *	tx_continuation
+ *	tx_final-flags
  */
   H2_FRAME(data,		DATA,		0x0, 0x09,
 	H2CE_PROTOCOL_ERROR,		// rfc7540,l,1758,1761
 	0,
 	H2CE_PROTOCOL_ERROR,
 	1,
-	H2_F_DATA
+	H2_F_DATA,
+	H2FF_DATA_END_STREAM		// rfc7540,l,1750,1753
   )
   H2_FRAME(headers,		HEADERS,	0x1, 0x2d,
 	H2CE_PROTOCOL_ERROR,		// rfc7540,l,1876,1879
 	0,
 	0,				// rfc7540,l,938,940
 	0,
-	H2_F_CONTINUATION
+	H2_F_CONTINUATION,
+	H2FF_HEADERS_END_HEADERS,	// rfc7540,l,1855,1857
   )
   H2_FRAME(priority,		PRIORITY,	0x2, 0x00,
 	H2CE_PROTOCOL_ERROR,		// rfc7540,l,1933,1936
 	0,
 	0,				// rfc7540,l,938,940
 	0,
+	0,
 	0
   )
   H2_FRAME(rst_stream,		RST_STREAM,	0x3, 0x00,
@@ -64,6 +68,7 @@
 	0,
 	H2CE_PROTOCOL_ERROR,
 	0,
+	0,
 	0
   )
   H2_FRAME(settings,		SETTINGS,	0x4, 0x01,
@@ -71,6 +76,7 @@
 	H2CE_PROTOCOL_ERROR,		// rfc7540,l,2052,2056
 	H2CE_PROTOCOL_ERROR,
 	0,
+	0,
 	0
   )
   H2_FRAME(push_promise,	PUSH_PROMISE,	0x5, 0x0c,
@@ -78,13 +84,15 @@
 	0,
 	H2CE_PROTOCOL_ERROR,
 	0,
-	H2_F_CONTINUATION
+	H2_F_CONTINUATION,
+	H2FF_PUSH_PROMISE_END_HEADERS,	// rfc7540,l,2249,2251
   )
   H2_FRAME(ping,		PING,		0x6, 0x01,
 	0,
 	H2CE_PROTOCOL_ERROR,		// rfc7540,l,2359,2362
 	H2CE_PROTOCOL_ERROR,
 	0,
+	0,
 	0
   )
   H2_FRAME(goaway,		GOAWAY,		0x7, 0x00,
@@ -92,6 +100,7 @@
 	H2CE_PROTOCOL_ERROR,		// rfc7540,l,2432,2435
 	H2CE_PROTOCOL_ERROR,
 	0,
+	0,
 	0
   )
   H2_FRAME(window_update,	WINDOW_UPDATE,	0x8, 0x00,
@@ -99,6 +108,7 @@
 	0,
 	H2CE_PROTOCOL_ERROR,
 	0,
+	0,
 	0
   )
   H2_FRAME(continuation,	CONTINUATION,	0x9, 0x04,
@@ -106,7 +116,8 @@
 	0,
 	H2CE_PROTOCOL_ERROR,
 	0,
-	H2_F_CONTINUATION
+	H2_F_CONTINUATION,
+	H2FF_CONTINUATION_END_HEADERS	// rfc7540,l,2753,2754
   )
   #undef H2_FRAME
 #endif



More information about the varnish-commit mailing list