[master] d8cef06 Add transmit properties to the frame descriptors.
Poul-Henning Kamp
phk at FreeBSD.org
Mon Mar 6 16:07:06 CET 2017
commit d8cef066b37254187de0fcdc33730b443579f442
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Mar 6 11:12:27 2017 +0000
Add transmit properties to the frame descriptors.
diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h
index 1dd618e..4f9b3b0 100644
--- a/bin/varnishd/http2/cache_http2.h
+++ b/bin/varnishd/http2/cache_http2.h
@@ -30,6 +30,7 @@
struct h2_sess;
struct h2_req;
struct h2h_decode;
+struct h2_frame_s;
#include "hpack/vhp.h"
@@ -46,6 +47,8 @@ typedef const struct h2_error_s *h2_error;
typedef h2_error h2_rxframe_f(struct worker *, struct h2_sess *,
struct h2_req *);
+typedef const struct h2_frame_s *h2_frame;
+
struct h2_frame_s {
const char *name;
h2_rxframe_f *rxfunc;
@@ -54,9 +57,10 @@ struct h2_frame_s {
h2_error act_szero;
h2_error act_snonzero;
h2_error act_sidle;
+ int respect_window;
+ h2_frame continuation;
};
-typedef const struct h2_frame_s *h2_frame;
#define H2_FRAME(l,U,...) extern const struct h2_frame_s H2_F_##U[1];
#include "tbl/h2_frames.h"
@@ -167,11 +171,11 @@ 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 *,
+h2_error H2_Send_Frame(struct worker *, const struct h2_sess *,
h2_frame type, uint8_t flags, uint32_t len, uint32_t stream,
const void *);
-int H2_Send(struct worker *, struct h2_req *, int flush,
+h2_error H2_Send(struct worker *, struct h2_req *, int flush,
h2_frame type, uint8_t flags, uint32_t len, const void *);
/* cache_http2_proto.c */
diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c
index eeffae3..076cc1d 100644
--- a/bin/varnishd/http2/cache_http2_send.c
+++ b/bin/varnishd/http2/cache_http2_send.c
@@ -55,22 +55,34 @@ h2_mk_hdr(uint8_t *hdr, h2_frame ftyp, uint8_t flags,
* the session mtx must be held.
*/
-int
+h2_error
H2_Send_Frame(struct worker *wrk, const struct h2_sess *h2,
h2_frame ftyp, uint8_t flags,
uint32_t len, uint32_t stream, const void *ptr)
{
uint8_t hdr[9];
+ ssize_t s;
- Lck_AssertHeld(&h2->sess->mtx);
(void)wrk;
+ Lck_AssertHeld(&h2->sess->mtx);
+
+ AN(ftyp);
+ AZ(flags & ~(ftyp->flags));
+ if (stream == 0)
+ AZ(ftyp->act_szero);
+ else
+ AZ(ftyp->act_snonzero);
h2_mk_hdr(hdr, ftyp, flags, len, stream);
VSLb_bin(h2->vsl, SLT_H2TxHdr, 9, hdr);
- /*XXX*/(void)write(h2->sess->fd, hdr, sizeof hdr);
+ s = write(h2->sess->fd, hdr, sizeof hdr);
+ if (s != sizeof hdr)
+ return (H2CE_PROTOCOL_ERROR); // XXX Need private ?
if (len > 0) {
- /*XXX*/(void)write(h2->sess->fd, ptr, len);
+ s = write(h2->sess->fd, ptr, len);
+ if (s != len)
+ return (H2CE_PROTOCOL_ERROR); // XXX Need private ?
VSLb_bin(h2->vsl, SLT_H2TxBody, len, ptr);
}
return (0);
@@ -82,11 +94,11 @@ H2_Send_Frame(struct worker *wrk, const struct h2_sess *h2,
* XXX: priority
*/
-int
+h2_error
H2_Send(struct worker *wrk, struct h2_req *r2, int flush,
h2_frame ftyp, uint8_t flags, uint32_t len, const void *ptr)
{
- int retval;
+ h2_error retval;
struct h2_sess *h2;
uint32_t mfs, tf;
const char *p;
@@ -98,16 +110,24 @@ H2_Send(struct worker *wrk, struct h2_req *r2, int flush,
CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
assert(len == 0 || ptr != NULL);
+ AN(ftyp);
+ AZ(flags & ~(ftyp->flags));
+ if (r2->stream == 0)
+ AZ(ftyp->act_szero);
+ else
+ AZ(ftyp->act_snonzero);
+
Lck_Lock(&h2->sess->mtx);
mfs = h2->their_settings[H2S_MAX_FRAME_SIZE];
if (len < mfs) {
retval = H2_Send_Frame(wrk, h2,
ftyp, flags, len, r2->stream, ptr);
- } else if (ftyp == H2_F_DATA) {
+ } else {
AN(ptr);
AN(len);
p = ptr;
do {
+ AN(ftyp->continuation);
tf = mfs;
if (tf > len)
tf = len;
@@ -116,9 +136,8 @@ H2_Send(struct worker *wrk, struct h2_req *r2, int flush,
tf, r2->stream, p);
p += tf;
len -= tf;
- } while (len > 0);
- } else {
- INCOMPL();
+ ftyp = ftyp->continuation;
+ } while (len > 0 && retval == 0);
}
Lck_Unlock(&h2->sess->mtx);
return (retval);
diff --git a/include/tbl/h2_frames.h b/include/tbl/h2_frames.h
index 29c338f..c8eb31f 100644
--- a/include/tbl/h2_frames.h
+++ b/include/tbl/h2_frames.h
@@ -32,59 +32,81 @@
#ifdef H2_FRAME
/* lower, upper, type, flags
- * stream-zero
- * stream-nonzero
- * stream-idle
+ * rx_stream-zero
+ * rx_stream-nonzero
+ * rx_stream-idle
+ * tx_flow-control // rfc7540,l,1265,1270
+ * tx_continuation
*/
H2_FRAME(data, DATA, 0x0, 0x09,
H2CE_PROTOCOL_ERROR, // rfc7540,l,1758,1761
0,
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 1,
+ H2_F_DATA
)
H2_FRAME(headers, HEADERS, 0x1, 0x2d,
H2CE_PROTOCOL_ERROR, // rfc7540,l,1876,1879
0,
- 0 // rfc7540,l,938,940
+ 0, // rfc7540,l,938,940
+ 0,
+ H2_F_CONTINUATION
)
H2_FRAME(priority, PRIORITY, 0x2, 0x00,
H2CE_PROTOCOL_ERROR, // rfc7540,l,1933,1936
0,
- 0 // rfc7540,l,938,940
+ 0, // rfc7540,l,938,940
+ 0,
+ 0
)
H2_FRAME(rst_stream, RST_STREAM, 0x3, 0x00,
H2CE_PROTOCOL_ERROR, // rfc7540,l,1993,1996
0,
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 0,
+ 0
)
H2_FRAME(settings, SETTINGS, 0x4, 0x01,
0,
H2CE_PROTOCOL_ERROR, // rfc7540,l,2052,2056
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 0,
+ 0
)
H2_FRAME(push_promise, PUSH_PROMISE, 0x5, 0x0c,
H2CE_PROTOCOL_ERROR, // rfc7540,l,2262,2263
0,
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 0,
+ H2_F_CONTINUATION
)
H2_FRAME(ping, PING, 0x6, 0x01,
0,
H2CE_PROTOCOL_ERROR, // rfc7540,l,2359,2362
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 0,
+ 0
)
H2_FRAME(goaway, GOAWAY, 0x7, 0x00,
0,
H2CE_PROTOCOL_ERROR, // rfc7540,l,2432,2435
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 0,
+ 0
)
H2_FRAME(window_update, WINDOW_UPDATE, 0x8, 0x00,
0,
0,
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 0,
+ 0
)
H2_FRAME(continuation, CONTINUATION, 0x9, 0x04,
H2CE_PROTOCOL_ERROR, // rfc7540,l,2764,2767
0,
- H2CE_PROTOCOL_ERROR
+ H2CE_PROTOCOL_ERROR,
+ 0,
+ H2_F_CONTINUATION
)
#undef H2_FRAME
#endif
More information about the varnish-commit
mailing list