Permalink
Browse files

Start working on systematic error handling

  • Loading branch information...
1 parent b167b52 commit 9a13765b824301e8de10bae1a0309e6992a64f5c @bsdphk bsdphk committed Feb 17, 2017
Showing with 51 additions and 37 deletions.
  1. +51 −37 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,20 +546,53 @@ 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];
AN(h2f->name);
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);
}

0 comments on commit 9a13765

Please sign in to comment.