[master] 05d91face http2: New send_goaway flag for errors

Simon Stridsberg simon.stridsberg at varnish-software.com
Mon Mar 18 18:32:08 UTC 2024


commit 05d91face09ba76b5fc1cec9e13cbf2859cb7e3d
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Thu Nov 16 17:27:11 2023 +0100

    http2: New send_goaway flag for errors

diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h
index 95550c080..126a70d3a 100644
--- a/bin/varnishd/http2/cache_http2.h
+++ b/bin/varnishd/http2/cache_http2.h
@@ -44,16 +44,18 @@ struct h2_error_s {
 	uint32_t			val;
 	int				stream;
 	int				connection;
+	int				send_goaway;
 	stream_close_t			reason;
 };
 
 typedef const struct h2_error_s *h2_error;
 
 #define H2_CUSTOM_ERRORS
-#define H2EC1(U,v,r,d) extern const struct h2_error_s H2CE_##U[1];
-#define H2EC2(U,v,r,d) extern const struct h2_error_s H2SE_##U[1];
-#define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d)
-#define H2_ERROR(NAME, val, sc, reason, desc) H2EC##sc(NAME, val, reason, desc)
+#define H2EC1(U,v,g,r,d) extern const struct h2_error_s H2CE_##U[1];
+#define H2EC2(U,v,g,r,d) extern const struct h2_error_s H2SE_##U[1];
+#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
+#define H2_ERROR(NAME, val, sc, goaway, reason, desc)	\
+	H2EC##sc(NAME, val, goaway, reason, desc)
 #include "tbl/h2_error.h"
 #undef H2EC1
 #undef H2EC2
diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index 1568e76bc..b9d03d47c 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -47,10 +47,13 @@
 #include "vtim.h"
 
 #define H2_CUSTOM_ERRORS
-#define H2EC1(U,v,r,d) const struct h2_error_s H2CE_##U[1] = {{#U,d,v,0,1,r}};
-#define H2EC2(U,v,r,d) const struct h2_error_s H2SE_##U[1] = {{#U,d,v,1,0,r}};
-#define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d)
-#define H2_ERROR(NAME, val, sc, reason, desc) H2EC##sc(NAME, val, reason, desc)
+#define H2EC1(U,v,g,r,d)	\
+	const struct h2_error_s H2CE_##U[1] = {{#U,d,v,0,1,g,r}};
+#define H2EC2(U,v,g,r,d)	\
+	const struct h2_error_s H2SE_##U[1] = {{#U,d,v,1,0,g,r}};
+#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
+#define H2_ERROR(NAME, val, sc, goaway, reason, desc)	\
+	H2EC##sc(NAME, val, goaway, reason, desc)
 #include "tbl/h2_error.h"
 #undef H2EC1
 #undef H2EC2
@@ -62,6 +65,7 @@ static const struct h2_error_s H2NN_ERROR[1] = {{
 	0xffffffff,
 	1,
 	1,
+	0,
 	SC_RX_JUNK
 }};
 
@@ -89,10 +93,11 @@ h2_framename(enum h2frame h2f)
  */
 
 static const h2_error stream_errors[] = {
-#define H2EC1(U,v,r,d)
-#define H2EC2(U,v,r,d) [v] = H2SE_##U,
-#define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d)
-#define H2_ERROR(NAME, val, sc, reason, desc) H2EC##sc(NAME, val, reason, desc)
+#define H2EC1(U,v,g,r,d)
+#define H2EC2(U,v,g,r,d) [v] = H2SE_##U,
+#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
+#define H2_ERROR(NAME, val, sc, goaway, reason, desc)	\
+	H2EC##sc(NAME, val, goaway, reason, desc)
 #include "tbl/h2_error.h"
 #undef H2EC1
 #undef H2EC2
@@ -114,10 +119,11 @@ h2_streamerror(uint32_t u)
  */
 
 static const h2_error conn_errors[] = {
-#define H2EC1(U,v,r,d) [v] = H2CE_##U,
-#define H2EC2(U,v,r,d)
-#define H2EC3(U,v,r,d) H2EC1(U,v,r,d) H2EC2(U,v,r,d)
-#define H2_ERROR(NAME, val, sc, reason, desc) H2EC##sc(NAME, val, reason, desc)
+#define H2EC1(U,v,g,r,d) [v] = H2CE_##U,
+#define H2EC2(U,v,g,r,d)
+#define H2EC3(U,v,g,r,d) H2EC1(U,v,g,r,d) H2EC2(U,v,g,r,d)
+#define H2_ERROR(NAME, val, sc, goaway, reason, desc)	\
+	H2EC##sc(NAME, val, goaway, reason, desc)
 #include "tbl/h2_error.h"
 #undef H2EC1
 #undef H2EC2
@@ -1320,6 +1326,10 @@ h2_stream_tmo(struct h2_sess *h2, const struct h2_req *r2, vtim_real now)
 	if (isnan(now))
 		AN(r2->t_winupd);
 
+	if (h2->error != NULL && h2->error->connection &&
+	    !h2->error->send_goaway)
+		return (h2->error);
+
 	if (r2->t_winupd == 0 && r2->t_send == 0)
 		return (NULL);
 
diff --git a/bin/varnishtest/vtc_http2.c b/bin/varnishtest/vtc_http2.c
index 0361b9e1a..93c7d6508 100644
--- a/bin/varnishtest/vtc_http2.c
+++ b/bin/varnishtest/vtc_http2.c
@@ -52,7 +52,7 @@
 #define BUF_SIZE	(1024*2048)
 
 static const char *const h2_errs[] = {
-#define H2_ERROR(n,v,sc,r,t) [v] = #n,
+#define H2_ERROR(n,v,sc,g,r,t) [v] = #n,
 #include <tbl/h2_error.h>
 	NULL
 };
@@ -1260,7 +1260,7 @@ cmd_var_resolve(const struct stream *s, const char *spec, char *buf)
 		else
 			return (NULL);
 	}
-#define H2_ERROR(U,v,sc,r,t) \
+#define H2_ERROR(U,v,sc,g,r,t) \
 	if (!strcmp(spec, #U)) { return (#v); }
 #include "tbl/h2_error.h"
 	return (spec);
diff --git a/include/tbl/h2_error.h b/include/tbl/h2_error.h
index 564d78544..f4dc5ca2c 100644
--- a/include/tbl/h2_error.h
+++ b/include/tbl/h2_error.h
@@ -39,6 +39,7 @@ H2_ERROR(
 	/* name */	NO_ERROR,
 	/* val */	0,
 	/* types */	3,
+	/* goaway */	1,
 	/* reason */	SC_REM_CLOSE,
 	/* descr */	"Graceful shutdown"
 )
@@ -47,6 +48,7 @@ H2_ERROR(
 	/* name */	PROTOCOL_ERROR,
 	/* val */	1,
 	/* types */	3,
+	/* goaway */	1,
 	/* reason */	SC_RX_JUNK,
 	/* descr */	"Protocol error detected"
 )
@@ -55,6 +57,7 @@ H2_ERROR(
 	/* name */	INTERNAL_ERROR,
 	/* val */	2,
 	/* types */	3,
+	/* goaway */	1,
 	/* reason */	SC_VCL_FAILURE,
 	/* descr */	"Implementation fault"
 )
@@ -63,6 +66,7 @@ H2_ERROR(
 	/* name */	FLOW_CONTROL_ERROR,
 	/* val */	3,
 	/* types */	3,
+	/* goaway */	1,
 	/* reason */	SC_OVERLOAD,
 	/* descr */	"Flow-control limits exceeded"
 )
@@ -71,6 +75,7 @@ H2_ERROR(
 	/* name */	SETTINGS_TIMEOUT,
 	/* val */	4,
 	/* types */	1,
+	/* goaway */	1,
 	/* reason */	SC_RX_TIMEOUT,
 	/* descr */	"Settings not acknowledged"
 )
@@ -79,6 +84,7 @@ H2_ERROR(
 	/* name */	STREAM_CLOSED,
 	/* val */	5,
 	/* types */	2,
+	/* goaway */	1,
 	/* reason */	SC_NULL,
 	/* descr */	"Frame received for closed stream"
 )
@@ -87,6 +93,7 @@ H2_ERROR(
 	/* name */	FRAME_SIZE_ERROR,
 	/* val */	6,
 	/* types */	3,
+	/* goaway */	1,
 	/* reason */	SC_RX_JUNK,
 	/* descr */	"Frame size incorrect"
 )
@@ -95,6 +102,7 @@ H2_ERROR(
 	/* name */	REFUSED_STREAM,
 	/* val */	7,
 	/* types */	2,
+	/* goaway */	1,
 	/* reason */	SC_NULL,
 	/* descr */	"Stream not processed"
 )
@@ -103,6 +111,7 @@ H2_ERROR(
 	/* name */	CANCEL,
 	/* val */	8,
 	/* types */	2,
+	/* goaway */	1,
 	/* reason */	SC_NULL,
 	/* descr */	"Stream cancelled"
 )
@@ -111,6 +120,7 @@ H2_ERROR(
 	/* name */	COMPRESSION_ERROR,
 	/* val */	9,
 	/* types */	1,
+	/* goaway */	1,
 	/* reason */	SC_RX_JUNK,
 	/* descr */	"Compression state not updated"
 )
@@ -119,6 +129,7 @@ H2_ERROR(
 	/* name */	CONNECT_ERROR,
 	/* val */	10,
 	/* types */	2,
+	/* goaway */	1,
 	/* reason */	SC_NULL,
 	/* descr */	"TCP connection error for CONNECT method"
 )
@@ -127,6 +138,7 @@ H2_ERROR(
 	/* name */	ENHANCE_YOUR_CALM,
 	/* val */	11,
 	/* types */	3,
+	/* goaway */	1,
 	/* reason */	SC_OVERLOAD,
 	/* descr */	"Processing capacity exceeded"
 )
@@ -135,6 +147,7 @@ H2_ERROR(
 	/* name */	INADEQUATE_SECURITY,
 	/* val */	12,
 	/* types */	1,
+	/* goaway */	1,
 	/* reason */	SC_RX_JUNK,
 	/* descr */	"Negotiated TLS parameters not acceptable"
 )
@@ -143,31 +156,35 @@ H2_ERROR(
 	/* name */	HTTP_1_1_REQUIRED,
 	/* val */	13,
 	/* types */	1,
+	/* goaway */	1,
 	/* reason */	SC_REQ_HTTP20,
 	/* descr */	"Use HTTP/1.1 for the request"
 )
 
 #ifdef H2_CUSTOM_ERRORS
 H2_ERROR(
-       /* name */      RAPID_RESET,
-       /* val */       11, /* ENHANCE_YOUR_CALM */
-       /* types */     1,
-       /* reason */    SC_RAPID_RESET,
-       /* descr */     "http/2 rapid reset detected"
+	/* name */	RAPID_RESET,
+	/* val */	11, /* ENHANCE_YOUR_CALM */
+	/* types */	1,
+	/* goaway */	1,
+	/* reason */	SC_RAPID_RESET,
+	/* descr */	"http/2 rapid reset detected"
 )
 
 H2_ERROR(
-       /* name */      MISSING_SCHEME,
-       /* val */       1, /* PROTOCOL_ERROR */
-       /* types */     2,
-       /* reason */    SC_NULL,
-       /* descr */     "Missing :scheme pseudo-header"
+	/* name */	MISSING_SCHEME,
+	/* val */	1, /* PROTOCOL_ERROR */
+	/* types */	2,
+	/* goaway */	1,
+	/* reason */	SC_NULL,
+	/* descr */	"Missing :scheme pseudo-header"
 )
 
 H2_ERROR(
 	/* name */	BROKE_WINDOW,
 	/* val */	8, /* CANCEL */
 	/* types */	2,
+	/* goaway */	0,
 	/* reason */	SC_NULL,
 	/* descr */	"http/2 stream out of window credits"
 )
@@ -176,6 +193,7 @@ H2_ERROR(
 	/* name */	BANKRUPT,
 	/* val */	11, /* ENHANCE_YOUR_CALM */
 	/* types */	1,
+	/* goaway */	0,
 	/* reason */	SC_BANKRUPT,
 	/* descr */	"http/2 bankrupt connection"
 )


More information about the varnish-commit mailing list