Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
a62435b3
Commit
a62435b3
authored
Feb 16, 2017
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce a selfdescribing h2_error struct
parent
3f46e4f8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
58 additions
and
42 deletions
+58
-42
cache_http2.h
bin/varnishd/http2/cache_http2.h
+21
-8
cache_http2_hpack.c
bin/varnishd/http2/cache_http2_hpack.c
+21
-21
cache_http2_proto.c
bin/varnishd/http2/cache_http2_proto.c
+15
-12
h2_error.h
include/tbl/h2_error.h
+1
-1
No files found.
bin/varnishd/http2/cache_http2.h
View file @
a62435b3
...
...
@@ -31,13 +31,26 @@ struct h2_sess;
#include "hpack/vhp.h"
enum
h2_error_e
{
H2E__DUMMY
=
-
1
,
#define H2_ERROR(NAME, val, sc, desc) \
H2E_##NAME = val,
#include "tbl/h2_error.h"
struct
h2_error_s
{
const
char
*
name
;
const
char
*
txt
;
uint32_t
val
;
int
stream
;
int
connection
;
};
typedef
const
struct
h2_error_s
*
h2_error
;
#define H2EC0(U,v,d)
#define H2EC1(U,v,d) extern const struct h2_error_s H2E_C_##U[1];
#define H2EC2(U,v,d) extern const struct h2_error_s H2E_S_##U[1];
#define H2EC3(U,v,d) H2EC1(U,v,d) H2EC2(U,v,d)
#define H2_ERROR(NAME, val, sc, desc) H2EC##sc(NAME, val, desc)
#include "tbl/h2_error.h"
#undef H2EC1
#undef H2EC2
#undef H2EC3
enum
h2_frame_e
{
H2_FRAME__DUMMY
=
-
1
,
#define H2_FRAME(l,u,t,f) H2_FRAME_##u = t,
...
...
@@ -118,7 +131,7 @@ struct h2h_decode {
unsigned
magic
;
#define H2H_DECODE_MAGIC 0xd092bde4
int
error
;
h2_error
error
;
enum
vhd_ret_e
vhd_ret
;
char
*
out
;
char
*
reset
;
...
...
@@ -129,8 +142,8 @@ struct h2h_decode {
};
void
h2h_decode_init
(
const
struct
h2_sess
*
h2
,
struct
h2h_decode
*
d
);
int
h2h_decode_fini
(
const
struct
h2_sess
*
h2
,
struct
h2h_decode
*
d
);
int
h2h_decode_bytes
(
struct
h2_sess
*
h2
,
struct
h2h_decode
*
d
,
h2_error
h2h_decode_fini
(
const
struct
h2_sess
*
h2
,
struct
h2h_decode
*
d
);
h2_error
h2h_decode_bytes
(
struct
h2_sess
*
h2
,
struct
h2h_decode
*
d
,
const
uint8_t
*
ptr
,
size_t
len
);
int
H2_Send_Frame
(
struct
worker
*
,
const
struct
h2_sess
*
,
...
...
bin/varnishd/http2/cache_http2_hpack.c
View file @
a62435b3
...
...
@@ -37,7 +37,7 @@
#include "http2/cache_http2.h"
#include "vct.h"
static
int
static
h2_error
h2h_checkhdr
(
const
struct
http
*
hp
,
const
char
*
b
,
size_t
namelen
,
size_t
len
)
{
const
char
*
p
;
...
...
@@ -49,7 +49,7 @@ h2h_checkhdr(const struct http *hp, const char *b, size_t namelen, size_t len)
if
(
namelen
==
2
)
{
VSLb
(
hp
->
vsl
,
SLT_BogoHeader
,
"Empty name"
);
return
(
H2E_PROTOCOL_ERROR
);
return
(
H2E_
C_
PROTOCOL_ERROR
);
}
for
(
p
=
b
;
p
<
b
+
len
;
p
++
)
{
...
...
@@ -64,7 +64,7 @@ h2h_checkhdr(const struct http *hp, const char *b, size_t namelen, size_t len)
VSLb
(
hp
->
vsl
,
SLT_BogoHeader
,
"Illegal header name: %.*s"
,
(
int
)(
len
>
20
?
20
:
len
),
b
);
return
(
H2E_PROTOCOL_ERROR
);
return
(
H2E_
C_
PROTOCOL_ERROR
);
}
else
if
(
p
<
b
+
namelen
)
{
/* ': ' added by us */
assert
(
*
p
==
':'
||
*
p
==
' '
);
...
...
@@ -75,14 +75,14 @@ h2h_checkhdr(const struct http *hp, const char *b, size_t namelen, size_t len)
VSLb
(
hp
->
vsl
,
SLT_BogoHeader
,
"Illegal header value: %.*s"
,
(
int
)(
len
>
20
?
20
:
len
),
b
);
return
(
H2E_PROTOCOL_ERROR
);
return
(
H2E_
C_
PROTOCOL_ERROR
);
}
}
return
(
0
);
}
static
int
static
h2_error
h2h_addhdr
(
struct
http
*
hp
,
char
*
b
,
size_t
namelen
,
size_t
len
)
{
/* XXX: This might belong in cache/cache_http.c */
...
...
@@ -95,7 +95,7 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len)
if
(
len
>
UINT_MAX
)
{
/* XXX: cache_param max header size */
VSLb
(
hp
->
vsl
,
SLT_BogoHeader
,
"Header too large: %.20s"
,
b
);
return
(
H2E_ENHANCE_YOUR_CALM
);
return
(
H2E_
S_
ENHANCE_YOUR_CALM
);
}
if
(
b
[
0
]
==
':'
)
{
...
...
@@ -127,7 +127,7 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len)
VSLb
(
hp
->
vsl
,
SLT_BogoHeader
,
"Unknown pseudo-header: %.*s"
,
(
int
)(
len
>
20
?
20
:
len
),
b
);
return
(
H2E_PROTOCOL_ERROR
);
return
(
H2E_
S_
PROTOCOL_ERROR
);
}
}
else
n
=
hp
->
nhd
;
...
...
@@ -138,14 +138,14 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len)
VSLb
(
hp
->
vsl
,
SLT_BogoHeader
,
"Duplicate pseudo-header: %.*s"
,
(
int
)(
len
>
20
?
20
:
len
),
b
);
return
(
H2E_PROTOCOL_ERROR
);
return
(
H2E_
S_
PROTOCOL_ERROR
);
}
}
else
{
/* Check for space in struct http */
if
(
n
>=
hp
->
shd
)
{
VSLb
(
hp
->
vsl
,
SLT_LostHeader
,
"Too many headers: %.*s"
,
(
int
)(
len
>
20
?
20
:
len
),
b
);
return
(
H2E_ENHANCE_YOUR_CALM
);
return
(
H2E_
S_
ENHANCE_YOUR_CALM
);
}
hp
->
nhd
++
;
}
...
...
@@ -181,10 +181,10 @@ h2h_decode_init(const struct h2_sess *h2, struct h2h_decode *d)
* H2E_ENHANCE_YOUR_CALM: Ran out of workspace or http header space. This
* is a stream level error.
*/
int
h2_error
h2h_decode_fini
(
const
struct
h2_sess
*
h2
,
struct
h2h_decode
*
d
)
{
int
ret
;
h2_error
ret
;
CHECK_OBJ_NOTNULL
(
h2
,
H2_SESS_MAGIC
);
CHECK_OBJ_NOTNULL
(
h2
->
new_req
,
REQ_MAGIC
);
...
...
@@ -195,7 +195,7 @@ h2h_decode_fini(const struct h2_sess *h2, struct h2h_decode *d)
boundary */
VSLb
(
h2
->
new_req
->
http
->
vsl
,
SLT_BogoHeader
,
"HPACK compression error (%s)"
,
VHD_Error
(
d
->
vhd_ret
));
ret
=
H2E_COMPRESSION_ERROR
;
ret
=
H2E_C
_C
OMPRESSION_ERROR
;
}
else
ret
=
d
->
error
;
d
->
magic
=
0
;
...
...
@@ -209,7 +209,7 @@ h2h_decode_fini(const struct h2_sess *h2, struct h2h_decode *d)
*
* H2E_PROTOCOL_ERROR: Malformed header or duplicate pseudo-header.
*/
int
h2_error
h2h_decode_bytes
(
struct
h2_sess
*
h2
,
struct
h2h_decode
*
d
,
const
uint8_t
*
in
,
size_t
in_l
)
{
...
...
@@ -227,7 +227,7 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d,
/* Only H2E_ENHANCE_YOUR_CALM indicates that we should continue
processing. Other errors should have been returned and handled
by the caller. */
assert
(
d
->
error
==
0
||
d
->
error
==
H2E_ENHANCE_YOUR_CALM
);
assert
(
d
->
error
==
0
||
d
->
error
==
H2E_
S_
ENHANCE_YOUR_CALM
);
while
(
1
)
{
AN
(
d
->
out
);
...
...
@@ -239,14 +239,14 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d,
VSLb
(
hp
->
vsl
,
SLT_BogoHeader
,
"HPACK compression error (%s)"
,
VHD_Error
(
d
->
vhd_ret
));
d
->
error
=
H2E_COMPRESSION_ERROR
;
d
->
error
=
H2E_C
_C
OMPRESSION_ERROR
;
break
;
}
else
if
(
d
->
vhd_ret
==
VHD_OK
||
d
->
vhd_ret
==
VHD_MORE
)
{
assert
(
in_u
==
in_l
);
break
;
}
if
(
d
->
error
==
H2E_ENHANCE_YOUR_CALM
)
{
if
(
d
->
error
==
H2E_
S_
ENHANCE_YOUR_CALM
)
{
d
->
out_u
=
0
;
assert
(
d
->
out_u
<
d
->
out_l
);
continue
;
...
...
@@ -258,7 +258,7 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d,
case
VHD_NAME
:
assert
(
d
->
namelen
==
0
);
if
(
d
->
out_l
-
d
->
out_u
<
2
)
{
d
->
error
=
H2E_ENHANCE_YOUR_CALM
;
d
->
error
=
H2E_
S_
ENHANCE_YOUR_CALM
;
break
;
}
d
->
out
[
d
->
out_u
++
]
=
':'
;
...
...
@@ -271,7 +271,7 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d,
case
VHD_VALUE
:
assert
(
d
->
namelen
>
0
);
if
(
d
->
out_l
-
d
->
out_u
<
1
)
{
d
->
error
=
H2E_ENHANCE_YOUR_CALM
;
d
->
error
=
H2E_
S_
ENHANCE_YOUR_CALM
;
break
;
}
d
->
error
=
h2h_checkhdr
(
hp
,
d
->
out
,
d
->
namelen
,
...
...
@@ -289,7 +289,7 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d,
break
;
case
VHD_BUF
:
d
->
error
=
H2E_ENHANCE_YOUR_CALM
;
d
->
error
=
H2E_
S_
ENHANCE_YOUR_CALM
;
break
;
default:
...
...
@@ -297,7 +297,7 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d,
break
;
}
if
(
d
->
error
==
H2E_ENHANCE_YOUR_CALM
)
{
if
(
d
->
error
==
H2E_
S_
ENHANCE_YOUR_CALM
)
{
http_Teardown
(
hp
);
d
->
out
=
d
->
reset
;
d
->
out_l
=
hp
->
ws
->
r
-
d
->
out
;
...
...
@@ -307,7 +307,7 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d,
break
;
}
if
(
d
->
error
==
H2E_ENHANCE_YOUR_CALM
)
if
(
d
->
error
==
H2E_
S_
ENHANCE_YOUR_CALM
)
return
(
0
);
/* Stream error, delay reporting until
h2h_decode_fini so that we can process the
complete header block */
...
...
bin/varnishd/http2/cache_http2_proto.c
View file @
a62435b3
...
...
@@ -40,6 +40,16 @@
#include "vtcp.h"
#include "vtim.h"
#define H2EC0(U,v,d)
#define H2EC1(U,v,d) const struct h2_error_s H2E_C_##U[1] = {{#U,d,v,0,1}};
#define H2EC2(U,v,d) const struct h2_error_s H2E_S_##U[1] = {{#U,d,v,1,0}};
#define H2EC3(U,v,d) H2EC1(U,v,d) H2EC2(U,v,d)
#define H2_ERROR(NAME, val, sc, desc) H2EC##sc(NAME, val, desc)
#include "tbl/h2_error.h"
#undef H2EC1
#undef H2EC2
#undef H2EC3
enum
h2frame
{
#define H2_FRAME(l,u,t,f) H2F_##u = t,
#include "tbl/h2_frames.h"
...
...
@@ -189,7 +199,7 @@ h2_new_req(const struct worker *wrk, struct h2_sess *h2,
}
static
void
h2_del_req
(
struct
worker
*
wrk
,
struct
h2_req
*
r2
,
enum
h2_error_e
err
)
h2_del_req
(
struct
worker
*
wrk
,
struct
h2_req
*
r2
,
h2_error
err
)
{
struct
h2_sess
*
h2
;
struct
sess
*
sp
;
...
...
@@ -384,7 +394,7 @@ h2_do_req(struct worker *wrk, void *priv)
VSL
(
SLT_Debug
,
0
,
"H2REQ CNT done"
);
/* XXX clean up req */
r2
->
state
=
H2_S_CLOSED
;
h2_del_req
(
wrk
,
r2
,
H2E_NO_ERROR
);
h2_del_req
(
wrk
,
r2
,
H2E_
S_
NO_ERROR
);
}
void
__match_proto__
(
h2_frame_f
)
...
...
@@ -394,7 +404,6 @@ h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
struct
h2h_decode
d
[
1
];
const
uint8_t
*
p
;
size_t
l
;
int
i
;
/* XXX: This still lacks support for CONTINUATION frames, half
* read frames and proper error handling.
...
...
@@ -436,14 +445,8 @@ h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
p
+=
5
;
l
-=
5
;
}
i
=
h2h_decode_bytes
(
h2
,
d
,
p
,
l
);
if
(
i
)
VSLb
(
h2
->
vsl
,
SLT_Debug
,
"H2H_decode_bytes = %d"
,
i
);
XXXAZ
(
i
);
i
=
h2h_decode_fini
(
h2
,
d
);
if
(
i
)
VSLb
(
h2
->
vsl
,
SLT_Debug
,
"H2H_decode_fini = %d"
,
i
);
XXXAZ
(
i
);
XXXAZ
(
h2h_decode_bytes
(
h2
,
d
,
p
,
l
));
XXXAZ
(
h2h_decode_fini
(
h2
,
d
));
VSLb_ts_req
(
req
,
"Req"
,
req
->
t_req
);
http_SetH
(
req
->
http
,
HTTP_HDR_PROTO
,
"HTTP/2.0"
);
...
...
@@ -762,7 +765,7 @@ h2_new_session(struct worker *wrk, void *arg)
/* Delete all idle streams */
VTAILQ_FOREACH_SAFE
(
r2
,
&
h2
->
streams
,
list
,
r22
)
{
if
(
r2
->
state
==
H2_S_IDLE
)
h2_del_req
(
wrk
,
r2
,
H2E_NO_ERROR
);
h2_del_req
(
wrk
,
r2
,
H2E_
S_
NO_ERROR
);
}
}
...
...
include/tbl/h2_error.h
View file @
a62435b3
...
...
@@ -32,7 +32,7 @@
/*lint -save -e525 -e539 */
H2_ERROR
(
NO_ERROR
,
0x0
,
0
,
"Graceful shutdown"
)
H2_ERROR
(
NO_ERROR
,
0x0
,
3
,
"Graceful shutdown"
)
H2_ERROR
(
PROTOCOL_ERROR
,
0x1
,
3
,
"Protocol error detected"
)
H2_ERROR
(
INTERNAL_ERROR
,
0x2
,
3
,
"Implementation fault"
)
H2_ERROR
(
FLOW_CONTROL_ERROR
,
0x3
,
3
,
"Flow-control limits exceeded"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment