aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Julien Boeuf <jboeuf@google.com>2016-05-10 15:26:17 -0700
committerGravatar Julien Boeuf <jboeuf@google.com>2016-05-10 15:26:17 -0700
commitbae6a4cb43db9afd0868cdb66f34a5449156a3e5 (patch)
tree344498f33e1583b4f35ad3e06655afeecdd26fdb /src/core
parent8ca294e417217e1577609052f18df84be437c03c (diff)
parente28415bdec34a9f4b19981d9d5d5d3df92eb8e5c (diff)
Merge branch 'master' of https://github.com/grpc/grpc into credentials_refactoring
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ext/client_config/resolver_registry.c8
-rw-r--r--src/core/ext/lb_policy/grpclb/load_balancer_api.c14
-rw-r--r--src/core/ext/lb_policy/grpclb/load_balancer_api.h10
-rw-r--r--src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h182
-rw-r--r--src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c (renamed from src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c)59
-rw-r--r--src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h178
-rw-r--r--src/core/ext/lb_policy/round_robin/round_robin.c6
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c153
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_rst_stream.c5
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.c6
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.c4
-rw-r--r--src/core/ext/transport/chttp2/transport/incoming_metadata.c1
-rw-r--r--src/core/ext/transport/chttp2/transport/incoming_metadata.h1
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h19
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.c58
-rw-r--r--src/core/lib/channel/channel_args.h4
-rw-r--r--src/core/lib/iomgr/tcp_posix.c4
-rw-r--r--src/core/lib/surface/version.c2
-rw-r--r--src/core/lib/transport/metadata.h4
-rw-r--r--src/core/lib/transport/metadata_batch.c9
-rw-r--r--src/core/lib/transport/metadata_batch.h3
21 files changed, 430 insertions, 300 deletions
diff --git a/src/core/ext/client_config/resolver_registry.c b/src/core/ext/client_config/resolver_registry.c
index 07f29bcb27..e7a4abd568 100644
--- a/src/core/ext/client_config/resolver_registry.c
+++ b/src/core/ext/client_config/resolver_registry.c
@@ -47,7 +47,6 @@ static int g_number_of_resolvers = 0;
static char *g_default_resolver_prefix;
void grpc_resolver_registry_init(const char *default_resolver_prefix) {
- g_number_of_resolvers = 0;
g_default_resolver_prefix = gpr_strdup(default_resolver_prefix);
}
@@ -57,6 +56,13 @@ void grpc_resolver_registry_shutdown(void) {
grpc_resolver_factory_unref(g_all_of_the_resolvers[i]);
}
gpr_free(g_default_resolver_prefix);
+ // FIXME(ctiller): this should live in grpc_resolver_registry_init,
+ // however that would have the client_config plugin call this AFTER we start
+ // registering resolvers from third party plugins, and so they'd never show
+ // up.
+ // We likely need some kind of dependency system for plugins.... what form
+ // that takes is TBD.
+ g_number_of_resolvers = 0;
}
void grpc_register_resolver_type(grpc_resolver_factory *factory) {
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.c b/src/core/ext/lb_policy/grpclb/load_balancer_api.c
index 459d6d9954..59b89997dd 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.c
+++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.c
@@ -50,7 +50,7 @@ static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
decode_serverlist_arg *dec_arg = *arg;
if (dec_arg->first_pass != 0) { /* first pass */
grpc_grpclb_server server;
- if (!pb_decode(stream, grpc_lb_v0_Server_fields, &server)) {
+ if (!pb_decode(stream, grpc_lb_v1_Server_fields, &server)) {
return false;
}
dec_arg->num_servers++;
@@ -61,7 +61,7 @@ static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
dec_arg->servers =
gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers);
}
- if (!pb_decode(stream, grpc_lb_v0_Server_fields, server)) {
+ if (!pb_decode(stream, grpc_lb_v1_Server_fields, server)) {
return false;
}
dec_arg->servers[dec_arg->i++] = server;
@@ -87,13 +87,13 @@ gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) {
pb_ostream_t outputstream;
gpr_slice slice;
memset(&sizestream, 0, sizeof(pb_ostream_t));
- pb_encode(&sizestream, grpc_lb_v0_LoadBalanceRequest_fields, request);
+ pb_encode(&sizestream, grpc_lb_v1_LoadBalanceRequest_fields, request);
encoded_length = sizestream.bytes_written;
slice = gpr_slice_malloc(encoded_length);
outputstream =
pb_ostream_from_buffer(GPR_SLICE_START_PTR(slice), encoded_length);
- GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v0_LoadBalanceRequest_fields,
+ GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v1_LoadBalanceRequest_fields,
request) != 0);
return slice;
}
@@ -109,7 +109,7 @@ grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) {
GPR_SLICE_LENGTH(encoded_response));
grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
memset(res, 0, sizeof(*res));
- status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
+ status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, res);
if (!status) {
grpc_grpclb_response_destroy(res);
return NULL;
@@ -132,7 +132,7 @@ grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
res->server_list.servers.funcs.decode = decode_serverlist;
res->server_list.servers.arg = &arg;
arg.first_pass = 1;
- status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
+ status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, res);
if (!status) {
grpc_grpclb_response_destroy(res);
return NULL;
@@ -140,7 +140,7 @@ grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
arg.first_pass = 0;
status =
- pb_decode(&stream_at_start, grpc_lb_v0_LoadBalanceResponse_fields, res);
+ pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields, res);
if (!status) {
grpc_grpclb_response_destroy(res);
return NULL;
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/lb_policy/grpclb/load_balancer_api.h
index 968f7d278a..71b5616d0c 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.h
+++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.h
@@ -37,7 +37,7 @@
#include <grpc/support/slice_buffer.h>
#include "src/core/ext/client_config/lb_policy_factory.h"
-#include "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h"
+#include "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
#ifdef __cplusplus
extern "C" {
@@ -45,10 +45,10 @@ extern "C" {
#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
-typedef grpc_lb_v0_LoadBalanceRequest grpc_grpclb_request;
-typedef grpc_lb_v0_LoadBalanceResponse grpc_grpclb_response;
-typedef grpc_lb_v0_Server grpc_grpclb_server;
-typedef grpc_lb_v0_Duration grpc_grpclb_duration;
+typedef grpc_lb_v1_LoadBalanceRequest grpc_grpclb_request;
+typedef grpc_lb_v1_LoadBalanceResponse grpc_grpclb_response;
+typedef grpc_lb_v1_Server grpc_grpclb_server;
+typedef grpc_lb_v1_Duration grpc_grpclb_duration;
typedef struct grpc_grpclb_serverlist {
grpc_grpclb_server **servers;
size_t num_servers;
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h
deleted file mode 100644
index 3599f881bb..0000000000
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *
- * Copyright 2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-/* Automatically generated nanopb header */
-/* Generated by nanopb-0.3.5-dev */
-
-#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED
-#define PB_LOAD_BALANCER_PB_H_INCLUDED
-#include "third_party/nanopb/pb.h"
-#if PB_PROTO_HEADER_VERSION != 30
-#error Regenerate this file with the current version of nanopb generator.
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Struct definitions */
-typedef struct _grpc_lb_v0_ClientStats {
- bool has_total_requests;
- int64_t total_requests;
- bool has_client_rpc_errors;
- int64_t client_rpc_errors;
- bool has_dropped_requests;
- int64_t dropped_requests;
-} grpc_lb_v0_ClientStats;
-
-typedef struct _grpc_lb_v0_Duration {
- bool has_seconds;
- int64_t seconds;
- bool has_nanos;
- int32_t nanos;
-} grpc_lb_v0_Duration;
-
-typedef struct _grpc_lb_v0_InitialLoadBalanceRequest {
- bool has_name;
- char name[128];
-} grpc_lb_v0_InitialLoadBalanceRequest;
-
-typedef PB_BYTES_ARRAY_T(64) grpc_lb_v0_Server_load_balance_token_t;
-typedef struct _grpc_lb_v0_Server {
- bool has_ip_address;
- char ip_address[46];
- bool has_port;
- int32_t port;
- bool has_load_balance_token;
- grpc_lb_v0_Server_load_balance_token_t load_balance_token;
- bool has_drop_request;
- bool drop_request;
-} grpc_lb_v0_Server;
-
-typedef struct _grpc_lb_v0_InitialLoadBalanceResponse {
- bool has_client_config;
- char client_config[64];
- bool has_load_balancer_delegate;
- char load_balancer_delegate[64];
- bool has_client_stats_report_interval;
- grpc_lb_v0_Duration client_stats_report_interval;
-} grpc_lb_v0_InitialLoadBalanceResponse;
-
-typedef struct _grpc_lb_v0_LoadBalanceRequest {
- bool has_initial_request;
- grpc_lb_v0_InitialLoadBalanceRequest initial_request;
- bool has_client_stats;
- grpc_lb_v0_ClientStats client_stats;
-} grpc_lb_v0_LoadBalanceRequest;
-
-typedef struct _grpc_lb_v0_ServerList {
- pb_callback_t servers;
- bool has_expiration_interval;
- grpc_lb_v0_Duration expiration_interval;
-} grpc_lb_v0_ServerList;
-
-typedef struct _grpc_lb_v0_LoadBalanceResponse {
- bool has_initial_response;
- grpc_lb_v0_InitialLoadBalanceResponse initial_response;
- bool has_server_list;
- grpc_lb_v0_ServerList server_list;
-} grpc_lb_v0_LoadBalanceResponse;
-
-/* Default values for struct fields */
-
-/* Initializer values for message structs */
-#define grpc_lb_v0_Duration_init_default {false, 0, false, 0}
-#define grpc_lb_v0_LoadBalanceRequest_init_default {false, grpc_lb_v0_InitialLoadBalanceRequest_init_default, false, grpc_lb_v0_ClientStats_init_default}
-#define grpc_lb_v0_InitialLoadBalanceRequest_init_default {false, ""}
-#define grpc_lb_v0_ClientStats_init_default {false, 0, false, 0, false, 0}
-#define grpc_lb_v0_LoadBalanceResponse_init_default {false, grpc_lb_v0_InitialLoadBalanceResponse_init_default, false, grpc_lb_v0_ServerList_init_default}
-#define grpc_lb_v0_InitialLoadBalanceResponse_init_default {false, "", false, "", false, grpc_lb_v0_Duration_init_default}
-#define grpc_lb_v0_ServerList_init_default {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_default}
-#define grpc_lb_v0_Server_init_default {false, "", false, 0, false, {0, {0}}, false, 0}
-#define grpc_lb_v0_Duration_init_zero {false, 0, false, 0}
-#define grpc_lb_v0_LoadBalanceRequest_init_zero {false, grpc_lb_v0_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v0_ClientStats_init_zero}
-#define grpc_lb_v0_InitialLoadBalanceRequest_init_zero {false, ""}
-#define grpc_lb_v0_ClientStats_init_zero {false, 0, false, 0, false, 0}
-#define grpc_lb_v0_LoadBalanceResponse_init_zero {false, grpc_lb_v0_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v0_ServerList_init_zero}
-#define grpc_lb_v0_InitialLoadBalanceResponse_init_zero {false, "", false, "", false, grpc_lb_v0_Duration_init_zero}
-#define grpc_lb_v0_ServerList_init_zero {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_zero}
-#define grpc_lb_v0_Server_init_zero {false, "", false, 0, false, {0, {0}}, false, 0}
-
-/* Field tags (for use in manual encoding/decoding) */
-#define grpc_lb_v0_ClientStats_total_requests_tag 1
-#define grpc_lb_v0_ClientStats_client_rpc_errors_tag 2
-#define grpc_lb_v0_ClientStats_dropped_requests_tag 3
-#define grpc_lb_v0_Duration_seconds_tag 1
-#define grpc_lb_v0_Duration_nanos_tag 2
-#define grpc_lb_v0_InitialLoadBalanceRequest_name_tag 1
-#define grpc_lb_v0_Server_ip_address_tag 1
-#define grpc_lb_v0_Server_port_tag 2
-#define grpc_lb_v0_Server_load_balance_token_tag 3
-#define grpc_lb_v0_Server_drop_request_tag 4
-#define grpc_lb_v0_InitialLoadBalanceResponse_client_config_tag 1
-#define grpc_lb_v0_InitialLoadBalanceResponse_load_balancer_delegate_tag 2
-#define grpc_lb_v0_InitialLoadBalanceResponse_client_stats_report_interval_tag 3
-#define grpc_lb_v0_LoadBalanceRequest_initial_request_tag 1
-#define grpc_lb_v0_LoadBalanceRequest_client_stats_tag 2
-#define grpc_lb_v0_ServerList_servers_tag 1
-#define grpc_lb_v0_ServerList_expiration_interval_tag 3
-#define grpc_lb_v0_LoadBalanceResponse_initial_response_tag 1
-#define grpc_lb_v0_LoadBalanceResponse_server_list_tag 2
-
-/* Struct field encoding specification for nanopb */
-extern const pb_field_t grpc_lb_v0_Duration_fields[3];
-extern const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3];
-extern const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2];
-extern const pb_field_t grpc_lb_v0_ClientStats_fields[4];
-extern const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3];
-extern const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4];
-extern const pb_field_t grpc_lb_v0_ServerList_fields[3];
-extern const pb_field_t grpc_lb_v0_Server_fields[5];
-
-/* Maximum encoded size of messages (where known) */
-#define grpc_lb_v0_Duration_size 22
-#define grpc_lb_v0_LoadBalanceRequest_size 169
-#define grpc_lb_v0_InitialLoadBalanceRequest_size 131
-#define grpc_lb_v0_ClientStats_size 33
-#define grpc_lb_v0_LoadBalanceResponse_size (165 + grpc_lb_v0_ServerList_size)
-#define grpc_lb_v0_InitialLoadBalanceResponse_size 156
-#define grpc_lb_v0_Server_size 127
-
-/* Message IDs (where set with "msgid" option) */
-#ifdef PB_MSGID
-
-#define LOAD_BALANCER_MESSAGES \
-
-
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
index 9719673181..52e11c40bb 100644
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c
+++ b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
@@ -33,7 +33,7 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.5-dev */
-#include "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h"
+#include "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
@@ -41,54 +41,53 @@
-const pb_field_t grpc_lb_v0_Duration_fields[3] = {
- PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v0_Duration, seconds, seconds, 0),
- PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Duration, nanos, seconds, 0),
+const pb_field_t grpc_lb_v1_Duration_fields[3] = {
+ PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v1_Duration, seconds, seconds, 0),
+ PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v1_Duration, nanos, seconds, 0),
PB_LAST_FIELD
};
-const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3] = {
- PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v0_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v0_InitialLoadBalanceRequest_fields),
- PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v0_ClientStats_fields),
+const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3] = {
+ PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v1_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v1_InitialLoadBalanceRequest_fields),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v1_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v1_ClientStats_fields),
PB_LAST_FIELD
};
-const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2] = {
- PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_InitialLoadBalanceRequest, name, name, 0),
+const pb_field_t grpc_lb_v1_InitialLoadBalanceRequest_fields[2] = {
+ PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v1_InitialLoadBalanceRequest, name, name, 0),
PB_LAST_FIELD
};
-const pb_field_t grpc_lb_v0_ClientStats_fields[4] = {
- PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v0_ClientStats, total_requests, total_requests, 0),
- PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ClientStats, client_rpc_errors, total_requests, 0),
- PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ClientStats, dropped_requests, client_rpc_errors, 0),
+const pb_field_t grpc_lb_v1_ClientStats_fields[4] = {
+ PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v1_ClientStats, total_requests, total_requests, 0),
+ PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v1_ClientStats, client_rpc_errors, total_requests, 0),
+ PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v1_ClientStats, dropped_requests, client_rpc_errors, 0),
PB_LAST_FIELD
};
-const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3] = {
- PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v0_LoadBalanceResponse, initial_response, initial_response, &grpc_lb_v0_InitialLoadBalanceResponse_fields),
- PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_LoadBalanceResponse, server_list, initial_response, &grpc_lb_v0_ServerList_fields),
+const pb_field_t grpc_lb_v1_LoadBalanceResponse_fields[3] = {
+ PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v1_LoadBalanceResponse, initial_response, initial_response, &grpc_lb_v1_InitialLoadBalanceResponse_fields),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v1_LoadBalanceResponse, server_list, initial_response, &grpc_lb_v1_ServerList_fields),
PB_LAST_FIELD
};
-const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4] = {
- PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_InitialLoadBalanceResponse, client_config, client_config, 0),
- PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, load_balancer_delegate, client_config, 0),
- PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &grpc_lb_v0_Duration_fields),
+const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3] = {
+ PB_FIELD( 2, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v1_InitialLoadBalanceResponse, load_balancer_delegate, load_balancer_delegate, 0),
+ PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &grpc_lb_v1_Duration_fields),
PB_LAST_FIELD
};
-const pb_field_t grpc_lb_v0_ServerList_fields[3] = {
- PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, grpc_lb_v0_ServerList, servers, servers, &grpc_lb_v0_Server_fields),
- PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ServerList, expiration_interval, servers, &grpc_lb_v0_Duration_fields),
+const pb_field_t grpc_lb_v1_ServerList_fields[3] = {
+ PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, grpc_lb_v1_ServerList, servers, servers, &grpc_lb_v1_Server_fields),
+ PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v1_ServerList, expiration_interval, servers, &grpc_lb_v1_Duration_fields),
PB_LAST_FIELD
};
-const pb_field_t grpc_lb_v0_Server_fields[5] = {
- PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_Server, ip_address, ip_address, 0),
- PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, port, ip_address, 0),
- PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, load_balance_token, port, 0),
- PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, drop_request, load_balance_token, 0),
+const pb_field_t grpc_lb_v1_Server_fields[5] = {
+ PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v1_Server, ip_address, ip_address, 0),
+ PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v1_Server, port, ip_address, 0),
+ PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, grpc_lb_v1_Server, load_balance_token, port, 0),
+ PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, grpc_lb_v1_Server, drop_request, load_balance_token, 0),
PB_LAST_FIELD
};
@@ -102,7 +101,7 @@ const pb_field_t grpc_lb_v0_Server_fields[5] = {
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
-PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v0_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server)
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v1_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
@@ -113,7 +112,7 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request)
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
-PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v0_ServerList, servers) < 256 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server)
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
#endif
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
new file mode 100644
index 0000000000..d5dc39ab94
--- /dev/null
+++ b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
@@ -0,0 +1,178 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.5-dev */
+
+#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED
+#define PB_LOAD_BALANCER_PB_H_INCLUDED
+#include "third_party/nanopb/pb.h"
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Struct definitions */
+typedef struct _grpc_lb_v1_ClientStats {
+ bool has_total_requests;
+ int64_t total_requests;
+ bool has_client_rpc_errors;
+ int64_t client_rpc_errors;
+ bool has_dropped_requests;
+ int64_t dropped_requests;
+} grpc_lb_v1_ClientStats;
+
+typedef struct _grpc_lb_v1_Duration {
+ bool has_seconds;
+ int64_t seconds;
+ bool has_nanos;
+ int32_t nanos;
+} grpc_lb_v1_Duration;
+
+typedef struct _grpc_lb_v1_InitialLoadBalanceRequest {
+ bool has_name;
+ char name[128];
+} grpc_lb_v1_InitialLoadBalanceRequest;
+
+typedef struct _grpc_lb_v1_Server {
+ bool has_ip_address;
+ char ip_address[46];
+ bool has_port;
+ int32_t port;
+ bool has_load_balance_token;
+ char load_balance_token[64];
+ bool has_drop_request;
+ bool drop_request;
+} grpc_lb_v1_Server;
+
+typedef struct _grpc_lb_v1_InitialLoadBalanceResponse {
+ bool has_load_balancer_delegate;
+ char load_balancer_delegate[64];
+ bool has_client_stats_report_interval;
+ grpc_lb_v1_Duration client_stats_report_interval;
+} grpc_lb_v1_InitialLoadBalanceResponse;
+
+typedef struct _grpc_lb_v1_LoadBalanceRequest {
+ bool has_initial_request;
+ grpc_lb_v1_InitialLoadBalanceRequest initial_request;
+ bool has_client_stats;
+ grpc_lb_v1_ClientStats client_stats;
+} grpc_lb_v1_LoadBalanceRequest;
+
+typedef struct _grpc_lb_v1_ServerList {
+ pb_callback_t servers;
+ bool has_expiration_interval;
+ grpc_lb_v1_Duration expiration_interval;
+} grpc_lb_v1_ServerList;
+
+typedef struct _grpc_lb_v1_LoadBalanceResponse {
+ bool has_initial_response;
+ grpc_lb_v1_InitialLoadBalanceResponse initial_response;
+ bool has_server_list;
+ grpc_lb_v1_ServerList server_list;
+} grpc_lb_v1_LoadBalanceResponse;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define grpc_lb_v1_Duration_init_default {false, 0, false, 0}
+#define grpc_lb_v1_LoadBalanceRequest_init_default {false, grpc_lb_v1_InitialLoadBalanceRequest_init_default, false, grpc_lb_v1_ClientStats_init_default}
+#define grpc_lb_v1_InitialLoadBalanceRequest_init_default {false, ""}
+#define grpc_lb_v1_ClientStats_init_default {false, 0, false, 0, false, 0}
+#define grpc_lb_v1_LoadBalanceResponse_init_default {false, grpc_lb_v1_InitialLoadBalanceResponse_init_default, false, grpc_lb_v1_ServerList_init_default}
+#define grpc_lb_v1_InitialLoadBalanceResponse_init_default {false, "", false, grpc_lb_v1_Duration_init_default}
+#define grpc_lb_v1_ServerList_init_default {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_default}
+#define grpc_lb_v1_Server_init_default {false, "", false, 0, false, "", false, 0}
+#define grpc_lb_v1_Duration_init_zero {false, 0, false, 0}
+#define grpc_lb_v1_LoadBalanceRequest_init_zero {false, grpc_lb_v1_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v1_ClientStats_init_zero}
+#define grpc_lb_v1_InitialLoadBalanceRequest_init_zero {false, ""}
+#define grpc_lb_v1_ClientStats_init_zero {false, 0, false, 0, false, 0}
+#define grpc_lb_v1_LoadBalanceResponse_init_zero {false, grpc_lb_v1_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v1_ServerList_init_zero}
+#define grpc_lb_v1_InitialLoadBalanceResponse_init_zero {false, "", false, grpc_lb_v1_Duration_init_zero}
+#define grpc_lb_v1_ServerList_init_zero {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_zero}
+#define grpc_lb_v1_Server_init_zero {false, "", false, 0, false, "", false, 0}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define grpc_lb_v1_ClientStats_total_requests_tag 1
+#define grpc_lb_v1_ClientStats_client_rpc_errors_tag 2
+#define grpc_lb_v1_ClientStats_dropped_requests_tag 3
+#define grpc_lb_v1_Duration_seconds_tag 1
+#define grpc_lb_v1_Duration_nanos_tag 2
+#define grpc_lb_v1_InitialLoadBalanceRequest_name_tag 1
+#define grpc_lb_v1_Server_ip_address_tag 1
+#define grpc_lb_v1_Server_port_tag 2
+#define grpc_lb_v1_Server_load_balance_token_tag 3
+#define grpc_lb_v1_Server_drop_request_tag 4
+#define grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate_tag 2
+#define grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval_tag 3
+#define grpc_lb_v1_LoadBalanceRequest_initial_request_tag 1
+#define grpc_lb_v1_LoadBalanceRequest_client_stats_tag 2
+#define grpc_lb_v1_ServerList_servers_tag 1
+#define grpc_lb_v1_ServerList_expiration_interval_tag 3
+#define grpc_lb_v1_LoadBalanceResponse_initial_response_tag 1
+#define grpc_lb_v1_LoadBalanceResponse_server_list_tag 2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t grpc_lb_v1_Duration_fields[3];
+extern const pb_field_t grpc_lb_v1_LoadBalanceRequest_fields[3];
+extern const pb_field_t grpc_lb_v1_InitialLoadBalanceRequest_fields[2];
+extern const pb_field_t grpc_lb_v1_ClientStats_fields[4];
+extern const pb_field_t grpc_lb_v1_LoadBalanceResponse_fields[3];
+extern const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3];
+extern const pb_field_t grpc_lb_v1_ServerList_fields[3];
+extern const pb_field_t grpc_lb_v1_Server_fields[5];
+
+/* Maximum encoded size of messages (where known) */
+#define grpc_lb_v1_Duration_size 22
+#define grpc_lb_v1_LoadBalanceRequest_size 169
+#define grpc_lb_v1_InitialLoadBalanceRequest_size 131
+#define grpc_lb_v1_ClientStats_size 33
+#define grpc_lb_v1_LoadBalanceResponse_size (98 + grpc_lb_v1_ServerList_size)
+#define grpc_lb_v1_InitialLoadBalanceResponse_size 90
+#define grpc_lb_v1_Server_size 127
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define LOAD_BALANCER_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 3f6051b892..dcdc0c6285 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -306,8 +306,10 @@ static void start_picking(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p) {
size_t i;
p->started_picking = 1;
- gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p,
- p->num_subchannels);
+ if (grpc_lb_round_robin_trace) {
+ gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p,
+ p->num_subchannels);
+ }
for (i = 0; i < p->num_subchannels; i++) {
subchannel_data *sd = p->subchannels[i];
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 8c8593748d..b6886a2201 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -56,6 +56,8 @@
#define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024)
#define MAX_WINDOW 0x7fffffffu
+#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
+
#define MAX_CLIENT_STREAM_ID 0x7fffffffu
int grpc_http_trace = 0;
@@ -65,8 +67,8 @@ int grpc_flowctl_trace = 0;
((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \
writing)))
-#define TRANSPORT_FROM_PARSING(tw) \
- ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \
+#define TRANSPORT_FROM_PARSING(tp) \
+ ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \
parsing)))
#define TRANSPORT_FROM_GLOBAL(tg) \
@@ -311,6 +313,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0);
}
push_setting(t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, DEFAULT_WINDOW);
+ push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
+ DEFAULT_MAX_HEADER_LIST_SIZE);
if (channel_args) {
for (i = 0; i < channel_args->num_args; i++) {
@@ -378,6 +382,18 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
&t->writing.hpack_compressor,
(uint32_t)channel_args->args[i].value.integer);
}
+ } else if (0 == strcmp(channel_args->args[i].key,
+ GRPC_ARG_MAX_METADATA_SIZE)) {
+ if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
+ gpr_log(GPR_ERROR, "%s: must be an integer",
+ GRPC_ARG_MAX_METADATA_SIZE);
+ } else if (channel_args->args[i].value.integer < 0) {
+ gpr_log(GPR_ERROR, "%s: must be non-negative",
+ GRPC_ARG_MAX_METADATA_SIZE);
+ } else {
+ push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
+ (uint32_t)channel_args->args[i].value.integer);
+ }
}
}
}
@@ -510,7 +526,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
[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;
+ s->global.in_stream_map = true;
}
grpc_chttp2_run_with_global_lock(exec_ctx, t, s, finish_init_stream_locked,
@@ -783,7 +799,8 @@ void grpc_chttp2_add_incoming_goaway(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
uint32_t goaway_error, gpr_slice goaway_text) {
char *msg = gpr_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg);
+ GRPC_CHTTP2_IF_TRACING(
+ gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
gpr_free(msg);
gpr_slice_unref(goaway_text);
transport_global->seen_goaway = 1;
@@ -833,7 +850,7 @@ static void maybe_start_some_streams(
grpc_chttp2_stream_map_add(
&TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map,
stream_global->id, STREAM_FROM_GLOBAL(stream_global));
- stream_global->in_stream_map = 1;
+ stream_global->in_stream_map = true;
transport_global->concurrent_stream_count++;
grpc_chttp2_become_writable(transport_global, stream_global);
}
@@ -932,24 +949,38 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
stream_global->send_initial_metadata_finished =
add_closure_barrier(on_complete);
stream_global->send_initial_metadata = op->send_initial_metadata;
- if (contains_non_ok_status(transport_global, op->send_initial_metadata)) {
- stream_global->seen_error = 1;
- grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
- }
- if (!stream_global->write_closed) {
- if (transport_global->is_client) {
- GPR_ASSERT(stream_global->id == 0);
- grpc_chttp2_list_add_waiting_for_concurrency(transport_global,
- stream_global);
- maybe_start_some_streams(exec_ctx, transport_global);
+ const size_t metadata_size =
+ grpc_metadata_batch_size(op->send_initial_metadata);
+ const size_t metadata_peer_limit =
+ transport_global->settings[GRPC_PEER_SETTINGS]
+ [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
+ if (metadata_size > metadata_peer_limit) {
+ gpr_log(GPR_DEBUG,
+ "to-be-sent initial metadata size exceeds peer limit "
+ "(%lu vs. %lu)",
+ metadata_size, metadata_peer_limit);
+ cancel_from_api(exec_ctx, transport_global, stream_global,
+ GRPC_STATUS_RESOURCE_EXHAUSTED);
+ } else {
+ if (contains_non_ok_status(transport_global, op->send_initial_metadata)) {
+ stream_global->seen_error = true;
+ grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
+ }
+ if (!stream_global->write_closed) {
+ if (transport_global->is_client) {
+ GPR_ASSERT(stream_global->id == 0);
+ grpc_chttp2_list_add_waiting_for_concurrency(transport_global,
+ stream_global);
+ maybe_start_some_streams(exec_ctx, transport_global);
+ } else {
+ GPR_ASSERT(stream_global->id != 0);
+ grpc_chttp2_become_writable(transport_global, stream_global);
+ }
} else {
- GPR_ASSERT(stream_global->id != 0);
- grpc_chttp2_become_writable(transport_global, stream_global);
+ grpc_chttp2_complete_closure_step(
+ exec_ctx, stream_global,
+ &stream_global->send_initial_metadata_finished, 0);
}
- } else {
- grpc_chttp2_complete_closure_step(
- exec_ctx, stream_global,
- &stream_global->send_initial_metadata_finished, 0);
}
}
@@ -973,19 +1004,34 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
stream_global->send_trailing_metadata_finished =
add_closure_barrier(on_complete);
stream_global->send_trailing_metadata = op->send_trailing_metadata;
- if (contains_non_ok_status(transport_global, op->send_trailing_metadata)) {
- stream_global->seen_error = 1;
- grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
- }
- if (stream_global->write_closed) {
- grpc_chttp2_complete_closure_step(
- exec_ctx, stream_global,
- &stream_global->send_trailing_metadata_finished,
- grpc_metadata_batch_is_empty(op->send_trailing_metadata));
- } else if (stream_global->id != 0) {
- /* TODO(ctiller): check if there's flow control for any outstanding
- bytes before going writable */
- grpc_chttp2_become_writable(transport_global, stream_global);
+ const size_t metadata_size =
+ grpc_metadata_batch_size(op->send_trailing_metadata);
+ const size_t metadata_peer_limit =
+ transport_global->settings[GRPC_PEER_SETTINGS]
+ [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
+ if (metadata_size > metadata_peer_limit) {
+ gpr_log(GPR_DEBUG,
+ "to-be-sent trailing metadata size exceeds peer limit "
+ "(%lu vs. %lu)",
+ metadata_size, metadata_peer_limit);
+ cancel_from_api(exec_ctx, transport_global, stream_global,
+ GRPC_STATUS_RESOURCE_EXHAUSTED);
+ } else {
+ if (contains_non_ok_status(transport_global,
+ op->send_trailing_metadata)) {
+ stream_global->seen_error = true;
+ grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
+ }
+ if (stream_global->write_closed) {
+ grpc_chttp2_complete_closure_step(
+ exec_ctx, stream_global,
+ &stream_global->send_trailing_metadata_finished,
+ grpc_metadata_batch_is_empty(op->send_trailing_metadata));
+ } else if (stream_global->id != 0) {
+ /* TODO(ctiller): check if there's flow control for any outstanding
+ bytes before going writable */
+ grpc_chttp2_become_writable(transport_global, stream_global);
+ }
}
}
@@ -1148,6 +1194,16 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
grpc_chttp2_list_pop_check_read_ops(transport_global, &stream_global)) {
if (stream_global->recv_initial_metadata_ready != NULL &&
stream_global->published_initial_metadata) {
+ if (stream_global->seen_error) {
+ while ((bs = grpc_chttp2_incoming_frame_queue_pop(
+ &stream_global->incoming_frames)) != NULL) {
+ incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
+ }
+ if (stream_global->exceeded_metadata_size) {
+ cancel_from_api(exec_ctx, transport_global, stream_global,
+ GRPC_STATUS_RESOURCE_EXHAUSTED);
+ }
+ }
grpc_chttp2_incoming_metadata_buffer_publish(
&stream_global->received_initial_metadata,
stream_global->recv_initial_metadata);
@@ -1177,10 +1233,15 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
}
if (stream_global->recv_trailing_metadata_finished != NULL &&
stream_global->read_closed && stream_global->write_closed) {
- while (stream_global->seen_error &&
- (bs = grpc_chttp2_incoming_frame_queue_pop(
- &stream_global->incoming_frames)) != NULL) {
- incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
+ if (stream_global->seen_error) {
+ while ((bs = grpc_chttp2_incoming_frame_queue_pop(
+ &stream_global->incoming_frames)) != NULL) {
+ incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
+ }
+ if (stream_global->exceeded_metadata_size) {
+ cancel_from_api(exec_ctx, transport_global, stream_global,
+ GRPC_STATUS_RESOURCE_EXHAUSTED);
+ }
}
if (stream_global->all_incoming_byte_streams_finished) {
grpc_chttp2_incoming_metadata_buffer_publish(
@@ -1212,7 +1273,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id);
}
GPR_ASSERT(s);
- s->global.in_stream_map = 0;
+ s->global.in_stream_map = false;
if (t->parsing.incoming_stream == &s->parsing) {
t->parsing.incoming_stream = NULL;
grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->parsing);
@@ -1256,7 +1317,7 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx,
NULL);
}
if (status != GRPC_STATUS_OK && !stream_global->seen_error) {
- stream_global->seen_error = 1;
+ stream_global->seen_error = true;
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
}
grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1,
@@ -1268,7 +1329,7 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream_global *stream_global,
grpc_status_code status, gpr_slice *slice) {
if (status != GRPC_STATUS_OK) {
- stream_global->seen_error = 1;
+ stream_global->seen_error = true;
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
}
/* stream_global->recv_trailing_metadata_finished gives us a
@@ -1292,7 +1353,7 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
GRPC_MDSTR_GRPC_MESSAGE,
grpc_mdstr_from_slice(gpr_slice_ref(*slice))));
}
- stream_global->published_trailing_metadata = 1;
+ stream_global->published_trailing_metadata = true;
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
}
if (slice) {
@@ -1322,13 +1383,13 @@ void grpc_chttp2_mark_stream_closed(
}
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
if (close_reads && !stream_global->read_closed) {
- stream_global->read_closed = 1;
- stream_global->published_initial_metadata = 1;
- stream_global->published_trailing_metadata = 1;
+ stream_global->read_closed = true;
+ stream_global->published_initial_metadata = true;
+ stream_global->published_trailing_metadata = true;
decrement_active_streams_locked(exec_ctx, transport_global, stream_global);
}
if (close_writes && !stream_global->write_closed) {
- stream_global->write_closed = 1;
+ stream_global->write_closed = true;
if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.writing_active) {
GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes");
grpc_chttp2_list_add_closed_waiting_for_writing(transport_global,
diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
index 22467e9ddd..7f01105e3e 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
@@ -45,15 +45,20 @@ gpr_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code,
stats->framing_bytes += frame_size;
uint8_t *p = GPR_SLICE_START_PTR(slice);
+ // Frame size.
*p++ = 0;
*p++ = 0;
*p++ = 4;
+ // Frame type.
*p++ = GRPC_CHTTP2_FRAME_RST_STREAM;
+ // Flags.
*p++ = 0;
+ // Stream ID.
*p++ = (uint8_t)(id >> 24);
*p++ = (uint8_t)(id >> 16);
*p++ = (uint8_t)(id >> 8);
*p++ = (uint8_t)(id);
+ // Error code.
*p++ = (uint8_t)(code >> 24);
*p++ = (uint8_t)(code >> 16);
*p++ = (uint8_t)(code >> 8);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index 555027c866..ebeee37f0d 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -63,6 +63,8 @@
/* don't consider adding anything bigger than this to the hpack table */
#define MAX_DECODER_SPACE_USAGE 512
+extern int grpc_http_trace;
+
typedef struct {
int is_first_frame;
/* number of bytes in 'output' when we started the frame - used to calculate
@@ -532,7 +534,9 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
}
}
c->advertise_table_size_change = 1;
- gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size);
+ if (grpc_http_trace) {
+ gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size);
+ }
}
void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c
index 4d64506de2..295f31c44f 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.c
@@ -253,7 +253,9 @@ void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
if (tbl->max_bytes == max_bytes) {
return;
}
- gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
+ if (grpc_http_trace) {
+ gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
+ }
while (tbl->mem_used > max_bytes) {
evict1(tbl);
}
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.c b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
index db21744f0c..3e463a7995 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.c
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
@@ -65,6 +65,7 @@ void grpc_chttp2_incoming_metadata_buffer_add(
gpr_realloc(buffer->elems, sizeof(*buffer->elems) * buffer->capacity);
}
buffer->elems[buffer->count++].md = elem;
+ buffer->size += GRPC_MDELEM_LENGTH(elem);
}
void grpc_chttp2_incoming_metadata_buffer_set_deadline(
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
index 17ecf8e181..df4343b93e 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -42,6 +42,7 @@ typedef struct {
size_t capacity;
gpr_timespec deadline;
int published;
+ size_t size; // total size of metadata
} grpc_chttp2_incoming_metadata_buffer;
/** assumes everything initially zeroed */
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 8c4fa2d34a..5872fd8e0a 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -422,23 +422,21 @@ typedef struct {
/** number of streams that are currently being read */
gpr_refcount active_streams;
- /** when the application requests writes be closed, the write_closed is
- 'queued'; when the close is flow controlled into the send path, we are
- 'sending' it; when the write has been performed it is 'sent' */
+ /** Is this stream closed for writing. */
bool write_closed;
- /** is this stream reading half-closed (boolean) */
+ /** Is this stream reading half-closed. */
bool read_closed;
- /** are all published incoming byte streams closed */
+ /** Are all published incoming byte streams closed. */
bool all_incoming_byte_streams_finished;
- /** is this stream in the stream map? (boolean) */
+ /** Is this stream in the stream map. */
bool in_stream_map;
- /** has this stream seen an error? if 1, then pending incoming frames
- can be thrown away */
+ /** Has this stream seen an error.
+ If true, then pending incoming frames can be thrown away. */
bool seen_error;
+ bool exceeded_metadata_size;
bool published_initial_metadata;
bool published_trailing_metadata;
- bool faked_trailing_metadata;
grpc_chttp2_incoming_metadata_buffer received_initial_metadata;
grpc_chttp2_incoming_metadata_buffer received_trailing_metadata;
@@ -481,7 +479,8 @@ struct grpc_chttp2_stream_parsing {
/** which metadata did we get (on this parse) */
uint8_t got_metadata_on_parse[2];
/** should we raise the seen_error flag in transport_global */
- uint8_t seen_error;
+ bool seen_error;
+ bool exceeded_metadata_size;
/** window available for peer to send to us */
int64_t incoming_window;
/** parsing state for data frames */
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 2995066e51..4bd374b7fa 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -45,6 +45,10 @@
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/transport/static_metadata.h"
+#define TRANSPORT_FROM_PARSING(tp) \
+ ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \
+ parsing)))
+
static int init_frame_parser(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport_parsing *transport_parsing);
static int init_header_frame_parser(
@@ -170,7 +174,9 @@ void grpc_chttp2_publish_reads(
while (grpc_chttp2_list_pop_parsing_seen_stream(
transport_global, transport_parsing, &stream_global, &stream_parsing)) {
if (stream_parsing->seen_error) {
- stream_global->seen_error = 1;
+ stream_global->seen_error = true;
+ stream_global->exceeded_metadata_size =
+ stream_parsing->exceeded_metadata_size;
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
}
@@ -612,7 +618,7 @@ static void on_initial_header(void *tp, grpc_mdelem *md) {
if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
/* TODO(ctiller): check for a status like " 0" */
- stream_parsing->seen_error = 1;
+ stream_parsing->seen_error = true;
}
if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) {
@@ -633,8 +639,26 @@ static void on_initial_header(void *tp, grpc_mdelem *md) {
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
GRPC_MDELEM_UNREF(md);
} else {
- grpc_chttp2_incoming_metadata_buffer_add(
- &stream_parsing->metadata_buffer[0], md);
+ const size_t new_size =
+ stream_parsing->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
+ grpc_chttp2_transport_global *transport_global =
+ &TRANSPORT_FROM_PARSING(transport_parsing)->global;
+ const size_t metadata_size_limit =
+ transport_global->settings[GRPC_LOCAL_SETTINGS]
+ [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
+ if (new_size > metadata_size_limit) {
+ if (!stream_parsing->exceeded_metadata_size) {
+ gpr_log(GPR_DEBUG,
+ "received initial metadata size exceeds limit (%lu vs. %lu)",
+ new_size, metadata_size_limit);
+ stream_parsing->seen_error = true;
+ stream_parsing->exceeded_metadata_size = true;
+ }
+ GRPC_MDELEM_UNREF(md);
+ } else {
+ grpc_chttp2_incoming_metadata_buffer_add(
+ &stream_parsing->metadata_buffer[0], md);
+ }
}
grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing);
@@ -658,12 +682,30 @@ static void on_trailing_header(void *tp, grpc_mdelem *md) {
if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
/* TODO(ctiller): check for a status like " 0" */
- stream_parsing->seen_error = 1;
+ stream_parsing->seen_error = true;
+ }
+
+ const size_t new_size =
+ stream_parsing->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md);
+ grpc_chttp2_transport_global *transport_global =
+ &TRANSPORT_FROM_PARSING(transport_parsing)->global;
+ const size_t metadata_size_limit =
+ transport_global->settings[GRPC_LOCAL_SETTINGS]
+ [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
+ if (new_size > metadata_size_limit) {
+ if (!stream_parsing->exceeded_metadata_size) {
+ gpr_log(GPR_DEBUG,
+ "received trailing metadata size exceeds limit (%lu vs. %lu)",
+ new_size, metadata_size_limit);
+ stream_parsing->seen_error = true;
+ stream_parsing->exceeded_metadata_size = true;
+ }
+ GRPC_MDELEM_UNREF(md);
+ } else {
+ grpc_chttp2_incoming_metadata_buffer_add(
+ &stream_parsing->metadata_buffer[1], md);
}
- grpc_chttp2_incoming_metadata_buffer_add(&stream_parsing->metadata_buffer[1],
- md);
-
grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing);
GPR_TIMER_END("on_trailing_header", 0);
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 0a51780a14..23c7b7b897 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -56,10 +56,6 @@ grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a,
/** Destroy arguments created by \a grpc_channel_args_copy */
void grpc_channel_args_destroy(grpc_channel_args *a);
-/** Reads census_enabled settings from channel args. Returns 1 if census_enabled
- * is specified in channel args, otherwise returns 0. */
-int grpc_channel_args_is_census_enabled(const grpc_channel_args *a);
-
/** Returns the compression algorithm set in \a a. */
grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
const grpc_channel_args *a);
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 7210aef5d5..e2869224f1 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -164,7 +164,7 @@ static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, int success) {
for (i = 0; i < tcp->incoming_buffer->count; i++) {
char *dump = gpr_dump_slice(tcp->incoming_buffer->slices[i],
GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "READ %p: %s", tcp, dump);
+ gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump);
gpr_free(dump);
}
}
@@ -398,7 +398,7 @@ static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
for (i = 0; i < buf->count; i++) {
char *data =
gpr_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "WRITE %p: %s", tcp, data);
+ gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data);
gpr_free(data);
}
}
diff --git a/src/core/lib/surface/version.c b/src/core/lib/surface/version.c
index fe954cbefb..aca76d2bb7 100644
--- a/src/core/lib/surface/version.c
+++ b/src/core/lib/surface/version.c
@@ -36,4 +36,4 @@
#include <grpc/grpc.h>
-const char *grpc_version_string(void) { return "0.14.0-dev"; }
+const char *grpc_version_string(void) { return "0.15.0-dev"; }
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 713d9e6782..6d82f4d681 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -147,6 +147,10 @@ const char *grpc_mdstr_as_c_string(grpc_mdstr *s);
#define GRPC_MDSTR_LENGTH(s) (GPR_SLICE_LENGTH(s->slice))
+/* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */
+#define GRPC_MDELEM_LENGTH(e) \
+ (GRPC_MDSTR_LENGTH((e)->key) + GRPC_MDSTR_LENGTH((e)->value) + 32)
+
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);
diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c
index 4567221a48..e4398abeb7 100644
--- a/src/core/lib/transport/metadata_batch.c
+++ b/src/core/lib/transport/metadata_batch.c
@@ -192,3 +192,12 @@ int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type),
batch->deadline) == 0;
}
+
+size_t grpc_metadata_batch_size(grpc_metadata_batch *batch) {
+ size_t size = 0;
+ for (grpc_linked_mdelem *elem = batch->list.head; elem != NULL;
+ elem = elem->next) {
+ size += GRPC_MDELEM_LENGTH(elem->md);
+ }
+ return size;
+}
diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h
index b62668876e..7af823f7ca 100644
--- a/src/core/lib/transport/metadata_batch.h
+++ b/src/core/lib/transport/metadata_batch.h
@@ -66,6 +66,9 @@ void grpc_metadata_batch_destroy(grpc_metadata_batch *batch);
void grpc_metadata_batch_clear(grpc_metadata_batch *batch);
int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch);
+/* Returns the transport size of the batch. */
+size_t grpc_metadata_batch_size(grpc_metadata_batch *batch);
+
/** Moves the metadata information from \a src to \a dst. Upon return, \a src is
* zeroed. */
void grpc_metadata_batch_move(grpc_metadata_batch *dst,