[master] 9a13765 Start working on systematic error handling

Poul-Henning Kamp phk at FreeBSD.org
Fri Feb 17 12:36:06 CET 2017


commit 9a13765b824301e8de10bae1a0309e6992a64f5c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Feb 17 09:29:31 2017 +0000

    Start working on systematic error handling

diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index b647262..0ad87ed 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -299,10 +299,13 @@ h2_vsl_frame(const struct h2_sess *h2, const void *ptr, size_t len)
 h2_error __match_proto__(h2_frame_f)
 h2_rx_ping(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
 {
+
 	(void)r2;
-	xxxassert(h2->rxf_len == 8);
-	xxxassert(h2->rxf_flags == 0);
-	xxxassert(h2->rxf_stream == 0);
+	if (h2->rxf_len != 8)
+		return (H2CE_FRAME_SIZE_ERROR);
+	if (h2->rxf_stream != 0)
+		return (H2CE_PROTOCOL_ERROR);
+	xxxassert(h2->rxf_flags == 0);	// XXX: we never send pings
 	H2_Send_Frame(wrk, h2,
 	    H2_FRAME_PING, H2FF_PING_ACK, 8, 0, h2->rxf_data);
 	return (0);
@@ -332,11 +335,14 @@ h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
 
 	(void)wrk;
 	Lck_AssertHeld(&h2->sess->mtx);
-	xxxassert(h2->rxf_len == 4);		// conn FRAME_SIZE_ERROR
-	wu = vbe32dec(h2->rxf_data);
-	xxxassert(wu != 0);			// stream PROTOCOL_ERROR
+	if (h2->rxf_len != 4)
+		return (H2CE_FRAME_SIZE_ERROR);
+	wu = vbe32dec(h2->rxf_data) & ~(1LU<<31);
+	if (wu == 0)
+		return (H2SE_PROTOCOL_ERROR);
 	r2->window += wu;
-	xxxassert(r2->window < (1LLU<<32));	// FLOW_CONTROL_ERROR
+	if (r2->window >= (1LLU << 31))
+		return (H2SE_FLOW_CONTROL_ERROR);
 	return (0);
 }
 
@@ -514,45 +520,20 @@ static const struct h2flist_s h2flist[] = {
 
 #define H2FMAX (sizeof(h2flist) / sizeof(h2flist[0]))
 
-static int
-h2_rxframe(struct worker *wrk, struct h2_sess *h2)
+static h2_error
+h2_procframe(struct worker *wrk, struct h2_sess *h2)
 {
-	enum htc_status_e hs;
 	struct h2_req *r2 = NULL;
 	const struct h2flist_s *h2f;
-
-	(void)VTCP_blocking(*h2->htc->rfd);
-	h2->sess->t_idle = VTIM_real();
-	hs = HTC_RxStuff(h2->htc, h2_frame_complete,
-	    NULL, NULL, NAN,
-	    h2->sess->t_idle + cache_param->timeout_idle + 100,
-	    1024);
-	if (hs != HTC_S_COMPLETE) {
-		Lck_Lock(&h2->sess->mtx);
-		VSLb(h2->vsl, SLT_Debug, "H2: No frame (hs=%d)", hs);
-		Lck_Unlock(&h2->sess->mtx);
-		return (0);
-	}
-
-	h2->rxf_len =  vbe32dec(h2->htc->rxbuf_b) >> 8;
-	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);
-	/* XXX: later full DATA will not be rx'ed yet. */
-	HTC_RxPipeline(h2->htc, h2->htc->rxbuf_b + h2->rxf_len + 9);
-
-	h2_vsl_frame(h2, h2->htc->rxbuf_b, 9L + h2->rxf_len);
+	h2_error h2e;
 
 	if (h2->rxf_stream != 0 && !(h2->rxf_stream & 1)) {
 		/* We don't do push, so all streams must be zero or odd# */
-		Lck_Lock(&h2->sess->mtx);
 		VSLb(h2->vsl, SLT_Debug, "H2: illegal stream (=%u)",
 		    h2->rxf_stream);
-		Lck_Unlock(&h2->sess->mtx);
 		return (0);
 	}
 
-	Lck_Lock(&h2->sess->mtx);
 	VTAILQ_FOREACH(r2, &h2->streams, list)
 		if (r2->stream == h2->rxf_stream)
 			break;
@@ -565,7 +546,6 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2)
 	if (h2->htc->rxbuf_b[3] >= H2FMAX) {
 		VSLb(h2->vsl, SLT_Debug,
 		    "H2: Unknown Frame %d", h2->htc->rxbuf_b[3]);
-		Lck_Unlock(&h2->sess->mtx);
 		return (0);
 	}
 	h2f = h2flist + h2->htc->rxbuf_b[3];
@@ -573,12 +553,46 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2)
 	if (h2->rxf_flags & ~h2f->flags) {
 		VSLb(h2->vsl, SLT_Debug, "H2: Bad flags 0x%02x on %s",
 		    h2->rxf_flags, h2f->name);
+		return (0);
+	}
+	h2e = h2f->func(wrk, h2, r2);
+	XXXAZ(h2e);
+	return (0);
+}
+
+static int
+h2_rxframe(struct worker *wrk, struct h2_sess *h2)
+{
+	enum htc_status_e hs;
+	h2_error h2e;
+
+	(void)VTCP_blocking(*h2->htc->rfd);
+	h2->sess->t_idle = VTIM_real();
+	hs = HTC_RxStuff(h2->htc, h2_frame_complete,
+	    NULL, NULL, NAN,
+	    h2->sess->t_idle + cache_param->timeout_idle + 100,
+	    1024);
+	if (hs != HTC_S_COMPLETE) {
+		Lck_Lock(&h2->sess->mtx);
+		VSLb(h2->vsl, SLT_Debug, "H2: No frame (hs=%d)", hs);
 		Lck_Unlock(&h2->sess->mtx);
 		return (0);
 	}
-	(void)h2f->func(wrk, h2, r2);
 
+	h2->rxf_len =  vbe32dec(h2->htc->rxbuf_b) >> 8;
+	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);
+	/* XXX: later full DATA will not be rx'ed yet. */
+	HTC_RxPipeline(h2->htc, h2->htc->rxbuf_b + h2->rxf_len + 9);
+
+	h2_vsl_frame(h2, h2->htc->rxbuf_b, 9L + h2->rxf_len);
+
+	Lck_Lock(&h2->sess->mtx);
+	h2e = h2_procframe(wrk, h2);
 	Lck_Unlock(&h2->sess->mtx);
+	if (h2e)
+		return (0);
 	return (1);
 }
 



More information about the varnish-commit mailing list