aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-04-27 15:29:25 -0700
committerGravatar Craig Tiller <ctiller@google.com>2017-04-27 15:29:25 -0700
commit86033d6b883e6530bf874f33f4e965322c8d7021 (patch)
treeeb46cfd8e4be56c157c60b7ec9df486b21ce5ee9 /src/core/lib
parent53e6b56e32c79ba401a67cb349519c12991539cc (diff)
parent4865c79548d4f83ebae4e10fbaf4c3ba10535c97 (diff)
Merge github.com:grpc/grpc into serve_fries
Diffstat (limited to 'src/core/lib')
-rw-r--r--src/core/lib/channel/connected_channel.c4
-rw-r--r--src/core/lib/compression/message_compress.c4
-rw-r--r--src/core/lib/http/httpcli_security_connector.c16
-rw-r--r--src/core/lib/iomgr/socket_mutator.h2
-rw-r--r--src/core/lib/iomgr/tcp_windows.c2
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.c76
-rw-r--r--src/core/lib/security/transport/client_auth_filter.c10
-rw-r--r--src/core/lib/security/transport/secure_endpoint.c8
-rw-r--r--src/core/lib/security/transport/security_connector.c75
-rw-r--r--src/core/lib/security/transport/security_connector.h24
-rw-r--r--src/core/lib/slice/b64.c2
-rw-r--r--src/core/lib/slice/percent_encoding.c6
-rw-r--r--src/core/lib/slice/slice.c99
-rw-r--r--src/core/lib/slice/slice_buffer.c31
-rw-r--r--src/core/lib/support/atomic.h45
-rw-r--r--src/core/lib/support/atomic_with_atm.h70
-rw-r--r--src/core/lib/support/atomic_with_std.h48
-rw-r--r--src/core/lib/support/avl.c28
-rw-r--r--src/core/lib/support/memory.h74
-rw-r--r--src/core/lib/surface/byte_buffer_reader.c2
-rw-r--r--src/core/lib/surface/lame_client.cc (renamed from src/core/lib/surface/lame_client.c)63
-rw-r--r--src/core/lib/surface/version.c2
22 files changed, 475 insertions, 216 deletions
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 22caf24373..d8985268eb 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -128,7 +128,9 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
channel_data *cd = (channel_data *)elem->channel_data;
- grpc_transport_destroy(exec_ctx, cd->transport);
+ if (cd->transport) {
+ grpc_transport_destroy(exec_ctx, cd->transport);
+ }
}
static char *con_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c
index 49beb953b0..fd3d1e6fcc 100644
--- a/src/core/lib/compression/message_compress.c
+++ b/src/core/lib/compression/message_compress.c
@@ -50,7 +50,7 @@ static int zlib_body(grpc_exec_ctx* exec_ctx, z_stream* zs,
int r;
int flush;
size_t i;
- grpc_slice outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE);
+ grpc_slice outbuf = GRPC_SLICE_MALLOC(OUTPUT_BLOCK_SIZE);
const uInt uint_max = ~(uInt)0;
GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max);
@@ -65,7 +65,7 @@ static int zlib_body(grpc_exec_ctx* exec_ctx, z_stream* zs,
do {
if (zs->avail_out == 0) {
grpc_slice_buffer_add_indexed(output, outbuf);
- outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE);
+ outbuf = GRPC_SLICE_MALLOC(OUTPUT_BLOCK_SIZE);
GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max);
zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf);
zs->next_out = GRPC_SLICE_START_PTR(outbuf);
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 9eab1360a4..76946434f0 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -106,9 +106,8 @@ static grpc_security_connector_vtable httpcli_ssl_vtable = {
httpcli_ssl_destroy, httpcli_ssl_check_peer};
static grpc_security_status httpcli_ssl_channel_security_connector_create(
- grpc_exec_ctx *exec_ctx, const unsigned char *pem_root_certs,
- size_t pem_root_certs_size, const char *secure_peer_name,
- grpc_channel_security_connector **sc) {
+ grpc_exec_ctx *exec_ctx, const char *pem_root_certs,
+ const char *secure_peer_name, grpc_channel_security_connector **sc) {
tsi_result result = TSI_OK;
grpc_httpcli_ssl_channel_security_connector *c;
@@ -126,8 +125,7 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
c->secure_peer_name = gpr_strdup(secure_peer_name);
}
result = tsi_create_ssl_client_handshaker_factory(
- NULL, 0, NULL, 0, pem_root_certs, pem_root_certs_size, NULL, NULL, NULL,
- 0, &c->handshaker_factory);
+ NULL, pem_root_certs, NULL, NULL, 0, &c->handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
@@ -173,10 +171,9 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg,
grpc_endpoint *endpoint)) {
grpc_channel_security_connector *sc = NULL;
- const unsigned char *pem_root_certs = NULL;
on_done_closure *c = gpr_malloc(sizeof(*c));
- size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
- if (pem_root_certs == NULL || pem_root_certs_size == 0) {
+ const char *pem_root_certs = grpc_get_default_ssl_roots();
+ if (pem_root_certs == NULL) {
gpr_log(GPR_ERROR, "Could not get default pem root certs.");
on_done(exec_ctx, arg, NULL);
gpr_free(c);
@@ -186,8 +183,7 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
c->arg = arg;
c->handshake_mgr = grpc_handshake_manager_create();
GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
- exec_ctx, pem_root_certs, pem_root_certs_size, host, &sc) ==
- GRPC_SECURITY_OK);
+ exec_ctx, pem_root_certs, host, &sc) == GRPC_SECURITY_OK);
grpc_channel_security_connector_add_handshakers(exec_ctx, sc,
c->handshake_mgr);
grpc_handshake_manager_do_handshake(
diff --git a/src/core/lib/iomgr/socket_mutator.h b/src/core/lib/iomgr/socket_mutator.h
index 2f5b6c248e..28b1710ec4 100644
--- a/src/core/lib/iomgr/socket_mutator.h
+++ b/src/core/lib/iomgr/socket_mutator.h
@@ -37,6 +37,8 @@
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/sync.h>
+#include <stdbool.h>
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index f74aa68793..bdd4dd07af 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -219,7 +219,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
tcp->read_slices = read_slices;
grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices);
- tcp->read_slice = grpc_slice_malloc(8192);
+ tcp->read_slice = GRPC_SLICE_MALLOC(8192);
buffer.len = (ULONG)GRPC_SLICE_LENGTH(
tcp->read_slice); // we know slice size fits in 32bit.
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.c b/src/core/lib/security/credentials/ssl/ssl_credentials.c
index b63bb6b6e9..7c35ebe684 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.c
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.c
@@ -40,28 +40,24 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
//
-// Utils
+// SSL Channel Credentials.
//
-static void ssl_copy_key_material(const char *input, unsigned char **output,
- size_t *output_size) {
- *output_size = strlen(input);
- *output = gpr_malloc(*output_size);
- memcpy(*output, input, *output_size);
+static void ssl_config_pem_key_cert_pair_destroy(
+ tsi_ssl_pem_key_cert_pair *kp) {
+ if (kp == NULL) return;
+ gpr_free((void *)kp->private_key);
+ gpr_free((void *)kp->cert_chain);
}
-//
-// SSL Channel Credentials.
-//
-
static void ssl_destruct(grpc_exec_ctx *exec_ctx,
grpc_channel_credentials *creds) {
grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
- if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
- if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
- if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain);
+ gpr_free(c->config.pem_root_certs);
+ ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pair);
}
static grpc_security_status ssl_create_security_connector(
@@ -102,18 +98,15 @@ static void ssl_build_config(const char *pem_root_certs,
grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
grpc_ssl_config *config) {
if (pem_root_certs != NULL) {
- ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
- &config->pem_root_certs_size);
+ config->pem_root_certs = gpr_strdup(pem_root_certs);
}
if (pem_key_cert_pair != NULL) {
GPR_ASSERT(pem_key_cert_pair->private_key != NULL);
GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL);
- ssl_copy_key_material(pem_key_cert_pair->private_key,
- &config->pem_private_key,
- &config->pem_private_key_size);
- ssl_copy_key_material(pem_key_cert_pair->cert_chain,
- &config->pem_cert_chain,
- &config->pem_cert_chain_size);
+ config->pem_key_cert_pair.cert_chain =
+ gpr_strdup(pem_key_cert_pair->cert_chain);
+ config->pem_key_cert_pair.private_key =
+ gpr_strdup(pem_key_cert_pair->private_key);
}
}
@@ -143,22 +136,10 @@ static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
size_t i;
for (i = 0; i < c->config.num_key_cert_pairs; i++) {
- if (c->config.pem_private_keys[i] != NULL) {
- gpr_free(c->config.pem_private_keys[i]);
- }
- if (c->config.pem_cert_chains[i] != NULL) {
- gpr_free(c->config.pem_cert_chains[i]);
- }
- }
- if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys);
- if (c->config.pem_private_keys_sizes != NULL) {
- gpr_free(c->config.pem_private_keys_sizes);
- }
- if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains);
- if (c->config.pem_cert_chains_sizes != NULL) {
- gpr_free(c->config.pem_cert_chains_sizes);
+ ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pairs[i]);
}
- if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
+ gpr_free(c->config.pem_key_cert_pairs);
+ gpr_free(c->config.pem_root_certs);
}
static grpc_security_status ssl_server_create_security_connector(
@@ -179,30 +160,21 @@ static void ssl_build_server_config(
size_t i;
config->client_certificate_request = client_certificate_request;
if (pem_root_certs != NULL) {
- ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
- &config->pem_root_certs_size);
+ config->pem_root_certs = gpr_strdup(pem_root_certs);
}
if (num_key_cert_pairs > 0) {
GPR_ASSERT(pem_key_cert_pairs != NULL);
- config->pem_private_keys =
- gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
- config->pem_cert_chains =
- gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
- config->pem_private_keys_sizes =
- gpr_malloc(num_key_cert_pairs * sizeof(size_t));
- config->pem_cert_chains_sizes =
- gpr_malloc(num_key_cert_pairs * sizeof(size_t));
+ config->pem_key_cert_pairs =
+ gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair));
}
config->num_key_cert_pairs = num_key_cert_pairs;
for (i = 0; i < num_key_cert_pairs; i++) {
GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
- ssl_copy_key_material(pem_key_cert_pairs[i].private_key,
- &config->pem_private_keys[i],
- &config->pem_private_keys_sizes[i]);
- ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain,
- &config->pem_cert_chains[i],
- &config->pem_cert_chains_sizes[i]);
+ config->pem_key_cert_pairs[i].cert_chain =
+ gpr_strdup(pem_key_cert_pairs[i].cert_chain);
+ config->pem_key_cert_pairs[i].private_key =
+ gpr_strdup(pem_key_cert_pairs[i].private_key);
}
}
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index f526653ffa..1f0daf7325 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -343,8 +343,16 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element_args *args) {
grpc_security_connector *sc =
grpc_security_connector_find_in_args(args->channel_args);
+ if (sc == NULL) {
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Security connector missing from client auth filter args");
+ }
grpc_auth_context *auth_context =
grpc_find_auth_context_in_args(args->channel_args);
+ if (auth_context == NULL) {
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Auth context missing from client auth filter args");
+ }
/* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data;
@@ -353,8 +361,6 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
handle the case that there's no 'next' filter to call on the up or down
path */
GPR_ASSERT(!args->is_last);
- GPR_ASSERT(sc != NULL);
- GPR_ASSERT(auth_context != NULL);
/* initialize members */
chand->security_connector =
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 24da949e48..0d5c7432c6 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -130,7 +130,7 @@ static void secure_endpoint_ref(secure_endpoint *ep) { gpr_ref(&ep->ref); }
static void flush_read_staging_buffer(secure_endpoint *ep, uint8_t **cur,
uint8_t **end) {
grpc_slice_buffer_add(ep->read_buffer, ep->read_staging_buffer);
- ep->read_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
+ ep->read_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
*cur = GRPC_SLICE_START_PTR(ep->read_staging_buffer);
*end = GRPC_SLICE_END_PTR(ep->read_staging_buffer);
}
@@ -252,7 +252,7 @@ static void endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
static void flush_write_staging_buffer(secure_endpoint *ep, uint8_t **cur,
uint8_t **end) {
grpc_slice_buffer_add(&ep->output_buffer, ep->write_staging_buffer);
- ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
+ ep->write_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
*cur = GRPC_SLICE_START_PTR(ep->write_staging_buffer);
*end = GRPC_SLICE_END_PTR(ep->write_staging_buffer);
}
@@ -415,8 +415,8 @@ grpc_endpoint *grpc_secure_endpoint_create(
grpc_slice_buffer_add(&ep->leftover_bytes,
grpc_slice_ref_internal(leftover_slices[i]));
}
- ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
- ep->read_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
+ ep->write_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
+ ep->read_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE);
grpc_slice_buffer_init(&ep->output_buffer);
grpc_slice_buffer_init(&ep->source_buffer);
ep->read_buffer = NULL;
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index b15196e677..30431a4e4a 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -78,9 +78,8 @@ void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
/* Defines the cipher suites that we accept by default. All these cipher suites
are compliant with HTTP2. */
-#define GRPC_SSL_CIPHER_SUITES \
- "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \
- "SHA384:ECDHE-RSA-AES256-GCM-SHA384"
+#define GRPC_SSL_CIPHER_SUITES \
+ "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384"
static gpr_once cipher_suites_once = GPR_ONCE_INIT;
static const char *cipher_suites = NULL;
@@ -695,6 +694,7 @@ static grpc_security_connector_vtable ssl_channel_vtable = {
static grpc_security_connector_vtable ssl_server_vtable = {
ssl_server_destroy, ssl_server_check_peer};
+/* returns a NULL terminated slice. */
static grpc_slice compute_default_pem_root_certs_once(void) {
grpc_slice result = grpc_empty_slice();
@@ -703,7 +703,7 @@ static grpc_slice compute_default_pem_root_certs_once(void) {
gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
if (default_root_certs_path != NULL) {
GRPC_LOG_IF_ERROR("load_file",
- grpc_load_file(default_root_certs_path, 0, &result));
+ grpc_load_file(default_root_certs_path, 1, &result));
gpr_free(default_root_certs_path);
}
@@ -714,15 +714,18 @@ static grpc_slice compute_default_pem_root_certs_once(void) {
ovrd_res = ssl_roots_override_cb(&pem_root_certs);
if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) {
GPR_ASSERT(pem_root_certs != NULL);
- result = grpc_slice_new(pem_root_certs, strlen(pem_root_certs), gpr_free);
+ result = grpc_slice_from_copied_buffer(
+ pem_root_certs,
+ strlen(pem_root_certs) + 1); // NULL terminator.
}
+ gpr_free(pem_root_certs);
}
/* Fall back to installed certs if needed. */
if (GRPC_SLICE_IS_EMPTY(result) &&
ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
GRPC_LOG_IF_ERROR("load_file",
- grpc_load_file(installed_roots_path, 0, &result));
+ grpc_load_file(installed_roots_path, 1, &result));
}
return result;
}
@@ -762,13 +765,14 @@ get_tsi_client_certificate_request_type(
}
}
-size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
+const char *grpc_get_default_ssl_roots(void) {
/* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
loading all the roots once for the lifetime of the process. */
static gpr_once once = GPR_ONCE_INIT;
gpr_once_init(&once, init_default_pem_root_certs);
- *pem_root_certs = GRPC_SLICE_START_PTR(default_pem_root_certs);
- return GRPC_SLICE_LENGTH(default_pem_root_certs);
+ return GRPC_SLICE_IS_EMPTY(default_pem_root_certs)
+ ? NULL
+ : (const char *)GRPC_SLICE_START_PTR(default_pem_root_certs);
}
grpc_security_status grpc_ssl_channel_security_connector_create(
@@ -776,22 +780,16 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
- const unsigned char **alpn_protocol_strings =
+ const char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols);
- unsigned char *alpn_protocol_string_lengths =
- gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
tsi_result result = TSI_OK;
grpc_ssl_channel_security_connector *c;
size_t i;
- const unsigned char *pem_root_certs;
- size_t pem_root_certs_size;
+ const char *pem_root_certs;
char *port;
for (i = 0; i < num_alpn_protocols; i++) {
- alpn_protocol_strings[i] =
- (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
- alpn_protocol_string_lengths[i] =
- (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
+ alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
}
if (config == NULL || target_name == NULL) {
@@ -799,14 +797,13 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
goto error;
}
if (config->pem_root_certs == NULL) {
- pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
- if (pem_root_certs == NULL || pem_root_certs_size == 0) {
+ pem_root_certs = grpc_get_default_ssl_roots();
+ if (pem_root_certs == NULL) {
gpr_log(GPR_ERROR, "Could not get default pem root certs.");
goto error;
}
} else {
pem_root_certs = config->pem_root_certs;
- pem_root_certs_size = config->pem_root_certs_size;
}
c = gpr_zalloc(sizeof(grpc_ssl_channel_security_connector));
@@ -823,11 +820,12 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
if (overridden_target_name != NULL) {
c->overridden_target_name = gpr_strdup(overridden_target_name);
}
+
+ bool has_key_cert_pair = config->pem_key_cert_pair.private_key != NULL &&
+ config->pem_key_cert_pair.cert_chain != NULL;
result = tsi_create_ssl_client_handshaker_factory(
- config->pem_private_key, config->pem_private_key_size,
- config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs,
- pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings,
- alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
+ has_key_cert_pair ? &config->pem_key_cert_pair : NULL, pem_root_certs,
+ ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
&c->handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
@@ -838,12 +836,10 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
}
*sc = &c->base;
gpr_free((void *)alpn_protocol_strings);
- gpr_free(alpn_protocol_string_lengths);
return GRPC_SECURITY_OK;
error:
gpr_free((void *)alpn_protocol_strings);
- gpr_free(alpn_protocol_string_lengths);
return GRPC_SECURITY_ERROR;
}
@@ -851,19 +847,14 @@ grpc_security_status grpc_ssl_server_security_connector_create(
grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
grpc_server_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
- const unsigned char **alpn_protocol_strings =
+ const char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols);
- unsigned char *alpn_protocol_string_lengths =
- gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
tsi_result result = TSI_OK;
grpc_ssl_server_security_connector *c;
size_t i;
for (i = 0; i < num_alpn_protocols; i++) {
- alpn_protocol_strings[i] =
- (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
- alpn_protocol_string_lengths[i] =
- (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
+ alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
}
if (config == NULL || config->num_key_cert_pairs == 0) {
@@ -876,15 +867,11 @@ grpc_security_status grpc_ssl_server_security_connector_create(
c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
c->base.base.vtable = &ssl_server_vtable;
result = tsi_create_ssl_server_handshaker_factory_ex(
- (const unsigned char **)config->pem_private_keys,
- config->pem_private_keys_sizes,
- (const unsigned char **)config->pem_cert_chains,
- config->pem_cert_chains_sizes, config->num_key_cert_pairs,
- config->pem_root_certs, config->pem_root_certs_size,
- get_tsi_client_certificate_request_type(
- config->client_certificate_request),
- ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths,
- (uint16_t)num_alpn_protocols, &c->handshaker_factory);
+ config->pem_key_cert_pairs, config->num_key_cert_pairs,
+ config->pem_root_certs, get_tsi_client_certificate_request_type(
+ config->client_certificate_request),
+ ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
+ &c->handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
@@ -895,11 +882,9 @@ grpc_security_status grpc_ssl_server_security_connector_create(
c->base.add_handshakers = ssl_server_add_handshakers;
*sc = &c->base;
gpr_free((void *)alpn_protocol_strings);
- gpr_free(alpn_protocol_string_lengths);
return GRPC_SECURITY_OK;
error:
gpr_free((void *)alpn_protocol_strings);
- gpr_free(alpn_protocol_string_lengths);
return GRPC_SECURITY_ERROR;
}
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index cf56cb3183..d74f6739c0 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -34,11 +34,14 @@
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
+#include <stdbool.h>
+
#include <grpc/grpc_security.h>
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/tcp_server.h"
+#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
/* --- status enum. --- */
@@ -184,13 +187,10 @@ grpc_server_security_connector *grpc_fake_server_security_connector_create(
void);
/* Config for ssl clients. */
+
typedef struct {
- unsigned char *pem_private_key;
- size_t pem_private_key_size;
- unsigned char *pem_cert_chain;
- size_t pem_cert_chain_size;
- unsigned char *pem_root_certs;
- size_t pem_root_certs_size;
+ tsi_ssl_pem_key_cert_pair pem_key_cert_pair;
+ char *pem_root_certs;
} grpc_ssl_config;
/* Creates an SSL channel_security_connector.
@@ -211,21 +211,17 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc);
-/* Gets the default ssl roots. */
-size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs);
+/* Gets the default ssl roots. Returns NULL if not found. */
+const char *grpc_get_default_ssl_roots(void);
/* Exposed for TESTING ONLY!. */
grpc_slice grpc_get_default_ssl_roots_for_testing(void);
/* Config for ssl servers. */
typedef struct {
- unsigned char **pem_private_keys;
- size_t *pem_private_keys_sizes;
- unsigned char **pem_cert_chains;
- size_t *pem_cert_chains_sizes;
+ tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs;
size_t num_key_cert_pairs;
- unsigned char *pem_root_certs;
- size_t pem_root_certs_size;
+ char *pem_root_certs;
grpc_ssl_client_certificate_request_type client_certificate_request;
} grpc_ssl_server_config;
diff --git a/src/core/lib/slice/b64.c b/src/core/lib/slice/b64.c
index 2007cc4810..d9091646e0 100644
--- a/src/core/lib/slice/b64.c
+++ b/src/core/lib/slice/b64.c
@@ -202,7 +202,7 @@ static int decode_group(const unsigned char *codes, size_t num_codes,
grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
size_t b64_len, int url_safe) {
- grpc_slice result = grpc_slice_malloc(b64_len);
+ grpc_slice result = GRPC_SLICE_MALLOC(b64_len);
unsigned char *current = GRPC_SLICE_START_PTR(result);
size_t result_size = 0;
unsigned char codes[4];
diff --git a/src/core/lib/slice/percent_encoding.c b/src/core/lib/slice/percent_encoding.c
index c76c58d371..a77c69763f 100644
--- a/src/core/lib/slice/percent_encoding.c
+++ b/src/core/lib/slice/percent_encoding.c
@@ -71,7 +71,7 @@ grpc_slice grpc_percent_encode_slice(grpc_slice slice,
return grpc_slice_ref_internal(slice);
}
// second pass: actually encode
- grpc_slice out = grpc_slice_malloc(output_length);
+ grpc_slice out = GRPC_SLICE_MALLOC(output_length);
uint8_t *q = GRPC_SLICE_START_PTR(out);
for (p = slice_start; p < slice_end; p++) {
if (is_unreserved_character(*p, unreserved_bytes)) {
@@ -125,7 +125,7 @@ bool grpc_strict_percent_decode_slice(grpc_slice slice_in,
return true;
}
p = GRPC_SLICE_START_PTR(slice_in);
- *slice_out = grpc_slice_malloc(out_length);
+ *slice_out = GRPC_SLICE_MALLOC(out_length);
uint8_t *q = GRPC_SLICE_START_PTR(*slice_out);
while (p != in_end) {
if (*p == '%') {
@@ -163,7 +163,7 @@ grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in) {
return grpc_slice_ref_internal(slice_in);
}
p = GRPC_SLICE_START_PTR(slice_in);
- grpc_slice out = grpc_slice_malloc(out_length);
+ grpc_slice out = GRPC_SLICE_MALLOC(out_length);
uint8_t *q = GRPC_SLICE_START_PTR(out);
while (p != in_end) {
if (*p == '%') {
diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c
index a2fcbbdbdf..b90738fd1a 100644
--- a/src/core/lib/slice/slice.c
+++ b/src/core/lib/slice/slice.c
@@ -55,6 +55,13 @@ grpc_slice grpc_empty_slice(void) {
return out;
}
+grpc_slice grpc_slice_copy(grpc_slice s) {
+ grpc_slice out = GRPC_SLICE_MALLOC(GRPC_SLICE_LENGTH(s));
+ memcpy(GRPC_SLICE_START_PTR(out), GRPC_SLICE_START_PTR(s),
+ GRPC_SLICE_LENGTH(s));
+ return out;
+}
+
grpc_slice grpc_slice_ref_internal(grpc_slice slice) {
if (slice.refcount) {
slice.refcount->vtable->ref(slice.refcount);
@@ -198,7 +205,7 @@ grpc_slice grpc_slice_new_with_len(void *p, size_t len,
grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t length) {
if (length == 0) return grpc_empty_slice();
- grpc_slice slice = grpc_slice_malloc(length);
+ grpc_slice slice = GRPC_SLICE_MALLOC(length);
memcpy(GRPC_SLICE_START_PTR(slice), source, length);
return slice;
}
@@ -228,35 +235,42 @@ static const grpc_slice_refcount_vtable malloc_vtable = {
malloc_ref, malloc_unref, grpc_slice_default_eq_impl,
grpc_slice_default_hash_impl};
+grpc_slice grpc_slice_malloc_large(size_t length) {
+ grpc_slice slice;
+
+ /* Memory layout used by the slice created here:
+
+ +-----------+----------------------------------------------------------+
+ | refcount | bytes |
+ +-----------+----------------------------------------------------------+
+
+ refcount is a malloc_refcount
+ bytes is an array of bytes of the requested length
+ Both parts are placed in the same allocation returned from gpr_malloc */
+ malloc_refcount *rc = gpr_malloc(sizeof(malloc_refcount) + length);
+
+ /* Initial refcount on rc is 1 - and it's up to the caller to release
+ this reference. */
+ gpr_ref_init(&rc->refs, 1);
+
+ rc->base.vtable = &malloc_vtable;
+ rc->base.sub_refcount = &rc->base;
+
+ /* Build up the slice to be returned. */
+ /* The slices refcount points back to the allocated block. */
+ slice.refcount = &rc->base;
+ /* The data bytes are placed immediately after the refcount struct */
+ slice.data.refcounted.bytes = (uint8_t *)(rc + 1);
+ /* And the length of the block is set to the requested length */
+ slice.data.refcounted.length = length;
+ return slice;
+}
+
grpc_slice grpc_slice_malloc(size_t length) {
grpc_slice slice;
if (length > sizeof(slice.data.inlined.bytes)) {
- /* Memory layout used by the slice created here:
-
- +-----------+----------------------------------------------------------+
- | refcount | bytes |
- +-----------+----------------------------------------------------------+
-
- refcount is a malloc_refcount
- bytes is an array of bytes of the requested length
- Both parts are placed in the same allocation returned from gpr_malloc */
- malloc_refcount *rc = gpr_malloc(sizeof(malloc_refcount) + length);
-
- /* Initial refcount on rc is 1 - and it's up to the caller to release
- this reference. */
- gpr_ref_init(&rc->refs, 1);
-
- rc->base.vtable = &malloc_vtable;
- rc->base.sub_refcount = &rc->base;
-
- /* Build up the slice to be returned. */
- /* The slices refcount points back to the allocated block. */
- slice.refcount = &rc->base;
- /* The data bytes are placed immediately after the refcount struct */
- slice.data.refcounted.bytes = (uint8_t *)(rc + 1);
- /* And the length of the block is set to the requested length */
- slice.data.refcounted.length = length;
+ return grpc_slice_malloc_large(length);
} else {
/* small slice: just inline the data */
slice.refcount = NULL;
@@ -306,7 +320,8 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) {
return subset;
}
-grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
+grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *source, size_t split,
+ grpc_slice_ref_whom ref_whom) {
grpc_slice tail;
if (source->refcount == NULL) {
@@ -320,28 +335,46 @@ grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
} else {
size_t tail_length = source->data.refcounted.length - split;
GPR_ASSERT(source->data.refcounted.length >= split);
- if (tail_length < sizeof(tail.data.inlined.bytes)) {
+ if (tail_length < sizeof(tail.data.inlined.bytes) &&
+ ref_whom != GRPC_SLICE_REF_TAIL) {
/* Copy out the bytes - it'll be cheaper than refcounting */
tail.refcount = NULL;
tail.data.inlined.length = (uint8_t)tail_length;
memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split,
tail_length);
+ source->refcount = source->refcount->sub_refcount;
} else {
/* Build the result */
- tail.refcount = source->refcount->sub_refcount;
- /* Bump the refcount */
- tail.refcount->vtable->ref(tail.refcount);
+ switch (ref_whom) {
+ case GRPC_SLICE_REF_TAIL:
+ tail.refcount = source->refcount->sub_refcount;
+ source->refcount = &noop_refcount;
+ break;
+ case GRPC_SLICE_REF_HEAD:
+ tail.refcount = &noop_refcount;
+ source->refcount = source->refcount->sub_refcount;
+ break;
+ case GRPC_SLICE_REF_BOTH:
+ tail.refcount = source->refcount->sub_refcount;
+ source->refcount = source->refcount->sub_refcount;
+ /* Bump the refcount */
+ tail.refcount->vtable->ref(tail.refcount);
+ break;
+ }
/* Point into the source array */
tail.data.refcounted.bytes = source->data.refcounted.bytes + split;
tail.data.refcounted.length = tail_length;
}
- source->refcount = source->refcount->sub_refcount;
source->data.refcounted.length = split;
}
return tail;
}
+grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
+ return grpc_slice_split_tail_maybe_ref(source, split, GRPC_SLICE_REF_BOTH);
+}
+
grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
grpc_slice head;
@@ -459,7 +492,7 @@ int grpc_slice_slice(grpc_slice haystack, grpc_slice needle) {
}
grpc_slice grpc_slice_dup(grpc_slice a) {
- grpc_slice copy = grpc_slice_malloc(GRPC_SLICE_LENGTH(a));
+ grpc_slice copy = GRPC_SLICE_MALLOC(GRPC_SLICE_LENGTH(a));
memcpy(GRPC_SLICE_START_PTR(copy), GRPC_SLICE_START_PTR(a),
GRPC_SLICE_LENGTH(a));
return copy;
diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c
index c96b9c3b28..e8d41ca0f7 100644
--- a/src/core/lib/slice/slice_buffer.c
+++ b/src/core/lib/slice/slice_buffer.c
@@ -253,16 +253,18 @@ void grpc_slice_buffer_move_into(grpc_slice_buffer *src,
src->length = 0;
}
-void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
- grpc_slice_buffer *dst) {
- size_t output_len = dst->length + n;
- size_t new_input_len = src->length - n;
+static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer *src, size_t n,
+ grpc_slice_buffer *dst,
+ bool incref) {
GPR_ASSERT(src->length >= n);
if (src->length == n) {
grpc_slice_buffer_move_into(src, dst);
return;
}
+ size_t output_len = dst->length + n;
+ size_t new_input_len = src->length - n;
+
while (src->count > 0) {
grpc_slice slice = grpc_slice_buffer_take_first(src);
size_t slice_len = GRPC_SLICE_LENGTH(slice);
@@ -272,11 +274,18 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
} else if (n == slice_len) {
grpc_slice_buffer_add(dst, slice);
break;
- } else { /* n < slice_len */
- grpc_slice_buffer_undo_take_first(src, grpc_slice_split_tail(&slice, n));
+ } else if (incref) { /* n < slice_len */
+ grpc_slice_buffer_undo_take_first(
+ src, grpc_slice_split_tail_maybe_ref(&slice, n, GRPC_SLICE_REF_BOTH));
GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
grpc_slice_buffer_add(dst, slice);
break;
+ } else { /* n < slice_len */
+ grpc_slice_buffer_undo_take_first(
+ src, grpc_slice_split_tail_maybe_ref(&slice, n, GRPC_SLICE_REF_TAIL));
+ GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
+ grpc_slice_buffer_add_indexed(dst, slice);
+ break;
}
}
GPR_ASSERT(dst->length == output_len);
@@ -284,6 +293,16 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
GPR_ASSERT(src->count > 0);
}
+void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
+ grpc_slice_buffer *dst) {
+ slice_buffer_move_first_maybe_ref(src, n, dst, true);
+}
+
+void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src, size_t n,
+ grpc_slice_buffer *dst) {
+ slice_buffer_move_first_maybe_ref(src, n, dst, false);
+}
+
void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx,
grpc_slice_buffer *src, size_t n,
void *dst) {
diff --git a/src/core/lib/support/atomic.h b/src/core/lib/support/atomic.h
new file mode 100644
index 0000000000..2226189b68
--- /dev/null
+++ b/src/core/lib/support/atomic.h
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_H
+#define GRPC_CORE_LIB_SUPPORT_ATOMIC_H
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_HAS_CXX11_ATOMIC
+#include "src/core/lib/support/atomic_with_std.h"
+#else
+#include "src/core/lib/support/atomic_with_atm.h"
+#endif
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_H */
diff --git a/src/core/lib/support/atomic_with_atm.h b/src/core/lib/support/atomic_with_atm.h
new file mode 100644
index 0000000000..55727f1dee
--- /dev/null
+++ b/src/core/lib/support/atomic_with_atm.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
+#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
+
+#include <grpc/support/atm.h>
+
+namespace grpc_core {
+
+enum MemoryOrderRelaxed { memory_order_relaxed };
+
+template <class T>
+class atomic;
+
+template <>
+class atomic<bool> {
+ public:
+ atomic() { gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(false)); }
+ explicit atomic(bool x) {
+ gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(x));
+ }
+
+ bool compare_exchange_strong(bool& expected, bool update, MemoryOrderRelaxed,
+ MemoryOrderRelaxed) {
+ if (!gpr_atm_no_barrier_cas(&x_, static_cast<gpr_atm>(expected),
+ static_cast<gpr_atm>(update))) {
+ expected = gpr_atm_no_barrier_load(&x_) != 0;
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ gpr_atm x_;
+};
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H */
diff --git a/src/core/lib/support/atomic_with_std.h b/src/core/lib/support/atomic_with_std.h
new file mode 100644
index 0000000000..7e9c19efe8
--- /dev/null
+++ b/src/core/lib/support/atomic_with_std.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
+#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
+
+#include <atomic>
+
+namespace grpc_core {
+
+template <class T>
+using atomic = std::atomic<T>;
+
+typedef std::memory_order memory_order;
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H */
diff --git a/src/core/lib/support/avl.c b/src/core/lib/support/avl.c
index acf8fd5a55..ffa10c1e4f 100644
--- a/src/core/lib/support/avl.c
+++ b/src/core/lib/support/avl.c
@@ -205,8 +205,8 @@ static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key,
}
}
-static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node,
- void *key, void *value) {
+static gpr_avl_node *add_key(const gpr_avl_vtable *vtable, gpr_avl_node *node,
+ void *key, void *value) {
long cmp;
if (node == NULL) {
return new_node(key, value, NULL, NULL);
@@ -217,17 +217,17 @@ static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node,
} else if (cmp > 0) {
return rebalance(
vtable, vtable->copy_key(node->key), vtable->copy_value(node->value),
- add(vtable, node->left, key, value), ref_node(node->right));
+ add_key(vtable, node->left, key, value), ref_node(node->right));
} else {
return rebalance(vtable, vtable->copy_key(node->key),
vtable->copy_value(node->value), ref_node(node->left),
- add(vtable, node->right, key, value));
+ add_key(vtable, node->right, key, value));
}
}
gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value) {
gpr_avl_node *old_root = avl.root;
- avl.root = add(avl.vtable, avl.root, key, value);
+ avl.root = add_key(avl.vtable, avl.root, key, value);
assert_invariants(avl.root);
unref_node(avl.vtable, old_root);
return avl;
@@ -247,8 +247,8 @@ static gpr_avl_node *in_order_tail(gpr_avl_node *node) {
return node;
}
-static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node,
- void *key) {
+static gpr_avl_node *remove_key(const gpr_avl_vtable *vtable,
+ gpr_avl_node *node, void *key) {
long cmp;
if (node == NULL) {
return NULL;
@@ -263,27 +263,27 @@ static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node,
gpr_avl_node *h = in_order_head(node->right);
return rebalance(vtable, vtable->copy_key(h->key),
vtable->copy_value(h->value), ref_node(node->left),
- remove(vtable, node->right, h->key));
+ remove_key(vtable, node->right, h->key));
} else {
gpr_avl_node *h = in_order_tail(node->left);
return rebalance(
vtable, vtable->copy_key(h->key), vtable->copy_value(h->value),
- remove(vtable, node->left, h->key), ref_node(node->right));
+ remove_key(vtable, node->left, h->key), ref_node(node->right));
}
} else if (cmp > 0) {
- return rebalance(vtable, vtable->copy_key(node->key),
- vtable->copy_value(node->value),
- remove(vtable, node->left, key), ref_node(node->right));
+ return rebalance(
+ vtable, vtable->copy_key(node->key), vtable->copy_value(node->value),
+ remove_key(vtable, node->left, key), ref_node(node->right));
} else {
return rebalance(vtable, vtable->copy_key(node->key),
vtable->copy_value(node->value), ref_node(node->left),
- remove(vtable, node->right, key));
+ remove_key(vtable, node->right, key));
}
}
gpr_avl gpr_avl_remove(gpr_avl avl, void *key) {
gpr_avl_node *old_root = avl.root;
- avl.root = remove(avl.vtable, avl.root, key);
+ avl.root = remove_key(avl.vtable, avl.root, key);
assert_invariants(avl.root);
unref_node(avl.vtable, old_root);
return avl;
diff --git a/src/core/lib/support/memory.h b/src/core/lib/support/memory.h
new file mode 100644
index 0000000000..6eff94eff7
--- /dev/null
+++ b/src/core/lib/support/memory.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SUPPORT_MEMORY_H
+#define GRPC_CORE_LIB_SUPPORT_MEMORY_H
+
+#include <grpc/support/alloc.h>
+
+#include <memory>
+#include <utility>
+
+namespace grpc_core {
+
+// Alternative to new, since we cannot use it (for fear of libstdc++)
+template <typename T, typename... Args>
+inline T* New(Args&&... args) {
+ void* p = gpr_malloc(sizeof(T));
+ return new (p) T(std::forward<Args>(args)...);
+}
+
+// Alternative to delete, since we cannot use it (for fear of libstdc++)
+template <typename T>
+inline void Delete(T* p) {
+ p->~T();
+ gpr_free(p);
+}
+
+template <typename T>
+class DefaultDelete {
+ public:
+ void operator()(T* p) { Delete(p); }
+};
+
+template <typename T, typename Deleter = DefaultDelete<T>>
+using UniquePtr = std::unique_ptr<T, Deleter>;
+
+template <typename T, typename... Args>
+inline UniquePtr<T> MakeUnique(Args&&... args) {
+ return UniquePtr<T>(New<T>(std::forward<Args>(args)...));
+}
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SUPPORT_MEMORY_H */
diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c
index 1a6ccdaddb..539b014278 100644
--- a/src/core/lib/surface/byte_buffer_reader.c
+++ b/src/core/lib/surface/byte_buffer_reader.c
@@ -124,7 +124,7 @@ grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) {
grpc_slice in_slice;
size_t bytes_read = 0;
const size_t input_size = grpc_byte_buffer_length(reader->buffer_out);
- grpc_slice out_slice = grpc_slice_malloc(input_size);
+ grpc_slice out_slice = GRPC_SLICE_MALLOC(input_size);
uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.cc
index 82428c42c0..88f4eaac08 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.cc
@@ -31,39 +31,50 @@
*
*/
-#include "src/core/lib/surface/lame_client.h"
-
#include <grpc/grpc.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+
+#include "src/core/lib/support/atomic.h"
+
+extern "C" {
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/surface/lame_client.h"
#include "src/core/lib/transport/static_metadata.h"
+}
-typedef struct {
+namespace grpc_core {
+
+namespace {
+
+struct CallData {
grpc_linked_mdelem status;
grpc_linked_mdelem details;
- gpr_atm filled_metadata;
-} call_data;
+ grpc_core::atomic<bool> filled_metadata;
+};
-typedef struct {
+struct ChannelData {
grpc_status_code error_code;
const char *error_message;
-} channel_data;
+};
static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_metadata_batch *mdb) {
- call_data *calld = elem->call_data;
- if (!gpr_atm_no_barrier_cas(&calld->filled_metadata, 0, 1)) {
+ CallData *calld = static_cast<CallData *>(elem->call_data);
+ bool expected = false;
+ if (!calld->filled_metadata.compare_exchange_strong(
+ expected, true, grpc_core::memory_order_relaxed,
+ grpc_core::memory_order_relaxed)) {
return;
}
- channel_data *chand = elem->channel_data;
+ ChannelData *chand = static_cast<ChannelData *>(elem->channel_data);
char tmp[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(chand->error_code, tmp);
calld->status.md = grpc_mdelem_from_slices(
@@ -83,7 +94,6 @@ static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
static void lame_start_transport_stream_op_batch(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_transport_stream_op_batch *op) {
- GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
if (op->recv_initial_metadata) {
fill_metadata(exec_ctx, elem,
op->payload->recv_initial_metadata.recv_initial_metadata);
@@ -127,8 +137,6 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx,
static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
const grpc_call_element_args *args) {
- call_data *calld = elem->call_data;
- gpr_atm_no_barrier_store(&calld->filled_metadata, 0);
return GRPC_ERROR_NONE;
}
@@ -149,18 +157,22 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {}
-const grpc_channel_filter grpc_lame_filter = {
- lame_start_transport_stream_op_batch,
- lame_start_transport_op,
- sizeof(call_data),
- init_call_elem,
+} // namespace
+
+} // namespace grpc_core
+
+extern "C" const grpc_channel_filter grpc_lame_filter = {
+ grpc_core::lame_start_transport_stream_op_batch,
+ grpc_core::lame_start_transport_op,
+ sizeof(grpc_core::CallData),
+ grpc_core::init_call_elem,
grpc_call_stack_ignore_set_pollset_or_pollset_set,
- destroy_call_elem,
- sizeof(channel_data),
- init_channel_elem,
- destroy_channel_elem,
- lame_get_peer,
- lame_get_channel_info,
+ grpc_core::destroy_call_elem,
+ sizeof(grpc_core::ChannelData),
+ grpc_core::init_channel_elem,
+ grpc_core::destroy_channel_elem,
+ grpc_core::lame_get_peer,
+ grpc_core::lame_get_channel_info,
"lame-client",
};
@@ -171,7 +183,6 @@ grpc_channel *grpc_lame_client_channel_create(const char *target,
const char *error_message) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_channel_element *elem;
- channel_data *chand;
grpc_channel *channel = grpc_channel_create(&exec_ctx, target, NULL,
GRPC_CLIENT_LAME_CHANNEL, NULL);
elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
@@ -180,7 +191,7 @@ grpc_channel *grpc_lame_client_channel_create(const char *target,
"error_message=%s)",
3, (target, (int)error_code, error_message));
GPR_ASSERT(elem->filter == &grpc_lame_filter);
- chand = (channel_data *)elem->channel_data;
+ auto chand = static_cast<grpc_core::ChannelData *>(elem->channel_data);
chand->error_code = error_code;
chand->error_message = error_message;
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/lib/surface/version.c b/src/core/lib/surface/version.c
index 3793845559..cddc595e4c 100644
--- a/src/core/lib/surface/version.c
+++ b/src/core/lib/surface/version.c
@@ -38,4 +38,4 @@
const char *grpc_version_string(void) { return "4.0.0-dev"; }
-const char *grpc_g_stands_for(void) { return "gentle"; }
+const char *grpc_g_stands_for(void) { return "gregarious"; }