MEDIUM: mux-h2: check the frame validity before considering the stream state

There are some uneasy situation where it's difficult to validate a frame's
format without being in an appropriate state. This patch makes sure that
each frame passes through h2_frame_check() before being checked in the
context of the stream's state. This makes sure we can always return a GOAWAY
for protocol violations even if we can't process the frame.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index c216f50..ec5fbca 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -2170,6 +2170,8 @@
 static void h2_process_demux(struct h2c *h2c)
 {
 	struct h2s *h2s = NULL, *tmp_h2s;
+	struct h2_fh hdr;
+	unsigned int padlen = 0;
 
 	if (h2c->st0 >= H2_CS_ERROR)
 		return;
@@ -2192,8 +2194,6 @@
 		}
 
 		if (h2c->st0 == H2_CS_SETTINGS1) {
-			struct h2_fh hdr;
-
 			/* ensure that what is pending is a valid SETTINGS frame
 			 * without an ACK.
 			 */
@@ -2226,12 +2226,8 @@
 			 * a SETTINGS frame whose header has already been
 			 * deleted above.
 			 */
-			h2c->dfl = hdr.len;
-			h2c->dsi = hdr.sid;
-			h2c->dft = hdr.ft;
-			h2c->dff = hdr.ff;
-			h2c->dpl = 0;
-			h2c->st0 = H2_CS_FRAME_P;
+			padlen = 0;
+			goto new_frame;
 		}
 	}
 
@@ -2243,9 +2239,6 @@
 			break;
 
 		if (h2c->st0 == H2_CS_FRAME_H) {
-			struct h2_fh hdr;
-			unsigned int padlen = 0;
-
 			if (!h2_peek_frame_hdr(&h2c->dbuf, 0, &hdr))
 				break;
 
@@ -2294,12 +2287,22 @@
 				b_del(&h2c->dbuf, 1);
 			}
 			h2_skip_frame_hdr(&h2c->dbuf);
+
+		new_frame:
 			h2c->dfl = hdr.len;
 			h2c->dsi = hdr.sid;
 			h2c->dft = hdr.ft;
 			h2c->dff = hdr.ff;
 			h2c->dpl = padlen;
 			h2c->st0 = H2_CS_FRAME_P;
+
+			/* check for minimum basic frame format validity */
+			ret = h2_frame_check(h2c->dft, 1, h2c->dsi, h2c->dfl, global.tune.bufsize);
+			if (ret != H2_ERR_NO_ERROR) {
+				h2c_error(h2c, ret);
+				sess_log(h2c->conn->owner);
+				goto fail;
+			}
 		}
 
 		/* Only H2_CS_FRAME_P and H2_CS_FRAME_A here */