aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/transport')
-rw-r--r--src/core/transport/chttp2/frame_data.c4
-rw-r--r--src/core/transport/chttp2/parsing.c7
-rw-r--r--src/core/transport/chttp2/stream_encoder.c12
-rw-r--r--src/core/transport/chttp2/stream_lists.c2
-rw-r--r--src/core/transport/chttp2/stream_map.c3
-rw-r--r--src/core/transport/chttp2/writing.c29
-rw-r--r--src/core/transport/chttp2_transport.c22
-rw-r--r--src/core/transport/metadata.c37
-rw-r--r--src/core/transport/metadata.h6
-rw-r--r--src/core/transport/stream_op.c6
10 files changed, 83 insertions, 45 deletions
diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c
index 40bf2ebd79..474c3d5ee6 100644
--- a/src/core/transport/chttp2/frame_data.c
+++ b/src/core/transport/chttp2/frame_data.c
@@ -92,10 +92,10 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
p->frame_type = *cur;
switch (p->frame_type) {
case 0:
- p->is_frame_compressed = 0; /* GPR_FALSE */
+ p->is_frame_compressed = 0; /* GPR_FALSE */
break;
case 1:
- p->is_frame_compressed = 1; /* GPR_TRUE */
+ p->is_frame_compressed = 1; /* GPR_TRUE */
break;
default:
gpr_log(GPR_ERROR, "Bad GRPC frame type 0x%02x", p->frame_type);
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index d84960009b..dc5eb18e42 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -177,10 +177,9 @@ void grpc_chttp2_publish_reads(
"parsed", transport_parsing, stream_global, max_recv_bytes,
-(gpr_int64)stream_parsing->incoming_window_delta);
stream_global->incoming_window -= stream_parsing->incoming_window_delta;
- GPR_ASSERT(stream_global->max_recv_bytes >=
- stream_parsing->incoming_window_delta);
- stream_global->max_recv_bytes -=
- stream_parsing->incoming_window_delta;
+ GPR_ASSERT(stream_global->max_recv_bytes >=
+ stream_parsing->incoming_window_delta);
+ stream_global->max_recv_bytes -= stream_parsing->incoming_window_delta;
stream_parsing->incoming_window_delta = 0;
grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
}
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 0f04169741..1ea697f71e 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -66,6 +66,8 @@ typedef struct {
size_t header_idx;
/* was the last frame emitted a header? (if yes, we'll need a CONTINUATION */
gpr_uint8 last_was_header;
+ /* have we seen a regular (non-colon-prefixed) header yet? */
+ gpr_uint8 seen_regular_header;
/* output stream id */
gpr_uint32 stream_id;
gpr_slice_buffer *output;
@@ -361,6 +363,15 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c,
gpr_uint32 indices_key;
int should_add_elem;
+ GPR_ASSERT (GPR_SLICE_LENGTH(elem->key->slice) > 0);
+ if (GPR_SLICE_START_PTR(elem->key->slice)[0] != ':') { /* regular header */
+ st->seen_regular_header = 1;
+ } else if (st->seen_regular_header != 0) { /* reserved header */
+ gpr_log(GPR_ERROR,
+ "Reserved header (colon-prefixed) happening after regular ones.");
+ abort();
+ }
+
inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum, c->filter_elems);
/* is this elem currently in the decoders table? */
@@ -566,6 +577,7 @@ void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
st.cur_frame_type = NONE;
st.last_was_header = 0;
+ st.seen_regular_header = 0;
st.stream_id = stream_id;
st.output = output;
diff --git a/src/core/transport/chttp2/stream_lists.c b/src/core/transport/chttp2/stream_lists.c
index 9c3ad7a777..38c6052f9c 100644
--- a/src/core/transport/chttp2/stream_lists.c
+++ b/src/core/transport/chttp2/stream_lists.c
@@ -363,7 +363,7 @@ void grpc_chttp2_register_stream(grpc_chttp2_transport *t,
}
int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t,
- grpc_chttp2_stream *s) {
+ grpc_chttp2_stream *s) {
stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS);
return stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS);
}
diff --git a/src/core/transport/chttp2/stream_map.c b/src/core/transport/chttp2/stream_map.c
index 0ec2f27291..bd16153ed1 100644
--- a/src/core/transport/chttp2/stream_map.c
+++ b/src/core/transport/chttp2/stream_map.c
@@ -123,8 +123,7 @@ void grpc_chttp2_stream_map_move_into(grpc_chttp2_stream_map *src,
dst->values = gpr_realloc(dst->values, dst->capacity * sizeof(void *));
}
memcpy(dst->keys + dst->count, src->keys, src->count * sizeof(gpr_uint32));
- memcpy(dst->values + dst->count, src->values,
- src->count * sizeof(void*));
+ memcpy(dst->values + dst->count, src->values, src->count * sizeof(void *));
dst->count += src->count;
dst->free += src->free;
src->count = 0;
diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c
index b55e81fdca..123061b3fc 100644
--- a/src/core/transport/chttp2/writing.c
+++ b/src/core/transport/chttp2/writing.c
@@ -112,13 +112,18 @@ int grpc_chttp2_unlocking_check_writes(
}
}
- if (!stream_global->read_closed && stream_global->unannounced_incoming_window > 0) {
- stream_writing->announce_window = stream_global->unannounced_incoming_window;
- GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
- incoming_window, stream_global->unannounced_incoming_window);
- GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
- unannounced_incoming_window, -(gpr_int64)stream_global->unannounced_incoming_window);
- stream_global->incoming_window += stream_global->unannounced_incoming_window;
+ if (!stream_global->read_closed &&
+ stream_global->unannounced_incoming_window > 0) {
+ stream_writing->announce_window =
+ stream_global->unannounced_incoming_window;
+ GRPC_CHTTP2_FLOWCTL_TRACE_STREAM(
+ "write", transport_global, stream_global, incoming_window,
+ stream_global->unannounced_incoming_window);
+ GRPC_CHTTP2_FLOWCTL_TRACE_STREAM(
+ "write", transport_global, stream_global, unannounced_incoming_window,
+ -(gpr_int64)stream_global->unannounced_incoming_window);
+ stream_global->incoming_window +=
+ stream_global->unannounced_incoming_window;
stream_global->unannounced_incoming_window = 0;
grpc_chttp2_list_add_incoming_window_updated(transport_global,
stream_global);
@@ -179,18 +184,20 @@ static void finalize_outbuf(grpc_chttp2_transport_writing *transport_writing) {
while (
grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) {
- if (stream_writing->sopb.nops > 0 || stream_writing->send_closed != GRPC_DONT_SEND_CLOSED) {
+ if (stream_writing->sopb.nops > 0 ||
+ stream_writing->send_closed != GRPC_DONT_SEND_CLOSED) {
grpc_chttp2_encode(stream_writing->sopb.ops, stream_writing->sopb.nops,
stream_writing->send_closed != GRPC_DONT_SEND_CLOSED,
- stream_writing->id, &transport_writing->hpack_compressor,
+ stream_writing->id,
+ &transport_writing->hpack_compressor,
&transport_writing->outbuf);
stream_writing->sopb.nops = 0;
}
if (stream_writing->announce_window > 0) {
gpr_slice_buffer_add(
&transport_writing->outbuf,
- grpc_chttp2_window_update_create(
- stream_writing->id, stream_writing->announce_window));
+ grpc_chttp2_window_update_create(stream_writing->id,
+ stream_writing->announce_window));
stream_writing->announce_window = 0;
}
if (stream_writing->send_closed == GRPC_SEND_CLOSED_WITH_RST_STREAM) {
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index a9f91b64d5..1bbd210e46 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -116,7 +116,7 @@ static void close_from_api(grpc_chttp2_transport_global *transport_global,
static void add_to_pollset_locked(grpc_chttp2_transport *t,
grpc_pollset *pollset);
static void add_to_pollset_set_locked(grpc_chttp2_transport *t,
- grpc_pollset_set *pollset_set);
+ grpc_pollset_set *pollset_set);
/** Start new streams that have been created if we can */
static void maybe_start_some_streams(
@@ -368,11 +368,10 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
s->global.outgoing_window =
t->global.settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
- s->global.max_recv_bytes =
- s->parsing.incoming_window =
+ s->global.max_recv_bytes = s->parsing.incoming_window =
s->global.incoming_window =
- t->global.settings[GRPC_SENT_SETTINGS]
- [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
+ t->global.settings[GRPC_SENT_SETTINGS]
+ [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
*t->accepting_stream = s;
grpc_chttp2_stream_map_add(&t->parsing_stream_map, s->global.id, s);
s->global.in_stream_map = 1;
@@ -580,7 +579,7 @@ static void maybe_start_some_streams(
stream_global->incoming_window =
transport_global->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
- stream_global->max_recv_bytes =
+ stream_global->max_recv_bytes =
GPR_MAX(stream_global->incoming_window, stream_global->max_recv_bytes);
grpc_chttp2_stream_map_add(
&TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map,
@@ -590,7 +589,6 @@ static void maybe_start_some_streams(
grpc_chttp2_list_add_incoming_window_updated(transport_global,
stream_global);
grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
-
}
/* cancel out streams that will never be started */
while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID &&
@@ -648,12 +646,14 @@ static void perform_stream_op_locked(
stream_global->publish_sopb->nops = 0;
stream_global->publish_state = op->recv_state;
if (stream_global->max_recv_bytes < op->max_recv_bytes) {
- GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("op", transport_global, stream_global,
- max_recv_bytes, op->max_recv_bytes - stream_global->max_recv_bytes);
+ GRPC_CHTTP2_FLOWCTL_TRACE_STREAM(
+ "op", transport_global, stream_global, max_recv_bytes,
+ op->max_recv_bytes - stream_global->max_recv_bytes);
GRPC_CHTTP2_FLOWCTL_TRACE_STREAM(
"op", transport_global, stream_global, unannounced_incoming_window,
op->max_recv_bytes - stream_global->max_recv_bytes);
- stream_global->unannounced_incoming_window += op->max_recv_bytes - stream_global->max_recv_bytes;
+ stream_global->unannounced_incoming_window +=
+ op->max_recv_bytes - stream_global->max_recv_bytes;
stream_global->max_recv_bytes = op->max_recv_bytes;
}
grpc_chttp2_incoming_metadata_live_op_buffer_end(
@@ -1175,7 +1175,7 @@ static void add_to_pollset_locked(grpc_chttp2_transport *t,
}
static void add_to_pollset_set_locked(grpc_chttp2_transport *t,
- grpc_pollset_set *pollset_set) {
+ grpc_pollset_set *pollset_set) {
if (t->ep) {
grpc_endpoint_add_to_pollset_set(t->ep, pollset_set);
}
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index 44d32b6cb2..3fd21a2f5d 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -133,8 +133,8 @@ static void unlock(grpc_mdctx *ctx) {
case), since otherwise we can be stuck waiting for a garbage collection
that will never happen. */
if (ctx->refs == 0) {
- /* uncomment if you're having trouble diagnosing an mdelem leak to make
- things clearer (slows down destruction a lot, however) */
+/* uncomment if you're having trouble diagnosing an mdelem leak to make
+ things clearer (slows down destruction a lot, however) */
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gc_mdtab(ctx);
#endif
@@ -311,7 +311,8 @@ static void slice_unref(void *p) {
unlock(ctx);
}
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str, int canonicalize_key) {
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str,
+ int canonicalize_key) {
if (canonicalize_key) {
size_t len;
size_t i;
@@ -522,9 +523,9 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
grpc_mdelem *grpc_mdelem_from_strings(grpc_mdctx *ctx, const char *key,
const char *value) {
- return grpc_mdelem_from_metadata_strings(ctx,
- grpc_mdstr_from_string(ctx, key, 0),
- grpc_mdstr_from_string(ctx, value, 0));
+ return grpc_mdelem_from_metadata_strings(
+ ctx, grpc_mdstr_from_string(ctx, key, 0),
+ grpc_mdstr_from_string(ctx, value, 0));
}
grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
@@ -680,16 +681,34 @@ void grpc_mdctx_locked_mdelem_unref(grpc_mdctx *ctx,
void grpc_mdctx_unlock(grpc_mdctx *ctx) { unlock(ctx); }
-int grpc_mdstr_is_legal_header(grpc_mdstr *s) {
- /* TODO(ctiller): consider caching this, or computing it on construction */
+static int conforms_to(grpc_mdstr *s, const gpr_uint8 *legal_bits) {
const gpr_uint8 *p = GPR_SLICE_START_PTR(s->slice);
const gpr_uint8 *e = GPR_SLICE_END_PTR(s->slice);
for (; p != e; p++) {
- if (*p < 32 || *p > 126) return 0;
+ int idx = *p;
+ int byte = idx / 8;
+ int bit = idx % 8;
+ if ((legal_bits[byte] & (1 << bit)) == 0) return 0;
}
return 1;
}
+int grpc_mdstr_is_legal_header(grpc_mdstr *s) {
+ static const gpr_uint8 legal_header_bits[256 / 8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00,
+ 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ return conforms_to(s, legal_header_bits);
+}
+
+int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s) {
+ static const gpr_uint8 legal_header_bits[256 / 8] = {
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ return conforms_to(s, legal_header_bits);
+}
+
int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s) {
/* TODO(ctiller): consider caching this */
return grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(s->slice),
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index 15ef9bb555..eb17747be7 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -95,7 +95,8 @@ size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *mdctx);
/* Constructors for grpc_mdstr instances; take a variety of data types that
clients may have handy */
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str, int perform_key_canonicalization);
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str,
+ int perform_key_canonicalization);
/* Unrefs the slice. */
grpc_mdstr *grpc_mdstr_from_slice(grpc_mdctx *ctx, gpr_slice slice);
grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *str,
@@ -153,6 +154,7 @@ void grpc_mdelem_unref(grpc_mdelem *md);
const char *grpc_mdstr_as_c_string(grpc_mdstr *s);
int grpc_mdstr_is_legal_header(grpc_mdstr *s);
+int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s);
int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
/* Batch mode metadata functions.
@@ -179,4 +181,4 @@ void grpc_mdctx_unlock(grpc_mdctx *ctx);
#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H */
+#endif /* GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H */
diff --git a/src/core/transport/stream_op.c b/src/core/transport/stream_op.c
index 0a9669b0ab..038586d48e 100644
--- a/src/core/transport/stream_op.c
+++ b/src/core/transport/stream_op.c
@@ -203,8 +203,8 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *batch) {
#endif /* NDEBUG */
void grpc_metadata_batch_init(grpc_metadata_batch *batch) {
- batch->list.head = batch->list.tail = batch->garbage.head = batch->garbage.tail =
- NULL;
+ batch->list.head = batch->list.tail = batch->garbage.head =
+ batch->garbage.tail = NULL;
batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
}
@@ -288,7 +288,7 @@ void grpc_metadata_batch_merge(grpc_metadata_batch *target,
}
void grpc_metadata_batch_move(grpc_metadata_batch *dst,
- grpc_metadata_batch *src) {
+ grpc_metadata_batch *src) {
*dst = *src;
memset(src, 0, sizeof(grpc_metadata_batch));
}